12 Feb 2010 @ 4:41 AM 

In memory fuzzing is a form off process instrumentation that allows the analyst to bypass parsers, network limitations, encryption and data marshaling steps to deal directly with a functions inputs and test its integrity.

The upsides:

  • It’s faster to get to your target function than creating mini-clients or modifying file formats (or generating 1.5 TB worth…)
  • Once you’re up and running the process fuzz cases happen much faster and it’s easier to distribute fuzz space to multiple VMs
  • It’s a lot more fun

The down sides:

  • Found a bug? No you didn’t… yes you did… did you?  Now that you found your bug you need to get to that section of the code… did you fuzz with the proper bounds?
  • There is a bit of a learning curve and not a lot of help out there.  This has been done in an ad-hoc manner for a few years but there are no real tools to get the job done simply.

So how exactly do we accomplish in memory fuzzing?  If you’ve been following along with the other posts you know I’m in love with pydbg and the PaiMei framework.  I want to continue to use this

framework but it should be noted that Dion Blazakis just had a fairly good shmoocon talk on BaSO4: A Dynamic Dataflow Analysis Tool for Auditing and Reversing and, from what I can tell, it can and should be used in tandum with in memory fuzzing. He has done work on analyzing the dependancies of call graph flow which would be useful in building a more intelligent in memory fuzzer. In anycase, he hasn’t released any code but its an IDA plugin which means it will be trivial to export the data using IDA Pro’s -A, -B and -S flags.

(Automatic disasm and creating of IDB / ASM files, Batch Mode with a a modified PIDA_dump.py to launch automatically, -S or script mode to define an IDC script that can be used to launch an IDAPython script to export more info… I’ll go over all of this in another post if anyone is interested)

…getting back to in-memory fuzzing, the basic steps are:

Initalize the debugger variables (DONE)
Attach to process (DONE)
Set your hooks (DONE)
When the entry point is hit time save memory state and continue (DONE)

Monitor process for memory access of function arguements, save address (IN PROGRESS)
When the exit point is reached revert to saved_state (DONE)
Allocate a space for our fuzz string or buffer with pydbg.virtual_alloc() (DONE)
Modify the functions argument pointers to our fuzz data (IN PROGRESS)
Monitor for stack integrity (IN PROGRESS)

Haz a nice cold coke. (IN PROGRESS)

There is much more to it than this of course.. but that’s the basic idea that I get…. here is a video of steps 1-4, step five is a whole new ball game so stay tuned. (Code is available at the end of the post).

The source code to the start of the in-memory fuzzer:

#!/usr/bin/env python

from pydbg import *
from pydbg.defines import *

import time
import random

snapshot_hook 	= 0x0040FBE8
restore_hook 	= 0x0040FBEB
snapshot_taken 	= False
hit_count		= 0
address			= 0

def set_entry(pydbg):
	return 1

def handle_bp(pydbg):
	global snapshot_hook, restore_hook
	global snapshot_taken, hit_count, address

	if pydbg.first_breakpoint:
		return DBG_CONTINUE

	print "ws2_32.recv() called from thread %d @%08x" % (pydbg.dbg.dwThreadId, pydbg.exception_address)

	context_dump = dbg.dump_context(stack_depth=4, print_dots=False)

	print context_dump

	if pydbg.exception_address == snapshot_hook:
		hit_count += 1
		print "hit the snapshot address"
		start = time.time()
		print "taking snapshot..."
		pydbg.process_snapshot()
		end = time.time() - start
		print "snapshot took: %.03f seconds\n" % end
		if hit_count >= 1:
			if address:
				print "freeing last chunk"
				print "%08x" % address
				pydbg.virtual_free(address, 1000, MEM_DECOMMIT)
		print "allocating memory for mutated data"
		address = pydbg.virtual_alloc( None, 1000, MEM_COMMIT, PAGE_READWRITE)
		print "Allocated 1000 bytes at: %08x" % address		

	return DBG_CONTINUE

def handle_av (pydbg, dbg, context):
    '''
    As we are mucking around with process state and calling potentially unknown subroutines, it is likely that we may
    cause an access violation. We register this handler to provide some useful information about the cause.
    '''

    crash_bin = utils.crash_binning.crash_binning()
    crash_bin.record_crash(dbg)

    print crash_bin.crash_synopsis()
    dbg.terminate_process()

dbg = pydbg()
dbg.set_callback(EXCEPTION_BREAKPOINT,handle_bp)
dbg.set_callback(EXCEPTION_ACCESS_VIOLATION, handle_av)

found_target = False

for (pid, proc_name) in dbg.enumerate_processes():
	#print proc_name.lower()
	if proc_name.lower() == "applemobiledeviceservice.exe":
		found_target = True
		print "[+] Found Target:\"%s" %proc_name.lower()
		break

if found_target:
	dbg.attach(pid)
	print "[+] Attached to :" + str(pid)
	dbg.bp_set(snapshot_hook)
	dbg.bp_set(restore_hook)
	print "[+] Hooks set, entering debug loop..."
	dbg.debug_event_loop()
else:
	print "Target not found\n"
Posted By: jRichards
Last Edit: 12 Feb 2010 @ 04:41 AM

EmailPermalink
Tags
Categories: Uncategorized


 

Responses to this post » (None)

 
Post a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


 Last 50 Posts
 Back
Change Theme...
  • Users » 55
  • Posts/Pages » 29
  • Comments » 13
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

About



    No Child Pages.

Vulns



    No Child Pages.

Tools



    No Child Pages.

PaiMei



    No Child Pages.

PGP Key



    No Child Pages.