Last active
September 10, 2020 17:46
-
-
Save v14dislav/7cee7c36e310d3db2d1298b4f4b48a83 to your computer and use it in GitHub Desktop.
pydbg -> winappdbg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from winappdbg import * | |
| import sys | |
| import random | |
| import struct | |
| import subprocess | |
| size = 1000 | |
| exe_name = "fuzz_server.exe" | |
| snapshot_hook = 0x1400070C0 | |
| restore_hook = 0x140007537 | |
| snapshot_taken = False | |
| hit_count = 0 | |
| address = 0 | |
| snapshot = None | |
| TIDs = [] # list | |
| CTX = dict() | |
| print "Running on %s for the %s architecture." % (System.os, System.arch) | |
| def my_event_handler( event ): | |
| # If the event is an exception... | |
| if event.get_event_code() == win32.EXCEPTION_DEBUG_EVENT: | |
| if (event.get_exception_code() not in (win32.EXCEPTION_SINGLE_STEP, win32.EXCEPTION_BREAKPOINT)) and event.is_last_chance(): | |
| crash = Crash( event ) | |
| crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # small memory dump | |
| # Connect to the database. You can use any URL supported by SQLAlchemy. | |
| # For more details see the reference documentation. | |
| dao = CrashDAO( "sqlite:///crashes.sqlite" ) | |
| #dao = CrashDAO( "mysql+MySQLdb://root:toor@localhost/crashes" ) | |
| # Store the crash dump in the database. | |
| dao.add( crash, False ) | |
| print "We've got and have recorded exception" | |
| event.get_process().kill() | |
| elif event.get_exception_code() in (win32.EXCEPTION_SINGLE_STEP, win32.EXCEPTION_BREAKPOINT): | |
| global snapshot_hook, restore_hook, snapshot_taken, hit_count, address, snapshot, CTX, TIDs | |
| if event.get_thread().get_register("Rip") == snapshot_hook: | |
| hit_count += 1 | |
| print "BP1 hit: #%d" % hit_count | |
| # if a process snapshot has not yet been taken, take one now. | |
| if not snapshot_taken: | |
| snapshot = event.get_process().take_memory_snapshot() | |
| list_th_ids = event.get_process().get_thread_ids() | |
| for TID in list_th_ids: | |
| thread = event.get_process().get_thread(TID) | |
| TIDs.append(TID) | |
| CTX[TID] = thread.get_context() | |
| snapshot_taken = True | |
| if hit_count > 1: | |
| address = event.get_process().malloc(size) | |
| print "Memory allocated at %08x" % address | |
| ''' | |
| print "generating mutant...", | |
| fuzz = "A" * 750 | |
| random_index = random.randint(0, 750) | |
| mutant = fuzz[0:random_index] | |
| mutant += chr(random.randint(32,126)) | |
| mutant += fuzz[random_index:] | |
| mutant += "\x00" | |
| print "done. index at %d." % random_index | |
| ''' | |
| shellcode = "\x99\x65\x48\x8b\x42\x60\x48\x8b\x40\x18\x48\x8b\x70\x10\x48\xad\x48\x8b\x30\x48\x8b\x7e\x30\x48\x31\xdb\x48\x31\xf6\x8b\x5f\x3c\x48\x01\xfb\xb2\x88\x8b\x1c\x13\x48\x01\xfb\x8b\x73\x1c\x48\x01\xfe\x99\x66\xba\x27\x05\x8b\x04\x96\x48\x01\xf8\xeb\x17\x59\x99\x48\xff\xc2\xff\xd0\x99\x66\xba\x29\x01\x8b\x04\x96\x48\x01\xf8\x48\x31\xc9\xff\xd0\xe8\xe4\xff\xff\xff\x63\x6d\x64" | |
| sc_size = len(shellcode) | |
| ch = "A" * 100 | |
| command = 'echo ' + ch + '34:35' + ch + ' | C:\\Users\\designer\\Desktop\\in-memory-fuzz\\radamsa.exe' | |
| result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
| fuzz,error = result.communicate() | |
| block = fuzz + shellcode | |
| if (sc_size + len(fuzz)) > size-2: | |
| block = block[0:size-1] | |
| else: | |
| block += fuzz[0:size-1-sc_size + len(fuzz)] | |
| block += "\x00" | |
| print "Writing block into target memory space" | |
| event.get_process().write(address, block) | |
| event.get_thread().set_register("Rcx", address) | |
| print "Continuing\n" | |
| elif event.get_thread().get_register("Rip") == restore_hook: | |
| if snapshot_taken: | |
| if hit_count > 1: | |
| if address: | |
| print "Freeing block at %08x" % address | |
| event.get_process().free(address) | |
| event.get_process().restore_memory_snapshot(snapshot) | |
| for TID in TIDs: | |
| thread = Process(event.get_pid()).get_thread(TID) | |
| thread.set_context(CTX[TID]) | |
| return win32.DBG_CONTINUE | |
| ''' | |
| # If the event is a process creation or destruction, # для создания процесса, а не attach | |
| # or a DLL being loaded or unloaded... | |
| elif code in (win32.CREATE_PROCESS_DEBUG_EVENT, win32.LOAD_DLL_DEBUG_EVENT): | |
| module = event.get_module() | |
| # If it's kernel32.dll... | |
| if module.match_name("kernel32.dll"): | |
| address = module.resolve( "CreateFileW" ) | |
| dbg.break_at(pid, address) | |
| ''' | |
| # Instance a Debug object. | |
| dbg = Debug( my_event_handler, bKillOnExit = True ) | |
| found_target = False | |
| # Create a system snaphot. | |
| system = System() | |
| # Now we can enumerate the running processes. | |
| for process in system: | |
| if process.get_filename() is not None: | |
| if exe_name in process.get_filename(): | |
| found_target = True | |
| break | |
| if found_target: | |
| dbg.attach( process.dwProcessId ) | |
| dbg.break_at( process.dwProcessId, snapshot_hook ) | |
| dbg.break_at( process.dwProcessId, restore_hook ) | |
| print "attached to %d. debugger active." % process.dwProcessId | |
| for (pid,tid,bp) in dbg.get_all_breakpoints(): | |
| print "bp at %08x" % bp.get_address() | |
| dbg.loop() | |
| else: | |
| print "target not found." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment