def handler(self, event): if ( event.get_event_code() == win32.EXCEPTION_DEBUG_EVENT and event.get_exception_code() != win32.STATUS_BREAKPOINT and (event.is_last_chance() or event.get_exception_code() in self.alwaysCatchExceptions) ): crash = Crash(event) report = CrashReport() crash = Crash(event) (exploitable, type, info) = crash.isExploitable() try: report.code = event.get_thread().disassemble(crash.pc, 0x10)[0][2] except: report.code = "Could not disassemble" if crash.faultAddress is None or MemoryAddresses.align_address_to_page_start(crash.faultAddress) == 0: report.nearNull = True else: report.nearNull = False report.type = type lib = event.get_thread().get_process().get_module_at_address(crash.pc) if lib != None: report.location = lib.get_label_at_address(crash.pc) else: report.location = HexDump.address(crash.pc, event.get_thread().get_process().get_bits())[-4:] if crash.faultAddress == None: crash.faultAddress = 0 report.faultAddr = HexDump.address(crash.faultAddress, event.get_thread().get_process().get_bits()) report.stack = "" stList = self.getStackTraceRelList(event.get_thread()) if len(stList) > 0: for ra in stList: lib = event.get_thread().get_process().get_module_at_address(ra) if lib != None: report.stack += ( lib.get_label_at_address(ra) + " " + HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" ) else: report.stack += HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" if report.stack == "": report.stack = "NO_STACK" report.info = crash.fullReport() return report return None
def debuggerEventHandler(self, event): code = event.get_event_code() crash = Crash(event) if code == win32.EXCEPTION_DEBUG_EVENT and crash.firstChance: status, rule, description = crash.isExploitable() if rule=='Unknown' or rule=='Breakpoint': return print 'WindowsDebugEngine: We found interesting exception' print 'WindowsDebugEngine: %08x, %s, %s, %s' % (code, rule, description, status) self.executorQueue.put({'fin':'exception', 'rule': rule, 'description': description, 'status': status})
def do(self, arg): ".exploitable - Determine the approximate exploitability rating" from winappdbg import Crash event = self.debug.lastEvent crash = Crash(event) crash.fetch_extra_data(event) status, rule, description = crash.isExploitable() print "-" * 79 print "Exploitability: %s" % status print "Matched rule: %s" % rule print "Description: %s" % description print "-" * 79
def _my_event_handler(self, event): """ handle debugger events """ code = event.get_event_code() if code == win32.EXCEPTION_DEBUG_EVENT and event.is_last_chance(): self._crash_event_complete.clear() self.logger.warning( "Crash detected, storing crash dump in database...") self.report.failed("crash detected") self.report.add("event name", event.get_event_name()) self.report.add("event code", code) # Generate a minimal crash dump. crash = Crash(event) # You can turn it into a full crash dump (recommended). # crash.fetch_extra_data( event, takeMemorySnapshot = 0 ) # no memory dump # crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # small memory dump crash.fetch_extra_data(event, takeMemorySnapshot=2) # full memory dump self.report.add("crash_isExploitable", crash.isExploitable()) self.report.add("crash_briefReport", crash.briefReport()) self.report.add("crash_fullReport", crash.fullReport()) self.report.add("crash_timestamp", crash.timeStamp) self.report.add("crash_signature", crash.signature) # Connect to the database. You can use any URL supported by SQLAlchemy. # For more details see the reference documentation. dao = CrashDAO(self._sql_crash_db) # If you do this instead, heuristics are used to detect duplicated # crashes so they aren"t added to the database. dao.add(crash, allow_duplicates=False) # Kill the process. self._process.kill() # DO WE NEED THIS ??? if "Process termination event" == event.get_event_name(): self.logger.debug("detected process termination event code=%d" % code) self.logger.debug("debugee count=%s" % self._debug.get_debugee_count()) self.logger.debug("debugee pids=%s" % self._debug.get_debugee_pids())
def handler(self, event): if event.get_event_code() == win32.EXCEPTION_DEBUG_EVENT and event.get_exception_code() != win32.STATUS_BREAKPOINT and (event.is_last_chance() or event.get_exception_code() in self.alwaysCatchExceptions): crash = Crash(event) report = CrashReport() crash = Crash(event) (exploitable, type, info) = crash.isExploitable() try: report.code = event.get_thread().disassemble( crash.pc, 0x10 ) [0][2] except: report.code = "Could not disassemble" if crash.faultAddress is None or MemoryAddresses.align_address_to_page_start(crash.faultAddress) == 0: report.nearNull = True else: report.nearNull = False report.type = type lib = event.get_thread().get_process().get_module_at_address(crash.pc) if lib != None: report.location = lib.get_label_at_address(crash.pc) else: report.location = HexDump.address(crash.pc, event.get_thread().get_process().get_bits())[-4:] if crash.faultAddress == None: crash.faultAddress = 0 report.faultAddr = HexDump.address(crash.faultAddress, event.get_thread().get_process().get_bits()) report.stack = "" stList = self.getStackTraceRelList(event.get_thread()) if len(stList)>0: for ra in stList: lib = event.get_thread().get_process().get_module_at_address(ra) if lib != None: report.stack += lib.get_label_at_address(ra) + " " + HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" else: report.stack += HexDump.address(ra, event.get_thread().get_process().get_bits()) + "\n" if report.stack == "": report.stack = "NO_STACK" report.info= crash.fullReport() return report return None
def _my_event_handler(self, event): ''' handle debugger events ''' code = event.get_event_code() if code == win32.EXCEPTION_DEBUG_EVENT and event.is_last_chance(): self._crash_event_complete.clear() self.logger.warning("Crash detected, storing crash dump in database...") self.report.failed('crash detected') self.report.add('event name', event.get_event_name()) self.report.add('event code', code) # Generate a minimal crash dump. crash = Crash(event) # You can turn it into a full crash dump (recommended). # crash.fetch_extra_data( event, takeMemorySnapshot = 0 ) # no memory dump # crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # small memory dump crash.fetch_extra_data(event, takeMemorySnapshot=2) # full memory dump self.report.add('crash_isExploitable', crash.isExploitable()) self.report.add('crash_briefReport', crash.briefReport()) self.report.add('crash_fullReport', crash.fullReport()) self.report.add('crash_timestamp', crash.timeStamp) self.report.add('crash_signature', crash.signature) # Connect to the database. You can use any URL supported by SQLAlchemy. # For more details see the reference documentation. dao = CrashDAO(self._sql_crash_db) # If you do this instead, heuristics are used to detect duplicated # crashes so they aren't added to the database. dao.add(crash, allow_duplicates=False) # Kill the process. self._process.kill() # DO WE NEED THIS ??? if 'Process termination event' == event.get_event_name(): self.logger.debug('detected process termination event code=%d' % code) self.logger.debug('debugee count=%s' % self._debug.get_debugee_count()) self.logger.debug('debugee pids=%s' % self._debug.get_debugee_pids())
def debuggerEventHandler(self, event): code = event.get_event_code() crash = Crash(event) if code == win32.EXCEPTION_DEBUG_EVENT and crash.firstChance: status, rule, description = crash.isExploitable() if rule == 'Unknown' or rule == 'Breakpoint': return print 'WindowsDebugEngine: We found interesting exception' print 'WindowsDebugEngine: %08x, %s, %s, %s' % ( code, rule, description, status) self.executorQueue.put({ 'fin': 'exception', 'rule': rule, 'description': description, 'status': status })
def crash_event_handler(event): """ This implements the whole logic. The code below triggered by an access violation is responsible for storing / doing whatever with the crash info """ code = event.get_event_code() # TODO: use this to distinguish between Eip and Rip? bits = event.get_process().get_bits() # If the event is a crash... if code == win32.EXCEPTION_DEBUG_EVENT and event.is_last_chance(): print "=== [*] Crash detected, analyzing..." name = event.get_exception_description() pc = event.get_thread().get_pc() # Get the offending address. address = event.get_exception_address() # TODO: Get the register values #thread = event.get_thread() #registers = thread.get_context() # Generate a minimal crash dump. crash = Crash(event) if crash.exceptionLabel: c_label = crash.exceptionLabel else: c_label = 'Not available' # Crashing file contents in Base64 if file_info: bin = file_info else: bin = None crash_properties = dict() crash_properties['victim'] = victim_filename crash_properties['processor'] = crash.arch crash_properties['event_name'] = name crash_properties['ip'] = address # pc, registers['Eip'], etc. crash_properties['crash_label'] = c_label crash_properties['stacktrace'] = crash.stackTraceLabels crash_properties['exploitability'] = crash.isExploitable() crash_properties['bin'] = bin # TODO: Calculate some kind of metric in order to discard already # found crashes (or minimal variations of them) # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # You can turn it into a full crash dump (recommended). # crash.fetch_extra_data( event, takeMemorySnapshot = 0 ) # no memory dump crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # small memory dump # crash.fetch_extra_data(event, takeMemorySnapshot = 2) # full memory dump # TODO: do not hardcode this directory dao = CrashDAO("sqlite:///crashes/crashes.sqlite") # Store the crash dump in the database. print "=== [*] Storing crash dump in (local) database..." # NOTE: If you do this instead, heuristics are used to detect duplicated # crashes so they aren't added to the database. # dao.add( crash, allow_duplicates = False ) dao.add(crash) # # Store the crash, locally and in server # # Kill the process. event.get_process().kill() communications.add_crash(crash_properties) fileops.save_crash_file(crash_filename, 'crashes')