Difference between revisions of "RAM analysis"
(2 intermediate revisions by the same user not shown) | |||
Line 31: | Line 31: | ||
1 load1 40000000 0000000000000000 0000000000000000 00000720 2**0 |
1 load1 40000000 0000000000000000 0000000000000000 00000720 2**0 |
||
− | <br>Let's extract the RAM |
+ | <br>Let's extract the RAM, getting rid of the first bytes. |
+ | size=0x40000000;off=0x720;head -c $(($size+$off)) test.elf|tail -c +$(($off+1)) > test.raw |
||
− | $ 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 |
$ ./vol.py -f test.raw --profile=Win7SP1x86 pslist |
||
Volatile Systems Volatility Framework 2.0 |
Volatile Systems Volatility Framework 2.0 |
||
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: via ELF64 coredump== |
==Volatility with VirtualBox: via ELF64 coredump== |
||
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. |
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. |
||
Line 144: | Line 145: | ||
Currently [https://code.google.com/p/volatility/issues/detail?id=212 an issue] was opened to discuss possible integration of this plugin into the core source. |
Currently [https://code.google.com/p/volatility/issues/detail?id=212 an issue] was opened to discuss possible integration of this plugin into the core source. |
||
<br>Meanwhile the plugin is mentioned [https://code.google.com/p/volatility/wiki/DocFiles20#Development_and_Plugins in the Volatility wiki]. |
<br>Meanwhile the plugin is mentioned [https://code.google.com/p/volatility/wiki/DocFiles20#Development_and_Plugins in the Volatility wiki]. |
||
+ | <br>'''Update:''' this has been integrated in branch 2.3-devel in [https://code.google.com/p/volatility/source/detail?r=2667 r2667] to r2670 |
||
==RAM dump with VirtualBox: via pgmphystofile== |
==RAM dump with VirtualBox: via pgmphystofile== |
Latest revision as of 16:29, 14 October 2013
Misc notes on physical RAM analysis
Links
- Volatility, for memory analysis of mainly Windows platforms (Linux support is in beta)
- Volatilitux, for memory analysis of linux and Android platforms
- Passware, a commercial tool mostly aiming at recovering passwords, including from memory dumps
RAM dump with VirtualBox: via ELF64 coredump
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, getting rid of the first bytes.
size=0x40000000;off=0x720;head -c $(($size+$off)) test.elf|tail -c +$(($off+1)) > test.raw
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: via ELF64 coredump
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_note_vbcore = False
found_load_ram = 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))
# NOTE VBCORE segment?
if ((not found_note_vbcore) and (stype == 4)):
(namesz, descsz, ntype) = struct.unpack('<III', base.read(offset, 12))
if (base.read(offset+12, namesz) == 'VBCORE'):
found_note_vbcore = True
self.as_assert((descsz == 24), 'Abnormal VBCORE size')
# parsing DBGFCOREDESCRIPTOR:
(magic, fmtvers, selfsize, vbvers, vbrev, ncpus) = struct.unpack('<IIIIII', base.read(offset+12+((((namesz-1)>>3)+1)<<3), 24))
self.as_assert((magic == 0xc01ac0de), 'Could not find VBox core magic signature')
self.as_assert((fmtvers == 0x00010000), 'Unknown VBox core format version')
# For info: VirtualBox version and revision are available in vbvers & vbrev
continue
# LOAD RAM segment?
if ((not found_load_ram) and (stype == 1)):
# LOAD segments contain also other stuff such as video memory
# but we're only interested into main RAM, starting at physical address 0
if paddr == 0x0000000000000000:
found_load_ram = True
self.moffset = offset
self.msize = filesz
self.as_assert(found_note_vbcore, 'ELF error: did not find any NOTE segment with VBCORE')
self.as_assert(found_load_ram, 'ELF error: did not find any LOAD segment with main RAM')
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 or to be used via the --plugins option:
Place vboxelf.py in a zip file or in a directory and pass it.
Warning: --plugins option was recognised only if placed before -f option
./vol.py --plugins=/path/to/vboxelf.zip -f test.elf --profile=Win7SP1x86 pslist
Currently an issue was opened to discuss possible integration of this plugin into the core source.
Meanwhile the plugin is mentioned in the Volatility wiki.
Update: this has been integrated in branch 2.3-devel in r2667 to r2670
RAM dump with VirtualBox: via pgmphystofile
See https://www.virtualbox.org/ticket/10222
- Start the VM with "VirtualBox --dbg --startvm <VM name>".
- Click on the "Debug" menu -> "Command line...".
- Then use
.pgmphystofile filename
to save the physical memory to the given file.
This file is directly the RAM image and can be read as such by Volatility.
So why using the first method if this method provides directly a memory dump?
It depends your needs, it is currently not possible to automate this second method from a command line or API.