Example #1
0
 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 = util.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:
         term.warn('Vendor OUI lookups will not be performed: {0}'.format(
             filename))
     return OUI
Example #2
0
 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()
Example #3
0
 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 = util.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:
         term.warn('Vendor OUI lookups will not be performed: {0}'
              .format(filename))
     return OUI
Example #4
0
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)
Example #5
0
 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()
Example #6
0
 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")
Example #7
0
 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')
Example #8
0
 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')
Example #9
0
 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()
Example #10
0
 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()
Example #11
0
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)
Example #12
0
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 # {1})'.format(address, page))
    if not cfg.dry_run:
        success = patch(device, address, chunks)
        if success:
            term.info('Write-back verified; patching 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')
    
    #Clean up
    device.close()
    
    return address, page