Python IE6 BHO (Browser Helper Object) / Keylogger Binding
So on one of my many journey’s across the internet I decided I wanted to create a Keylogger and bind it to the IE 6 Browser using a BHO (Browser Helper Objects)
this involved some interesting feats I will share here what I came up with. I decided I wanted to use python for this task as it was and still is rather rare to accomplish this
First I came across this code amply named bho_skel.py
import sys
import _winreg
from ctypes import *
from ctypes.com import IUnknown, PIUnknown, REFIID, GUID, STDMETHOD, HRESULT, \
COMObject
from ctypes.com.automation import IDispatch, BSTR, VARIANT, \
dispinterface, DISPMETHOD
from ctypes.com.register import Registrar
from ctypes.com.connectionpoints import dispinterface_EventReceiver, \
GetConnectionPoint
import ie6 # module generated by ctypes/com/tools/readtlb.py
# _Logger is pinched from ctypes 0.6.2
# ——————————————————————–
from ctypes import windll
kernel32 = windll.kernel32
# Hm. We cannot redirect sys.stderr/sys.stdout in the inproc case,
# If the process is Python, the user would be pissed off if we did.
class _Logger(object):
# Redirect standard output and standard error to
# win32 Debug Messages. Output can be viewed for example
# in DebugView from www.sysinternals.com
_installed = 0
_text = “”
def write(self, text):
self._text += str(text)
if “\n” in self._text:
kernel32.OutputDebugStringA(self._text)
self._text = “”
def install(cls):
if cls._installed:
return
import sys
sys.stdout = sys.stderr = cls()
cls._installed = 1
install = classmethod(install)
def isatty(self):
return 0
# ——————————————————————–
_Logger.install() # redirect stdout to win32′s OutputDebugStringA()
HKLM = _winreg.HKEY_LOCAL_MACHINE
BHO_KEY = (“Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\”
“Browser Helper Objects\\”)
class MyRegistrar(Registrar):
def build_table(self):
table = Registrar.build_table(self)
table.extend([(HKLM, BHO_KEY+self._reg_clsid_, "", None)])
return table
class IObjectWithSite(IUnknown):
_iid_ = GUID(“{FC4801A3-2BA9-11CF-A229-00AA003D7352}”)
IObjectWithSite._methods_ = IUnknown._methods_ + [
(STDMETHOD(HRESULT, "SetSite", PIUnknown)),
(STDMETHOD(HRESULT, "GetSite", POINTER(c_void_p), REFIID))]
class PythonBHO(COMObject):
_reg_clsid_ = “INSERT GUID HERE”
_reg_progid_ = “PythonBHO”
_com_interfaces_ = [IObjectWithSite]
def _get_registrar(cls):
return MyRegistrar(cls)
_get_registrar = classmethod(_get_registrar)
def IObjectWithSite_SetSite(self, this, pUnkSite):
self.browser = POINTER(ie6.IWebBrowser2)()
hr = pUnkSite.QueryInterface(
byref(ie6.IWebBrowser2._iid_), byref(self.browser))
sink = DWebBrowserEvents2Impl()
sink.handle = sink.connect(self.browser)
class DWebBrowserEvents2Impl(dispinterface_EventReceiver):
_com_interfaces_ = [ie6.DWebBrowserEvents2]
def OnQuit(self, this, *args):
self.disconnect(self.handle)
def BeforeNavigate2(self, this, pDisp, url, Flags, TargetFrameName,
PostData, Headers, Cancel):
print “url”, url
if __name__ == ‘__main__’:
from ctypes.com.server import UseCommandLine
UseCommandLine(PythonBHO)
in order for it to work I needed a rather older version of ctypes to generate the ie6.py module which you can find here ( the ctypes version is 6.3 in case the link goes dead) as well as python23
in order to generate the ie6 module now go to a cmd window and type
python ctypes\com\tools\readtlb.py C:\windows\system32\SHDOCVW.DLL > ie6.py
You will need to generate a GUID using using Mark Hammonds win32 files and add it to the bho_skel.py source code
import pythoncom
pythoncom.CreateGUID()
when you run the source the bho_skel.py file you will run it like this
python bho_skel.py /regserver
its pretty straight forward from there run IE and watch its output in debug view
As for the keylogger portion.. Well we will leave that to your imagination

Nice work but why ie6?