Difference between revisions of "RAM analysis"
m |
|||
Line 45: | Line 45: | ||
0x84d9c568 winlogon.exe 392 332 5 111 2012-02-07 16:06:42 |
0x84d9c568 winlogon.exe 392 332 5 111 2012-02-07 16:06:42 |
||
etc |
etc |
||
+ | ==Volatility with VirtualBox== |
||
+ | We just saw how to extract a RAM image but it would be nice if Volatility was able to read directly the VirtualBox core dump. |
||
+ | <br>Thanks to the support of Mike Auty I managed to write a plugin for Volatility. |
||
+ | <br>You can download it [{{#file: vboxelf.py}} as vboxelf.py] |
||
+ | <source lang=python> |
||
+ | # Volatility |
||
+ | # Copyright (C) 2007,2008 Volatile Systems |
||
+ | # Copyright (C) 2005,2006,2007 4tphi Research |
||
+ | # |
||
+ | # Authors: |
||
+ | # {npetroni,awalters}@4tphi.net (Nick Petroni and AAron Walters) |
||
+ | # phil@teuwen.org (Philippe Teuwen) |
||
+ | # |
||
+ | # 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 2 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, write to the Free Software |
||
+ | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
+ | # |
||
+ | |||
+ | """ An AS for processing VirtualBox ELF64 coredumps """ |
||
+ | # References: |
||
+ | # VirtualBox core format: http://www.virtualbox.org/manual/ch12.html#guestcoreformat |
||
+ | # ELF64 format: http://downloads.openwatcom.org/ftp/devel/docs/elf-64-gen.pdf |
||
+ | |||
+ | import struct |
||
+ | import volatility.plugins.addrspaces.standard as standard |
||
+ | |||
+ | #pylint: disable-msg=C0111 |
||
+ | |||
+ | class VirtualBoxCoreDumpElf64(standard.FileAddressSpace): |
||
+ | """ This AS supports VirtualBox ELF64 coredump format """ |
||
+ | order = 30 |
||
+ | def __init__(self, base, config, **kwargs): |
||
+ | ## We must have an AS below us |
||
+ | self.as_assert(base, "No base Address Space") |
||
+ | # Testing for ELF64, little-endian: |
||
+ | self.as_assert((base.read(0, 6) == '\x7fELF\x02\x01'), "ELF64 Header signature invalid") |
||
+ | self.as_assert((base.read(0x10, 2) == '\x04\x00'), "ELF64 type is not a Core file") |
||
+ | (phoff,) = struct.unpack('<Q', base.read(0x20, 8)) |
||
+ | (phentsize, phnum) = struct.unpack('<HH', base.read(0x36, 4)) |
||
+ | found = False |
||
+ | for phptr in range(phoff, phoff + (phentsize * phnum), phentsize): |
||
+ | (stype, flags, offset, vaddr, paddr, filesz, memsz, align) = struct.unpack('<IIQQQQQQ', base.read(phptr, phentsize)) |
||
+ | # Look for first LOAD segment |
||
+ | if stype != 1: |
||
+ | continue |
||
+ | found = True |
||
+ | self.moffset = offset |
||
+ | self.msize = filesz |
||
+ | break |
||
+ | self.as_assert(found, 'ELF error: no segment LOAD found') |
||
+ | standard.FileAddressSpace.__init__(self, base, config, layered = True, **kwargs) |
||
+ | self.fsize = min(self.msize, self.fsize - self.moffset) |
||
+ | |||
+ | def read(self, addr, length): |
||
+ | return self.base.read(addr + self.moffset, length) |
||
+ | |||
+ | def zread(self, addr, length): |
||
+ | return self.base.zread(addr + self.moffset, length) |
||
+ | |||
+ | def read_long(self, addr): |
||
+ | return self.base.read_long(addr + self.moffset) |
||
+ | |||
+ | def write(self, addr, data): |
||
+ | return self.base.write(addr + self.moffset, data) |
||
+ | |||
+ | def is_valid_address(self, addr): |
||
+ | return self.base.is_valid_address(addr + self.moffset) |
||
+ | </source> |
||
+ | To be placed in your Volatility installation under plugins/addrspaces |
Revision as of 10:47, 9 February 2012
Misc notes on physical RAM analysis
Links
- Volatility, for memory analysis of mainly Windows platforms
- Volatilinux, should I explain? (it covers also Android btw)
- Passware, a commercial tool mostly aiming at recovering passwords, including from memory dumps
RAM dump with VirtualBox
VMWare snapshots contain a .vmem which is basically a RAM dump, but for VirtualBox, it's not that easy...
Snapshot .sav files contain all machine state including memory but in a hardly exploitable format (even if VirtualBox is open-source...) and the few people having looked in that direction didn't succeed.
But there is another way to get a RAM dump with VirtualBox (I'm not talking about tools running in the guest as I don't want to interfere at all with the target):
See Ch8 of the manual about debugvm capabilities:
With dumpguestcore --filename <name>, you can create a system dump of the running VM, which will be written into the given file. This file will have the standard ELF core format (with custom sections);
The dump format itself is described here
So let's try:
- VM has to run in order to be able to make the RAM dump, then:
$ vboxmanage debugvm "Win7" dumpguestcore --filename test.elf
- We're interested into the first LOAD section, that's where main memory reference is:
$ readelf --program-headers test.elf|grep -m1 -A1 LOAD LOAD 0x0000000000000720 0x0000000000000000 0x0000000000000000 0x0000000040000000 0x0000000040000000 R 0
If I unwrap the info and label it, we have:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000720 0x0000000000000000 0x0000000000000000 0x0000000040000000 0x0000000040000000 R 0
So memory dump is in test.elf, starting at offset 0x720 and counting 0x40000000 bytes (1024Mb)
Alternatively, using objdump:
$ objdump -h test.elf|egrep -w "(Idx|load1)" Idx Name Size VMA LMA File off Algn 1 load1 40000000 0000000000000000 0000000000000000 00000720 2**0
Let's extract the RAM. Computations deserve some automation but doing it by hand (32*57 = 0x720, 32*33554432 = 0x40000000):
$ dd if=test.elf of=test.raw bs=32 skip=57 count=33554432
Now using volatility on the obtained file:
$ ./vol.py -f test.raw --profile=Win7SP1x86 pslist Volatile Systems Volatility Framework 2.0 Offset(V) Name PID PPID Thds Hnds Time ---------- -------------------- ------ ------ ------ ------ ------------------- 0x83d33d40 System 4 0 69 506 2012-02-07 16:06:19 0x84c5c758 smss.exe 228 4 2 29 2012-02-07 16:06:19 0x85475030 csrss.exe 304 296 9 398 2012-02-07 16:06:30 0x83d9b108 wininit.exe 340 296 3 76 2012-02-07 16:06:41 0x83d70528 csrss.exe 352 332 7 103 2012-02-07 16:06:41 0x84d9c568 winlogon.exe 392 332 5 111 2012-02-07 16:06:42
etc
Volatility with VirtualBox
We just saw how to extract a RAM image but it would be nice if Volatility was able to read directly the VirtualBox core dump.
Thanks to the support of Mike Auty I managed to write a plugin for Volatility.
You can download it [{{#file: vboxelf.py}} as vboxelf.py]
# Volatility
# Copyright (C) 2007,2008 Volatile Systems
# Copyright (C) 2005,2006,2007 4tphi Research
#
# Authors:
# {npetroni,awalters}@4tphi.net (Nick Petroni and AAron Walters)
# phil@teuwen.org (Philippe Teuwen)
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
""" An AS for processing VirtualBox ELF64 coredumps """
# References:
# VirtualBox core format: http://www.virtualbox.org/manual/ch12.html#guestcoreformat
# ELF64 format: http://downloads.openwatcom.org/ftp/devel/docs/elf-64-gen.pdf
import struct
import volatility.plugins.addrspaces.standard as standard
#pylint: disable-msg=C0111
class VirtualBoxCoreDumpElf64(standard.FileAddressSpace):
""" This AS supports VirtualBox ELF64 coredump format """
order = 30
def __init__(self, base, config, **kwargs):
## We must have an AS below us
self.as_assert(base, "No base Address Space")
# Testing for ELF64, little-endian:
self.as_assert((base.read(0, 6) == '\x7fELF\x02\x01'), "ELF64 Header signature invalid")
self.as_assert((base.read(0x10, 2) == '\x04\x00'), "ELF64 type is not a Core file")
(phoff,) = struct.unpack('<Q', base.read(0x20, 8))
(phentsize, phnum) = struct.unpack('<HH', base.read(0x36, 4))
found = False
for phptr in range(phoff, phoff + (phentsize * phnum), phentsize):
(stype, flags, offset, vaddr, paddr, filesz, memsz, align) = struct.unpack('<IIQQQQQQ', base.read(phptr, phentsize))
# Look for first LOAD segment
if stype != 1:
continue
found = True
self.moffset = offset
self.msize = filesz
break
self.as_assert(found, 'ELF error: no segment LOAD found')
standard.FileAddressSpace.__init__(self, base, config, layered = True, **kwargs)
self.fsize = min(self.msize, self.fsize - self.moffset)
def read(self, addr, length):
return self.base.read(addr + self.moffset, length)
def zread(self, addr, length):
return self.base.zread(addr + self.moffset, length)
def read_long(self, addr):
return self.base.read_long(addr + self.moffset)
def write(self, addr, data):
return self.base.write(addr + self.moffset, data)
def is_valid_address(self, addr):
return self.base.is_valid_address(addr + self.moffset)
To be placed in your Volatility installation under plugins/addrspaces