Volatility
Volatility
Volatility
Image Identification
o imageinfo
o kdbgscan
o kpcrscan
Processes and DLLs
o pslist
o pstree
o psscan
o psdispscan
o dlllist
o dlldump
o handles
o getsids
o cmdscan
o consoles
o privs
o envars
o verinfo
o enumfunc
Process Memory
o memmap
o memdump
o procdump
o vadinfo
o vadwalk
o vadtree
o vaddump
o evtlogs
o iehistory
Kernel Memory and Objects
o modules
o modscan
o moddump
o ssdt
o driverscan
o filescan
o mutantscan
o symlinkscan
o thrdscan
o dumpfiles
o unloadedmodules
Networking
o connections
o connscan
o sockets
o sockscan
o netscan
Registry
o hivescan
o hivelist
o printkey
o hivedump
o hashdump
o lsadump
o userassist
o shellbags
o shimcache
o getservicesids
o dumpregistry
Crash Dumps, Hibernation, and Conversion
o crashinfo
o hibinfo
o imagecopy
o raw2dmp
o vboxinfo
o vmwareinfo
o hpakinfo
o hpakextract
File System
o mbrparser
o mftparser
Miscellaneous
o strings
o volshell
o bioskbd
o patcher
o pagecheck
o timeliner
Image Identification
imageinfo
For a high level summary of the memory sample you're analyzing, use the imageinfo
command. Most often this command is used to identify the operating system, service
pack, and hardware architecture (32 or 64 bit), but it also contains other useful
information such as the DTB address and time the sample was collected.
kdbgscan
As opposed to imageinfo which simply provides profile suggestions, kdbgscan is
designed to positively identify the correct profile and the correct KDBG address (if
there happen to be multiple). This plugin scans for the KDBGHeader signatures
linked to Volatility profiles and applies sanity checks to reduce false positives. The
verbosity of the output and number of sanity checks that can be performed depends
on whether Volatility can find a DTB, so if you already know the correct profile (or if
you have a profile suggestion from imageinfo), then make sure you use it.
Here's an example scenario of when this plugin can be useful. You have a memory
sample that you believe to be Windows 2003 SP2 x64, but pslist doesn't show any
processes. The pslist plugin relies on finding the process list head which is pointed
to by KDBG. However, the plugin takes the first KDBG found in the memory sample,
which is not always the best one. You may run into this problem if a KDBG with an
invalid PsActiveProcessHead pointer is found earlier in a sample (i.e. at a lower
physical offset) than the valid KDBG.
Notice below how kdbgscan picks up two KDBG structures: an invalid one (with 0
processes and 0 modules) is found first at 0xf80001172cb0 and a valid one (with 37
processes and 116 modules) is found next at 0xf80001175cf0. In order to
"fix" pslist for this sample, you would simply need to supply the --
kdbg=0xf80001175cf0 to the plist plugin.
$ python vol.py -f Win2K3SP2x64-6f1bedec.vmem --profile=Win2003SP2x64 kdbgscan
Volatility Foundation Volatility Framework 2.4
**************************************************
Instantiating KDBG using: Kernel AS Win2003SP2x64 (5.2.3791 64bit)
Offset (V) : 0xf80001172cb0
Offset (P) : 0x1172cb0
KDBG owner tag check : True
Profile suggestion (KDBGHeader): Win2003SP2x64
Version64 : 0xf80001172c70 (Major: 15, Minor: 3790)
Service Pack (CmNtCSDVersion) : 0
Build string (NtBuildLab) : T?
PsActiveProcessHead : 0xfffff800011947f0 (0 processes)
PsLoadedModuleList : 0xfffff80001197ac0 (0 modules)
KernelBase : 0xfffff80001000000 (Matches MZ: True)
Major (OptionalHeader) : 5
Minor (OptionalHeader) : 2
**************************************************
Instantiating KDBG using: Kernel AS Win2003SP2x64 (5.2.3791 64bit)
Offset (V) : 0xf80001175cf0
Offset (P) : 0x1175cf0
KDBG owner tag check : True
Profile suggestion (KDBGHeader): Win2003SP2x64
Version64 : 0xf80001175cb0 (Major: 15, Minor: 3790)
Service Pack (CmNtCSDVersion) : 2
Build string (NtBuildLab) : 3790.srv03_sp2_rtm.070216-1710
PsActiveProcessHead : 0xfffff800011977f0 (37 processes)
PsLoadedModuleList : 0xfffff8000119aae0 (116 modules)
KernelBase : 0xfffff80001000000 (Matches MZ: True)
Major (OptionalHeader) : 5
Minor (OptionalHeader) : 2
KPCR : 0xfffff80001177000 (CPU 0)
For more information on how KDBG structures are identified read Finding Kernel
Global Variables in Windows and Identifying Memory Images
kpcrscan
Use this command to scan for potential KPCR structures by checking for the self-
referencing members as described by Finding Object Roots in Vista. On a multi-core
system, each processor has its own KPCR. Therefore, you'll see details for each
processor, including IDT and GDT address; current, idle, and next threads; CPU
number, vendor & speed; and CR3 value.
If you see processes with 0 threads, 0 handles, and/or a non-empty exit time, the
process may not actually still be active. For more information, see The Missing Active
in PsActiveProcessHead. Below, you'll notice regsvr32.exe has terminated even
though its still in the "active" list.
Also note the two processes System and smss.exe will not have a Session ID, because
System starts before sessions are established and smss.exe is the session manager
itself.
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 pslist
Volatility Foundation Volatility Framework 2.4
Offset(V) Name PID PPID Thds Hnds Sess
Wow64 Start Exit
------------------ -------------------- ------ ------ ------ -------- ------
------ -------------------- --------------------
0xfffffa80004b09e0 System 4 0 78 489 ------
0 2012-02-22 19:58:20
0xfffffa8000ce97f0 smss.exe 208 4 2 29 ------
0 2012-02-22 19:58:20
0xfffffa8000c006c0 csrss.exe 296 288 9 385 0
0 2012-02-22 19:58:24
0xfffffa8000c92300 wininit.exe 332 288 3 74 0
0 2012-02-22 19:58:30
0xfffffa8000c06b30 csrss.exe 344 324 7 252 1
0 2012-02-22 19:58:30
0xfffffa8000c80b30 winlogon.exe 372 324 5 136 1
0 2012-02-22 19:58:31
0xfffffa8000c5eb30 services.exe 428 332 6 193 0
0 2012-02-22 19:58:32
0xfffffa80011c5700 lsass.exe 444 332 6 557 0
0 2012-02-22 19:58:32
0xfffffa8000ea31b0 lsm.exe 452 332 10 133 0
0 2012-02-22 19:58:32
0xfffffa8001296b30 svchost.exe 568 428 10 352 0
0 2012-02-22 19:58:34
0xfffffa80012c3620 svchost.exe 628 428 6 247 0
0 2012-02-22 19:58:34
0xfffffa8001325950 sppsvc.exe 816 428 5 154 0
0 2012-02-22 19:58:41
0xfffffa80007b7960 svchost.exe 856 428 16 404 0
0 2012-02-22 19:58:43
0xfffffa80007bb750 svchost.exe 880 428 34 1118 0
0 2012-02-22 19:58:43
0xfffffa80007d09e0 svchost.exe 916 428 19 443 0
0 2012-02-22 19:58:43
0xfffffa8000c64840 svchost.exe 348 428 14 338 0
0 2012-02-22 20:02:07
0xfffffa8000c09630 svchost.exe 504 428 16 496 0
0 2012-02-22 20:02:07
0xfffffa8000e86690 spoolsv.exe 1076 428 12 271 0
0 2012-02-22 20:02:10
0xfffffa8000518b30 svchost.exe 1104 428 18 307 0
0 2012-02-22 20:02:10
0xfffffa800094d960 wlms.exe 1264 428 4 43 0
0 2012-02-22 20:02:11
0xfffffa8000995b30 svchost.exe 1736 428 12 200 0
0 2012-02-22 20:02:25
0xfffffa8000aa0b30 SearchIndexer. 1800 428 12 757 0
0 2012-02-22 20:02:26
0xfffffa8000aea630 taskhost.exe 1144 428 7 189 1
0 2012-02-22 20:02:41
0xfffffa8000eafb30 dwm.exe 1476 856 3 71 1
0 2012-02-22 20:02:41
0xfffffa80008f3420 explorer.exe 1652 840 21 760 1
0 2012-02-22 20:02:42
0xfffffa8000c9a630 regsvr32.exe 1180 1652 0 -------- 1
0 2012-02-22 20:03:05 2012-02-22 20:03:08
0xfffffa8000a03b30 rundll32.exe 2016 568 3 67 1
0 2012-02-22 20:03:16
0xfffffa8000a4f630 svchost.exe 1432 428 12 350 0
0 2012-02-22 20:04:14
0xfffffa8000999780 iexplore.exe 1892 1652 19 688 1
1 2012-02-22 11:26:12
0xfffffa80010c9060 iexplore.exe 2820 1892 23 733 1
1 2012-02-22 11:26:15
0xfffffa8001016060 DumpIt.exe 2860 1652 2 42 1
1 2012-02-22 11:28:59
0xfffffa8000acab30 conhost.exe 2236 344 2 51 1
0 2012-02-22 11:28:59
By default, pslist shows virtual offsets for the _EPROCESS but the physical offset can
be obtained with the -P switch:
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 pslist -P
Volatility Foundation Volatility Framework 2.4
Offset(P) Name PID PPID Thds Hnds Sess
Wow64 Start Exit
------------------ -------------------- ------ ------ ------ -------- ------
------ -------------------- --------------------
0x0000000017fef9e0 System 4 0 78 489 ------
0 2012-02-22 19:58:20
0x00000000176e97f0 smss.exe 208 4 2 29 ------
0 2012-02-22 19:58:20
0x00000000176006c0 csrss.exe 296 288 9 385 0
0 2012-02-22 19:58:24
0x0000000017692300 wininit.exe 332 288 3 74 0
0 2012-02-22 19:58:30
0x0000000017606b30 csrss.exe 344 324 7 252 1
0 2012-02-22 19:58:30
...
pstree
To view the process listing in tree form, use the pstree command. This enumerates
processes using the same technique as pslist, so it will also not show hidden or
unlinked processes. Child process are indicated using indention and periods.
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 pstree
Volatility Foundation Volatility Framework 2.4
Name Pid PPid Thds Hnds
Time
-------------------------------------------------- ------ ------ ------ ------
--------------------
0xfffffa80004b09e0:System 4 0 78 489
2012-02-22 19:58:20
. 0xfffffa8000ce97f0:smss.exe 208 4 2 29
2012-02-22 19:58:20
0xfffffa8000c006c0:csrss.exe 296 288 9 385
2012-02-22 19:58:24
0xfffffa8000c92300:wininit.exe 332 288 3 74
2012-02-22 19:58:30
. 0xfffffa8000c5eb30:services.exe 428 332 6 193
2012-02-22 19:58:32
.. 0xfffffa8000aa0b30:SearchIndexer. 1800 428 12 757
2012-02-22 20:02:26
.. 0xfffffa80007d09e0:svchost.exe 916 428 19 443
2012-02-22 19:58:43
.. 0xfffffa8000a4f630:svchost.exe 1432 428 12 350
2012-02-22 20:04:14
.. 0xfffffa800094d960:wlms.exe 1264 428 4 43
2012-02-22 20:02:11
.. 0xfffffa8001325950:sppsvc.exe 816 428 5 154
2012-02-22 19:58:41
.. 0xfffffa8000e86690:spoolsv.exe 1076 428 12 271
2012-02-22 20:02:10
.. 0xfffffa8001296b30:svchost.exe 568 428 10 352
2012-02-22 19:58:34
... 0xfffffa8000a03b30:rundll32.exe 2016 568 3 67
2012-02-22 20:03:16
...
psscan
To enumerate processes using pool tag scanning (_POOL_HEADER), use
the psscan command. This can find processes that previously terminated (inactive)
and processes that have been hidden or unlinked by a rootkit. The downside is that
rootkits can still hide by overwriting the pool tag values (though not commonly seen
in the wild).
$ python vol.py --profile=Win7SP0x86 -f win7.dmp psscan
Volatility Foundation Volatility Framework 2.0
Offset Name PID PPID PDB Time created
Time exited
---------- ---------------- ------ ------ ---------- ------------------------
------------------------
0x3e025ba8 svchost.exe 1116 508 0x3ecf1220 2010-06-16 15:25:25
0x3e04f070 svchost.exe 1152 508 0x3ecf1340 2010-06-16 15:27:40
0x3e144c08 dwm.exe 1540 832 0x3ecf12e0 2010-06-16 15:26:58
0x3e145c18 TPAutoConnSvc. 1900 508 0x3ecf1360 2010-06-16 15:25:41
0x3e3393f8 lsass.exe 516 392 0x3ecf10e0 2010-06-16 15:25:18
0x3e35b8f8 svchost.exe 628 508 0x3ecf1120 2010-06-16 15:25:19
0x3e383770 svchost.exe 832 508 0x3ecf11a0 2010-06-16 15:25:20
0x3e3949d0 svchost.exe 740 508 0x3ecf1160 2010-06-16 15:25:20
0x3e3a5100 svchost.exe 872 508 0x3ecf11c0 2010-06-16 15:25:20
0x3e3f64e8 svchost.exe 992 508 0x3ecf1200 2010-06-16 15:25:24
0x3e45a530 wininit.exe 392 316 0x3ecf10a0 2010-06-16 15:25:15
0x3e45d928 svchost.exe 1304 508 0x3ecf1260 2010-06-16 15:25:28
0x3e45f530 csrss.exe 400 384 0x3ecf1040 2010-06-16 15:25:15
0x3e4d89c8 vmtoolsd.exe 1436 508 0x3ecf1280 2010-06-16 15:25:30
0x3e4db030 spoolsv.exe 1268 508 0x3ecf1240 2010-06-16 15:25:28
0x3e50b318 services.exe 508 392 0x3ecf1080 2010-06-16 15:25:18
0x3e7f3d40 csrss.exe 352 316 0x3ecf1060 2010-06-16 15:25:12
0x3e7f5bc0 winlogon.exe 464 384 0x3ecf10c0 2010-06-16 15:25:18
0x3eac6030 SearchProtocol 2448 1168 0x3ecf15c0 2010-06-16 23:30:52
2010-06-16 23:33:14
0x3eb10030 SearchFilterHo 1812 1168 0x3ecf1480 2010-06-16 23:31:02
2010-06-16 23:33:14
[snip]
If a process has previously terminated, the Time exited field will show the exit time. If
you want to investigate a hidden process (such as displaying its DLLs), then you'll
need physical offset of the _EPROCESS object, which is shown in the far left column.
Almost all process-related plugins take a --OFFSET parameter so that you can work
with hidden processes.
psdispscan
This plugin is similar to psscan, except it enumerates processes by scanning
for DISPATCHER_HEADER instead of pool tags. This gives you an alternate way to
carve _EPROCESS objects in the event an attacker tried to hide by altering pool tags.
This plugin is not well maintained and only supports XP x86. To use it, you must
type --plugins=contrib/plugins on command-line.
dlllist
To display a process's loaded DLLs, use the dlllist command. It walks the doubly-
linked list of _LDR_DATA_TABLE_ENTRY structures which is pointed to by the
PEB's InLoadOrderModuleList. DLLs are automatically added to this list when a process
calls LoadLibrary (or some derivative such as LdrLoadDll) and they aren't removed
until FreeLibrary is called and the reference count reaches zero. The load count
column tells you if a DLL was statically loaded (i.e. as a result of being in the exe or
another DLL's import table) or dynamically loaded.
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 dlllist
************************************************************************
wininit.exe pid: 332
Command line : wininit.exe
dlldump
To extract a DLL from a process's memory space and dump it to disk for analysis, use
the dlldump command. The syntax is nearly the same as what we've shown for dlllist
above. You can:
To dump a PE file that doesn't exist in the DLLs list (for example, due to code
injection or malicious unlinking), just specify the base address of the PE in process
memory:
$ python vol.py --profile=Win7SP0x86 -f win7.dmp dlldump --pid=492 -D out
--base=0x00680000
You can also specify an EPROCESS offset if the DLL you want is in a hidden process:
handles
To display the open handles in a process, use the handles command. This applies to
files, registry keys, mutexes, named pipes, events, window stations, desktops, threads,
and all other types of securable executive objects. As of 2.1, the output includes
handle value and granted access for each object.
In some cases, the Details column will be blank (for example, if the objects don't have
names). By default, you'll see both named and un-named objects. However, if you
want to hide the less meaningful results and only show named objects, use the --
silent parameter to this plugin.
getsids
To view the SIDs (Security Identifiers) associated with a process, use the getsids
command. Among other things, this can help you identify processes which have
maliciously escalated privileges and which processes belong to specific users.
cmdscan
The cmdscan plugin searches the memory of csrss.exe on XP/2003/Vista/2008 and
conhost.exe on Windows 7 for commands that attackers entered through a console
shell (cmd.exe). This is one of the most powerful commands you can use to gain
visibility into an attackers actions on a victim system, whether they opened cmd.exe
through an RDP session or proxied input/output to a command shell from a
networked backdoor.
The structures used by this plugin are not public (i.e. Microsoft does not produce
PDBs for them), thus they're not available in WinDBG or any other forensic
framework. They were reverse engineered by Michael Ligh from the conhost.exe and
winsrv.dll binaries.
Due to the scanning technique this plugin uses, it has the capability to find
commands from both active and closed consoles.
**************************************************
CommandProcess: csrss.exe Pid: 528
CommandHistory: 0x135ec00 Application: cmd.exe Flags: Allocated, Reset
CommandCount: 18 LastAdded: 17 LastDisplayed: 17
FirstCommand: 0 CommandCountMax: 50
ProcessHandle: 0x330
Cmd #0 @ 0x135ef10: cd \
Cmd #1 @ 0x135ef50: cd de
Cmd #2 @ 0x135ef70: cd PerfLogs
Cmd #3 @ 0x135ef90: cd ..
Cmd #4 @ 0x5c78b90: cd "Program Files"
Cmd #5 @ 0x135fae0: cd "Debugging Tools for Windows (x64)"
Cmd #6 @ 0x135efb0: livekd -w
Cmd #7 @ 0x135f010: windbg
Cmd #8 @ 0x135efd0: cd \
Cmd #9 @ 0x135fd20: rundll32 c:\apphelp.dll,ExportFunc
Cmd #10 @ 0x5c8bdb0: rundll32 c:\windows_apphelp.dll,ExportFunc
Cmd #11 @ 0x5c8be10: rundll32 c:\windows_apphelp.dll
Cmd #12 @ 0x135ee30: rundll32 c:\windows_apphelp.dll,Test
Cmd #13 @ 0x135fd70: cd "Program Files"
Cmd #14 @ 0x5c8b9e0: dir
Cmd #15 @ 0x5c8be60: cd "Debugging Tools for Windows (x64)"
Cmd #16 @ 0x5c8ba00: dir
Cmd #17 @ 0x135eff0: livekd -w
[snip]
For background information, see Richard Stevens and Eoghan Casey's Extracting
Windows Cmd Line Details from Physical Memory.
consoles
Similar to cmdscan the consoles plugin finds commands that attackers typed into
cmd.exe or executed via backdoors. However, instead of scanning for
COMMAND_HISTORY, this plugin scans for CONSOLE_INFORMATION. The major
advantage to this plugin is it not only prints the commands attackers typed, but it
collects the entire screen buffer (input and output). For instance, instead of just
seeing "dir", you'll see exactly what the attacker saw, including all files and directories
listed by the "dir" command.
Here's an example of the consoles command. Below, you'll notice something quite
funny. The forensic investigator seems to have lost his mind and cannot find the
dd.exe tool for dumping memory. Nearly 20 typos later, he finds the tool and uses it.
privs
This plugin shows you which process privileges are present, enabled, and/or enabled
by default. You can pass it the --silent flag to only show privileges that a process
explicitly enabled (i.e. that were were not enabled by default but are currently
enabled). The --regex=REGEX parameter can be used to filter for specific privilege
names.
envars
To display a process's environment variables, use the envars plugin. Typically this will
show the number of CPUs installed and the hardware architecture (though
the kdbgscan output is a much more reliable source), the process's current directory,
temporary directory, session name, computer name, user name, and various other
interesting artifacts.
verinfo
To display the version information embedded in PE files, use the verinfo command.
Not all PE files have version information, and many malware authors forge it to
include false data, but nonetheless this command can be very helpful with identifying
binaries and for making correlations with other files.
This plugin only supports printing version information from process executables and
DLLs, but later will be expanded to include kernel modules. If you want to filter by
module name, use the --regex=REGEX and/or --ignore-case options.
C:\Windows\system32\csrss.exe
File version : 6.1.7600.16385
Product version : 6.1.7600.16385
Flags :
OS : Windows NT
File Type : Application
File Date :
CompanyName : Microsoft Corporation
FileDescription : Client Server Runtime Process
FileVersion : 6.1.7600.16385 (win7_rtm.090713-1255)
InternalName : CSRSS.Exe
LegalCopyright : \xa9 Microsoft Corporation. All rights reserved.
OriginalFilename : CSRSS.Exe
ProductName : Microsoft\xae Windows\xae Operating System
ProductVersion : 6.1.7600.16385
[snip]
enumfunc
This plugin enumerates imported and exported functions from processes, dlls, and
kernel drivers. Specifically, it handles functions imported by name or ordinal,
functions exported by name or ordinal, and forwarded exports. The output will be
very verbose in most cases (functions exported by ntdll, msvcrt, and kernel32 can
reach 1000+ alone). So you can either reduce the verbosity by filtering criteria with
the command-line options (shown below) or you can use look at the code in
enumfunc.py and use it as an example of how to use the IAT and EAT parsing API
functions in your own plugin. For example, the apihooks plugin leverages the imports
and exports APIs to find functions in memory when checking for hooks.
Also note this plugin is in the contrib directory, so you can pass that to --plugins like
this:
Process Memory
memmap
The memmap command shows you exactly which pages are memory resident, given
a specific process DTB (or kernel DTB if you use this plugin on the Idle or System
process). It shows you the virtual address of the page, the corresponding physical
offset of the page, and the size of the page. The map information generated by this
plugin comes from the underlying address space's get_available_addresses method.
As of 2.1, the new column DumpFileOffset helps you correlate the output of
memmap with the dump file produced by the memdump plugin. For example,
according to the output below, the page at virtual address 0x0000000000058000 in
the System process's memory can be found at offset 0x00000000162ed000 of the
win7_trial_64bit.raw file. After using memdump to extract the addressable memory of
the System process to an individual file, you can find this page at offset 0x8000.
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 memmap -p 4
Volatility Foundation Volatility Framework 2.4
System pid: 4
Virtual Physical Size DumpFileOffset
------------------ ------------------ ------------------ ------------------
0x0000000000050000 0x0000000000cbc000 0x1000 0x0
0x0000000000051000 0x0000000015ec6000 0x1000 0x1000
0x0000000000052000 0x000000000f5e7000 0x1000 0x2000
0x0000000000053000 0x0000000005e28000 0x1000 0x3000
0x0000000000054000 0x0000000008b29000 0x1000 0x4000
0x0000000000055000 0x00000000155b8000 0x1000 0x5000
0x0000000000056000 0x000000000926e000 0x1000 0x6000
0x0000000000057000 0x0000000002dac000 0x1000 0x7000
0x0000000000058000 0x00000000162ed000 0x1000 0x8000
[snip]
memdump
To extract all memory resident pages in a process (see memmap for details) into an
individual file, use the memdump command. Supply the output directory with -D or
--dump-dir=DIR.
$ ls -alh dump/4.dmp
-rw-r--r-- 1 Michael staff 111M Jun 24 15:47 dump/4.dmp
To conclude the demonstration we began in the memmap discussion, we should now
be able to make an assertion regarding the relationship of the mapped and extracted
pages:
procdump
To dump a process's executable, use the procdump command. Optionally, pass
the --unsafe or -u flags to bypass certain sanity checks used when parsing the PE
header. Some malware will intentionally forge size fields in the PE header so that
memory dumping tools fail.
Use --memory to include slack space between the PE sections that aren't page aligned.
Without --memory you'll get a file that more closely resembles the file on disk, before
sections expanded.
For more information, see Andreas Schuster's 4-part series on Reconstructing a
Binary. Also see impscan for help rebuilding a binary's import address table.
$ file dump/executable.296.exe
dump/executable.296.exe: PE32+ executable for MS Windows (native) Mono/.Net
assembly
vadinfo
The vadinfo command displays extended information about a process's VAD nodes.
In particular, it shows:
[snip]
vadwalk
To inspect a process's VAD nodes in table form, use the vadwalk command.
vadtree
To display the VAD nodes in a visual tree form, use the vadtree command.
Red: Heaps
Gray: DLLs
Green: Stacks
Yellow: Mapped Files
vaddump
To extract the range of pages described by a VAD node, use the vaddump command.
This is similar to memdump, except the pages belonging to each VAD node are
placed in separate files (named according to the starting and ending addresses)
instead of one large conglomerate file. If any pages in the range are not memory
resident, they're padded with 0's using the address space's zread() method.
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 vaddump -D
vads
Volatility Foundation Volatility Framework 2.4
Pid Process Start End Result
---------- -------------------- ------------------ ------------------ ------
4 System 0x0000000076d40000 0x0000000076eeafff
vads/System.17fef9e0.0x0000000076d40000-0x0000000076eeafff.dmp
4 System 0x0000000000040000 0x0000000000040fff
vads/System.17fef9e0.0x0000000000040000-0x0000000000040fff.dmp
4 System 0x0000000000010000 0x0000000000032fff
vads/System.17fef9e0.0x0000000000010000-0x0000000000032fff.dmp
4 System 0x000000007ffe0000 0x000000007ffeffff
vads/System.17fef9e0.0x000000007ffe0000-0x000000007ffeffff.dmp
4 System 0x0000000076f20000 0x000000007709ffff
vads/System.17fef9e0.0x0000000076f20000-0x000000007709ffff.dmp
208 smss.exe 0x000000007efe0000 0x000000007ffdffff
vads/smss.exe.176e97f0.0x000000007efe0000-0x000000007ffdffff.dmp
208 smss.exe 0x00000000003d0000 0x00000000004cffff
vads/smss.exe.176e97f0.0x00000000003d0000-0x00000000004cffff.dmp
208 smss.exe 0x0000000000100000 0x0000000000100fff
vads/smss.exe.176e97f0.0x0000000000100000-0x0000000000100fff.dmp
208 smss.exe 0x0000000000000000 0x00000000000fffff
vads/smss.exe.176e97f0.0x0000000000000000-0x00000000000fffff.dmp
208 smss.exe 0x0000000000190000 0x000000000020ffff
vads/smss.exe.176e97f0.0x0000000000190000-0x000000000020ffff.dmp
208 smss.exe 0x0000000047a90000 0x0000000047aaffff
vads/smss.exe.176e97f0.0x0000000047a90000-0x0000000047aaffff.dmp
208 smss.exe 0x00000000005e0000 0x000000000065ffff
vads/smss.exe.176e97f0.0x00000000005e0000-0x000000000065ffff.dmp
[snip]
$ ls -al vads/
total 123720
drwxr-xr-x 69 michaelligh staff 2346 Apr 6 13:12 .
drwxr-xr-x 37 michaelligh staff 1258 Apr 6 13:11 ..
-rw-r--r-- 1 michaelligh staff 143360 Apr 6 13:12
System.17fef9e0.0x0000000000010000-0x0000000000032fff.dmp
-rw-r--r-- 1 michaelligh staff 4096 Apr 6 13:12
System.17fef9e0.0x0000000000040000-0x0000000000040fff.dmp
-rw-r--r-- 1 michaelligh staff 1748992 Apr 6 13:12
System.17fef9e0.0x0000000076d40000-0x0000000076eeafff.dmp
-rw-r--r-- 1 michaelligh staff 1572864 Apr 6 13:12
System.17fef9e0.0x0000000076f20000-0x000000007709ffff.dmp
-rw-r--r-- 1 michaelligh staff 65536 Apr 6 13:12
System.17fef9e0.0x000000007ffe0000-0x000000007ffeffff.dmp
-rw-r--r-- 1 michaelligh staff 1048576 Apr 6 13:12
csrss.exe.176006c0.0x0000000000000000-0x00000000000fffff.dmp
-rw-r--r-- 1 michaelligh staff 421888 Apr 6 13:12
csrss.exe.176006c0.0x0000000000100000-0x0000000000166fff.dmp
-rw-r--r-- 1 michaelligh staff 4096 Apr 6 13:12
csrss.exe.176006c0.0x0000000000170000-0x0000000000170fff.dmp
-rw-r--r-- 1 michaelligh staff 8192 Apr 6 13:12
csrss.exe.176006c0.0x0000000000180000-0x0000000000181fff.dmp
[snip]
The files are named like this:
ProcessName.PhysicalOffset.StartingVPN.EndingVPN.dmp
The reason the PhysicalOffset field exists is so you can distinguish between two
processes with the same name.
evtlogs
The evtlogs command extracts and parses binary event logs from memory. Binary
event logs are found on Windows XP and 2003 machines, therefore this plugin only
works on these architectures. These files are extracted from VAD of the services.exe
process, parsed and dumped to a specified location.
$ python vol.py -f WinXPSP1x64.vmem --profile=WinXPSP2x64 evtlogs -D output
Volatility Foundation Volatility Framework 2.4
Parsed data sent to appevent.txt
Parsed data sent to secevent.txt
Parsed data sent to sysevent.txt
There is also an option (--save-evt) to dump raw event logs for parsing with external
tools:
$ python vol.py -f WinXPSP1x64.vmem --profile=WinXPSP2x64 evtlogs
--save-evt -D output
Volatility Foundation Volatility Framework 2.4
Saved raw .evt file to appevent.evt
Parsed data sent to appevent.txt
Saved raw .evt file to secevent.evt
Parsed data sent to secevent.txt
Saved raw .evt file to sysevent.evt
Parsed data sent to sysevent.txt
Parsed output is pipe delimited to make it easier to import into excel files and the
"messages" are separated by semicolons:
$ cat output/secevent.txt
[snip]
If the --verbose flag is used, SIDs are also evaluated and placed in the parsed output
instead of the defaulting raw SID. This action takes longer to run, since the plugin has
to calculate each of the service SID and user SID from registry entries.
iehistory
This plugin recovers fragments of IE history index.dat cache files. It can find basic
accessed links (via FTP or HTTP), redirected links (--REDR), and deleted entries (--
LEAK). It applies to any process which loads and uses the wininet.dll library, not just
Internet Explorer. Typically that includes Windows Explorer and even malware
samples. For more information, see HowTo: Scan for Internet Cache/History and
URLs.
modscan
The modscan command finds LDR_DATA_TABLE_ENTRY structures by scanning
physical memory for pool tags. This can pick up previously unloaded drivers and
drivers that have been hidden/unlinked by rootkits. Unlike modules the order of
results has no relationship with the order in which the drivers loaded. As you can see
below, DumpIt.sys was found at the lowest physical offset, but it was probably one of
the last drivers to load (since it was used to acquire memory).
moddump
To extract a kernel driver to a file, use the moddump command. Supply the output
directory with -D or --dump-dir=DIR. Without any additional parameters, all drivers
identified by modlist will be dumped. If you want a specific driver, supply a regular
expression of the driver's name with --regex=REGEX or the module's base address
with --base=BASE.
ssdt
To list the functions in the Native and GUI SSDTs, use the ssdt command. This
displays the index, function name, and owning driver for each entry in the SSDT.
Please note the following:
There are multiple ways to locate the SSDTs in memory. Most tools do it by
finding the exported KeServiceDescriptorTable symbol in the NT module, but
this is not the way Volatility works.
The order and total number of functions in the SSDTs differ across operating
system versions. Thus, Volatility stores the information in a per-profile (OS)
dictionary which is auto-generated and cross-referenced using the
ntoskrnl.exe, ntdll.dll, win32k.sys, user32.dll and gdi32.dll modules from the
respective systems.
[snip]
driverscan
To find DRIVER_OBJECTs in physical memory using pool tag scanning, use the
driverscan command. This is another way to locate kernel modules, although not all
kernel modules have an associated DRIVER_OBJECT. The DRIVER_OBJECT is what
contains the 28 IRP (Major Function) tables, thus the driverirp command is based on
the methodology used by driverscan.
filescan
To find FILE_OBJECTs in physical memory using pool tag scanning, use the filescan
command. This will find open files even if a rootkit is hiding the files on disk and if
the rootkit hooks some API functions to hide the open handles on a live system. The
output shows the physical offset of the FILE_OBJECT, file name, number of pointers
to the object, number of handles to the object, and the effective permissions granted
to the object.
mutantscan
To scan physical memory for KMUTANT objects with pool tag scanning, use the
mutantscan command. By default, it displays all objects, but you can pass -s or
--silent to only show named mutexes. The CID column contains the process ID and
thread ID of the mutex owner if one exists.
For more information, see Andreas Schuster's Searching for Mutants.
symlinkscan
This plugin scans for symbolic link objects and outputs their information. In the past,
this has been used to link drive letters (i.e. D:, E:, F:, etc) to true crypt volumes (i.e.
\Device\TrueCryptVolume). For more information, see Symbolic Link
Objects and Identifying a Mounted True Crypt Volume from Artifacts in Volatile
Memory.
thrdscan
To find ETHREAD objects in physical memory with pool tag scanning, use the
thrdscan command. Since an ETHREAD contains fields that identify its parent process,
you can use this technique to find hidden processes. One such use case is
documented in the psxview command. Also, for verbose details, try
the threads plugin.
dumpfiles
An important concept that every computer scientist, especially those who have spent
time doing operating system research, is intimately familiar with is that of caching.
Files are cached in memory for system performance as they are accessed and used.
This makes the cache a valuable source from a forensic perspective since we are able
to retrieve files that were in use correctly, instead of file carving which does not make
use of how items are mapped in memory. Files may not be completely mapped in
memory (also for performance), so missing sections are zero padded. Files dumped
from memory can then be processed with external tools.
For more information see AAron Walter's post: MoVP 4.4 Cache Rules Everything
Around Me(mory).
-r REGEX, --regex=REGEX
Dump files matching REGEX
-i, --ignore-case Ignore case in pattern match
-o OFFSET, --offset=OFFSET
Dump files for Process with physical address OFFSET
-Q PHYSOFFSET, --physoffset=PHYSOFFSET
Dump File Object at physical address PHYSOFFSET
-D DUMP_DIR, --dump-dir=DUMP_DIR
Directory in which to dump extracted files
-S SUMMARY_FILE, --summary-file=SUMMARY_FILE
File where to store summary information
-p PID, --pid=PID Operate on these Process IDs (comma-separated)
-n, --name Include extracted filename in output file path
-u, --unsafe Relax safety constraints for more data
-F FILTER, --filter=FILTER
Filters to apply (comma-separated)
By default, dumpfiles iterates through the VAD and extracts all files that are mapped
as DataSectionObject, ImageSectionObject or SharedCacheMap. As an investigator,
however, you may want to perform a more targeted search. You can use the -r and -
i flags to specify a case-insensitive regex of a filename. In the output below, you can
see where the file was dumped from (DataSectionObject, ImageSectionObject or
SharedCacheMap), the offset of the _FILE_OBJECT, the PID of the process whose VAD
contained the file and the file path on disk:
$ python vol.py -f mebromi.raw dumpfiles -D output/ -r evt$ -i -S summary.txt
Volatility Foundation Volatility Framework 2.4
DataSectionObject 0x81ed6240 684
\Device\HarddiskVolume1\WINDOWS\system32\config\AppEvent.Evt
SharedCacheMap 0x81ed6240 684
\Device\HarddiskVolume1\WINDOWS\system32\config\AppEvent.Evt
DataSectionObject 0x8217beb0 684
\Device\HarddiskVolume1\WINDOWS\system32\config\SecEvent.Evt
DataSectionObject 0x8217bd78 684
\Device\HarddiskVolume1\WINDOWS\system32\config\SysEvent.Evt
SharedCacheMap 0x8217bd78 684
\Device\HarddiskVolume1\WINDOWS\system32\config\SysEvent.Evt
$ ls output/
file.684.0x81fc6ed0.vacb file.684.0x82256a48.dat file.684.0x82256e48.dat
file.None.0x82339cd8.vacb
file.684.0x8217b720.vacb file.684.0x82256c50.dat
file.None.0x82339c70.dat
The dumped filename is in the format of:
file.[PID].[OFFSET].ext
The OFFSET is the offset of the SharedCacheMap or the _CONTROL_AREA, not
the _FILE_OBJECT.
The extension (EXT) can be:
img – ImageSectionObject
dat - DataSectionObject
vacb – SharedCacheMap
You can look at the -S/--summary-file in order to map the file back to its original
filename:
{"name": "\\Device\\HarddiskVolume1\\WINDOWS\\system32\\config\\AppEvent.Evt",
"ofpath": "dumpfiles/file.684.0x82256e48.dat", "pid": 684,...
You can also use the parsesummary.py script to parse out the json output of the
summary file. The following shows an example of using this script. In addition to the
original file name, PID of the process that had the file open and size, you can see
which pages were present and which pages were missing and padded with zeros in
the parsed summary output:
unloadedmodules
Windows stores information on recently unloaded drivers for debugging purposes.
This gives you an alternative way to determine what happened on a system, besides
the well known modules and modscan plugins.
Networking
connections
To view TCP connections that were active at the time of the memory acquisition, use
the connections command. This walks the singly-linked list of connection structures
pointed to by a non-exported symbol in the tcpip.sys module.
This command is for x86 and x64 Windows XP and Windows 2003 Server only.
connscan
To find _TCPT_OBJECT structures using pool tag scanning, use the connscan command.
This can find artifacts from previous connections that have since been terminated, in
addition to the active ones. In the output below, you'll notice some fields have been
partially overwritten, but some of the information is still accurate. For example, the
very last entry's Pid field is 0, but all other fields are still in tact. Thus, while it may
find false positives sometimes, you also get the benefit of detecting as much
information as possible.
This command is for x86 and x64 Windows XP and Windows 2003 Server only.
This command is for x86 and x64 Windows XP and Windows 2003 Server only.
sockscan
To find _ADDRESS_OBJECT structures using pool tag scanning, use the sockscan
command. As with connscan, this can pick up residual data and artifacts from
previous sockets.
This command is for x86 and x64 Windows XP and Windows 2003 Server only.
$ python vol.py -f Win2K3SP0x64.vmem --profile=Win2003SP2x64 sockscan
Volatility Foundation Volatility Framework 2.4
Offset(P) PID Port Proto Protocol Address Create
Time
------------------ ------ ------ ------ --------------- ---------------
-----------
0x0000000000608010 804 123 17 UDP 172.16.237.150 2012-05-08
22:17:44
0x000000000eae8400 4 0 47 GRE 0.0.0.0 2012-02-24
18:09:07
0x000000000eaf1240 2136 1403 6 TCP 0.0.0.0 2012-06-25
12:42:37
0x000000000ec6dc90 4 445 6 TCP 0.0.0.0 2012-01-23
18:19:38
0x000000000ec96560 4 137 17 UDP 172.16.237.150 2012-06-25
12:40:55
0x000000000ecf7d20 2136 1408 6 TCP 0.0.0.0 2012-06-25
12:42:37
0x000000000ed5a010 2136 1352 6 TCP 0.0.0.0 2012-06-25
12:42:18
0x000000000ed84ca0 804 123 17 UDP 172.16.237.150 2012-06-25
12:40:55
0x000000000ee2d380 2136 1393 6 TCP 0.0.0.0 2012-06-25
12:42:37
0x000000000ee81120 804 123 17 UDP 127.0.0.1 2012-06-25
12:40:55
0x000000000eeda8c0 776 1363 17 UDP 0.0.0.0 2012-06-25
12:42:20
0x000000000f0be1a0 2136 1402 6 TCP 0.0.0.0 2012-06-25
12:42:37
0x000000000f0d0890 4 1133 6 TCP 0.0.0.0 2012-02-24
18:09:07
[snip]
netscan
To scan for network artifacts in 32- and 64-bit Windows Vista, Windows 2008 Server
and Windows 7 memory dumps, use the netscan command. This finds TCP
endpoints, TCP listeners, UDP endpoints, and UDP listeners. It distinguishes between
IPv4 and IPv6, prints the local and remote IP (if applicable), the local and remote port
(if applicable), the time when the socket was bound or when the connection was
established, and the current state (for TCP connections only). For more information,
see http://mnin.blogspot.com/2011/03/volatilitys-new-netscan-module.html
Volatility's New Netscan Module.
Registry
Volatility is the only memory forensics framework with the ability to carve registry
data. For more information, see BDG's Memory Registry Tools and Registry Code
Updates.
hivescan
To find the physical addresses of CMHIVEs (registry hives) in memory, use the
hivescan command. For more information, see BDG's Enumerating Registry Hives.
This plugin isn't generally useful by itself. Its meant to be inherited by other plugins
(such as hivelist below) that build on and interpret the information found in
CMHIVEs.
hivelist
To locate the virtual addresses of registry hives in memory, and the full paths to the
corresponding hive on disk, use the hivelist command. If you want to print values
from a certain hive, run this command first so you can see the address of the hives.
printkey
To display the subkeys, values, data, and data types contained within a specified
registry key, use the printkey command. By default, printkey will search all hives and
print the key information (if found) for the requested key. Therefore, if the key is
located in more than one hive, the information for the key will be printed for each
hive that contains it.
----------------------------
Registry: \SystemRoot\System32\Config\SOFTWARE
Key name: Svc (S)
Last updated: 2012-02-22 20:04:44
Subkeys:
(V) Vol
Values:
REG_QWORD VistaSp1 : (S) 128920218544262440
REG_DWORD AntiSpywareOverride : (S) 0
REG_DWORD ConfigMask : (S) 4361
Here you can see how the output appears when multiple hives (DEFAULT and
ntuser.dat) contain the same key "Software\Microsoft\Windows NT\CurrentVersion".
$ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 printkey -K
"Software\Microsoft\Windows NT\CurrentVersion"
Volatility Foundation Volatility Framework 2.4
Legend: (S) = Stable (V) = Volatile
----------------------------
Registry: \SystemRoot\System32\Config\DEFAULT
Key name: CurrentVersion (S)
Last updated: 2009-07-14 04:53:31
Subkeys:
(S) Devices
(S) PrinterPorts
Values:
----------------------------
Registry: \??\C:\Users\testing\ntuser.dat
Key name: CurrentVersion (S)
Last updated: 2012-02-22 11:26:13
Subkeys:
(S) Devices
(S) EFS
(S) MsiCorruptedFileRecovery
(S) Network
(S) PeerNet
(S) PrinterPorts
(S) Windows
(S) Winlogon
[snip]
If you want to limit your search to a specific hive, printkey also accepts a virtual
address to the hive. For example, to see the contents of HKEY_LOCAL_MACHINE, use
the command below. Note: the offset is taken from the previous hivelist output.
----------------------------
Registry: User Specified
Key name: CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902} (S)
Last updated: 2009-07-14 07:13:38
Subkeys:
(S) ATI Technologies
(S) Classes
(S) Clients
(S) Intel
(S) Microsoft
(S) ODBC
(S) Policies
(S) RegisteredApplications
(S) Sonic
(S) Wow6432Node
hivedump
To recursively list all subkeys in a hive, use the hivedump command and pass it the
virtual address to the desired hive.
hashdump
To extract and decrypt cached domain credentials stored in the registry, use the
hashdump command. For more information, see BDG's Cached Domain
Credentials and SANS Forensics 2009 - Memory Forensics and Registry Analysis.
To use hashdump, pass the virtual address of the SYSTEM hive as -y and the virtual
address of the SAM hive as -s, like this:
It is possible that a registry key is not available in memory. When this happens, you
may see the following error:
"ERROR : volatility.plugins.registry.lsadump: Unable to read hashes from registry"
You can try to see if the correct keys are available: "CurrentControlSet\Control\lsa"
from SYSTEM and "SAM\Domains\Account" from SAM. First you need to get the
"CurrentControlSet", for this we can use volshell (replace [REGISTRY ADDRESS]
(SYSTEM) below with the offset you get from hivelist), for example:
$ python vol.py -f XPSP3.vmem --profile=WinXPSP3x86 volshell
Volatility Foundation Volatility Framework 2.4
Current context: process System, pid=4, ppid=0 DTB=0x319000
Welcome to volshell Current memory image is:
file:///XPSP3.vmem
To get help, type 'hh()'
>>> import volatility.win32.hashdump as h
>>> import volatility.win32.hive as hive
>>> addr_space = utils.load_as(self._config)
>>> sysaddr = hive.HiveAddressSpace(addr_space, self._config, [SYSTEM REGISTRY
ADDRESS])
>>> print h.find_control_set(sysaddr)
1
>>> ^D
Then you can use the printkey plugin to make sure the keys and their data are there.
Since the "CurrentControlSet" is 1 in our previous example, we use "ControlSet001"
in the first command:
lsadump
To dump LSA secrets from the registry, use the lsadump command. This exposes
information such as the default password (for systems with autologin enabled), the
RDP public key, and credentials used by DPAPI.
0000 00 92 8D 60 01 FF C8 01 ...`....
_SC_Dnscache
L$HYDRAENCKEY_28ada6da-d622-11d1-9cb9-00c04fb16e75
0000 52 53 41 32 48 00 00 00 00 02 00 00 3F 00 00 00 RSA2H.......?...
0010 01 00 01 00 37 CE 0C C0 EF EC 13 C8 A4 C5 BC B8 ....7...........
0020 AA F5 1A 7C 50 95 A4 E9 3B BA 41 C8 53 D7 CE C6 ...|P...;.A.S...
0030 CB A0 6A 46 7C 70 F3 21 17 1C FB 79 5C C1 83 68 ..jF|p....y...h
0040 91 E5 62 5E 2C AC 21 1E 79 07 A9 21 BB F0 74 E8 ..b^,..y....t.
0050 85 66 F4 C4 00 00 00 00 00 00 00 00 F9 D7 AD 5C .f..............
0060 B4 7C FB F6 88 89 9D 2E 91 F2 60 07 10 42 CA 5A .|........`..B.Z
0070 FC F0 D1 00 0F 86 29 B5 2E 1E 8C E0 00 00 00 00 ......).........
0080 AF 43 30 5F 0D 0E 55 04 57 F9 0D 70 4A C8 36 01 .C0_..U.W..pJ.6.
0090 C2 63 45 59 27 62 B5 77 59 84 B7 65 8E DB 8A E0 .cEY'b.wY..e....
00A0 00 00 00 00 89 19 5E D8 CB 0E 03 39 E2 52 04 37 ......^....9.R.7
00B0 20 DC 03 C8 47 B5 2A B3 9C 01 65 15 FF 0F FF 8F ...G.*...e.....
00C0 17 9F C1 47 00 00 00 00 1B AC BF 62 4E 81 D6 2A ...G.......bN..*
00D0 32 98 36 3A 11 88 2D 99 3A EA 59 DE 4D 45 2B 9E 2.6:..-.:.Y.ME+.
00E0 74 15 14 E1 F2 B5 B2 80 00 00 00 00 75 BD A0 36 t...........u..6
00F0 20 AD 29 0E 88 E0 FD 5B AD 67 CA 88 FC 85 B9 82 .)....[.g......
0100 94 15 33 1A F1 65 45 D1 CA F9 D8 4C 00 00 00 00 ..3..eE....L....
0110 71 F0 0B 11 F2 F1 AA C5 0C 22 44 06 E1 38 6C ED q........"D..8l.
0120 6E 38 51 18 E8 44 5F AD C2 CE 0A 0A 1E 8C 68 4F n8Q..D_.......hO
0130 4D 91 69 07 DE AA 1A EC E6 36 2A 9C 9C B6 49 1F M.i......6*...I.
0140 B3 DD 89 18 52 7C F8 96 4F AF 05 29 DF 17 D8 48 ....R|..O..)...H
0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0170 00 00 00 00 00 00 00 00 00 00 00 00 ............
DPAPI_SYSTEM
0000 01 00 00 00 24 04 D6 B0 DA D1 3C 40 BB EE EC 89 ....$.....<@....
0010 B4 BB 90 5B 9A BF 60 7D 3E 96 72 CD 9A F6 F8 BE ...[..`}>.r.....
0020 D3 91 5C FA A5 8B E6 B4 81 0D B6 D4 ............
Possible items are:
userassist
To get the UserAssist keys from a sample you can use the userassist plugin. For more
information see Gleeda's Volatility UserAssist plugin post.
Subkeys:
Values:
REG_BINARY Microsoft.Windows.GettingStarted :
Count: 14
Focus Count: 21
Time Focused: 0:07:00.500000
Last updated: 2010-03-09 19:49:20
0000 00 00 00 00 0E 00 00 00 15 00 00 00 A0 68 06 00 .............h..
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................
0030 00 00 80 BF 00 00 80 BF FF FF FF FF EC FE 7B 9C ..............{.
0040 C1 BF CA 01 00 00 00 00 ........
REG_BINARY UEME_CTLSESSION :
Count: 187
Focus Count: 1205
Time Focused: 6:25:06.216000
Last updated: 1970-01-01 00:00:00
[snip]
REG_BINARY %windir%\system32\calc.exe :
Count: 12
Focus Count: 17
Time Focused: 0:05:40.500000
Last updated: 2010-03-09 19:49:20
REG_BINARY Z:\vmware-share\apps\odbg110\OLLYDBG.EXE :
Count: 11
Focus Count: 266
Time Focused: 1:19:58.045000
Last updated: 2010-03-18 01:56:31
0000 00 00 00 00 0B 00 00 00 0A 01 00 00 69 34 49 00 ............i4I.
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................
0030 00 00 80 BF 00 00 80 BF FF FF FF FF 70 3B CB 3A ............p;.:
0040 3E C6 CA 01 00 00 00 00 >.......
[snip]
shellbags
This plugin parses and prints Shellbag (pdf) information obtained from the registry.
For more information see Shellbags in Memory, SetRegTime, and TrueCrypt Volumes.
There are two options for output: verbose (default) and bodyfile format.
***************************************************************************
Registry: \??\C:\Users\user\AppData\Local\Microsoft\Windows\UsrClass.dat
Key: Local Settings\Software\Microsoft\Windows\Shell\BagMRU
Last updated: 2011-10-20 15:14:21
Value Mru Entry Type GUID GUID
Description Folder IDs
------- ----- -------------- ----------------------------------------
-------------------- ----------
1 2 Folder Entry 031e4825-7b94-4dc3-b131-e946b44c8dd5 Libraries
EXPLORER, LIBRARIES
0 1 Folder Entry 20d04fe0-3aea-1069-a2d8-08002b30309d My Computer
EXPLORER, MY_COMPUTER
2 0 Folder Entry 59031a47-3f72-44a7-89c5-5595fe6b30ee Users
EXPLORER, USERS
***************************************************************************
***************************************************************************
Registry: \??\C:\Users\user\AppData\Local\Microsoft\Windows\UsrClass.dat
Key: Local Settings\Software\Microsoft\Windows\Shell\BagMRU\0
Last updated: 2011-05-15 23:10:01
Value Mru Entry Type Path
------- ----- -------------- ----
1 0 Volume Name Z:\
0 1 Volume Name C:\
***************************************************************************
[snip]
***************************************************************************
Registry: \??\C:\Users\user\AppData\Local\Microsoft\Windows\UsrClass.dat
Key: Local Settings\Software\Microsoft\Windows\Shell\BagMRU\0\0\0\0
Last updated: 2011-05-15 23:03:22
Value Mru File Name Modified Date Create Date Access Date
File Attr Path
------- ----- -------------- -------------------- --------------------
-------------------- ------------------------- ----
0 0 AppData 2011-05-15 22:57:52 2011-05-15 22:57:52 2011-05-15
22:57:52 HID, NI, DIR C:\Users\user\AppData
***************************************************************************
[snip]
Another option is to use the --output=body option for TSK 3.x bodyfile format. You
can use this output option when you want to combine output
from timeliner, mftparser and timeliner. You can also include a machine identifier in
the bodyfile header with the --machine flag (this is useful when combining timelines
from multiple machines). Only ITEMPOS and FILE_ENTRY items are output with the
bodyfile format:
$ python vol.py -f win7.vmem --profile=Win7SP1x86 shellbags --output=body
Volatility Foundation Volatility Framework 2.4
Scanning for registries....
Gathering shellbag items and building path tree...
0|[SHELLBAGS ITEMPOS] Name: Adobe Reader X.lnk/Attrs: ARC/FullPath: Adobe Reader
X.lnk/Registry: \??\C:\Users\user\ntuser.dat /Key:
Software\Microsoft\Windows\Shell\Bags\1\Desktop/LW: 2011-10-20 15:24:46 UTC+0000|
0|---------------|0|0|0|1319124004|1319124004|1319124004|1319124004
0|[SHELLBAGS ITEMPOS] Name: EnCase v6.18.lnk/Attrs: ARC/FullPath: EnCase
v6.18.lnk/Registry: \??\C:\Users\user\ntuser.dat /Key:
Software\Microsoft\Windows\Shell\Bags\1\Desktop/LW: 2011-10-20 15:24:46 UTC+0000|
0|---------------|0|0|0|1305500546|1305500546|1305500546|1305500546
0|[SHELLBAGS ITEMPOS] Name: VMware Shared Folders.lnk/Attrs: ARC/FullPath: VMware
Shared Folders.lnk/Registry: \??\C:\Users\user\ntuser.dat /Key:
Software\Microsoft\Windows\Shell\Bags\1\Desktop/LW: 2011-10-20 15:24:46 UTC+0000|
0|---------------|0|0|0|1319123586|1319123586|1305500948|1305500948
[snip]
0|[SHELLBAGS FILE_ENTRY] Name: Program Files/Attrs: RO, DIR/FullPath: C:\Program
Files/Registry: \??\C:\Users\user\AppData\Local\Microsoft\Windows\UsrClass.dat
/Key: Local Settings\Software\Microsoft\Windows\Shell\BagMRU\0\0/LW: 2011-05-15
23:03:35 UTC+0000|0|---------------|0|0|0|1305500504|1305500504|1247539026|
1247539026
0|[SHELLBAGS FILE_ENTRY] Name: Users/Attrs: RO, DIR/FullPath:
C:\Users/Registry: \??\C:\Users\user\AppData\Local\Microsoft\Windows\UsrClass.dat
/Key: Local Settings\Software\Microsoft\Windows\Shell\BagMRU\0\0/LW: 2011-05-15
23:03:35 UTC+0000|0|---------------|0|0|0|1305500270|1305500270|1247539026|
1247539026
[snip]
shimcache
This plugin parses the Application Compatibility Shim Cache registry key.
getservicesids
The getservicesids command calculates the SIDs for services on a machine and
outputs them in Python dictionary format for future use. The service names are taken
from the registry ("SYSTEM\CurrentControlSet\Services"). For more information on
how these SIDs are calculated, see Timeliner Release Documentation (pdf). Example
output can be seen below:
$ python vol.py -f WinXPSP1x64.vmem --profile=WinXPSP2x64 getservicesids
Volatility Foundation Volatility Framework 2.4
servicesids = {
'S-1-5-80-2675092186-3691566608-1139246469-1504068187-1286574349':
'Abiosdsk',
'S-1-5-80-850610371-2162948594-2204246734-1395993891-583065928': 'ACPIEC',
'S-1-5-80-2838020983-819055183-730598559-323496739-448665943': 'adpu160m',
'S-1-5-80-3218321610-3296847771-3570773115-868698368-3117473630': 'aec',
'S-1-5-80-1344778701-2960353790-662938617-678076498-4183748354': 'aic78u2',
'S-1-5-80-1076555770-1261388817-3553637611-899283093-3303637635': 'Alerter',
'S-1-5-80-1587539839-2488332913-1287008632-3751426284-4220573165': 'AliIde',
'S-1-5-80-4100430975-1934021090-490597466-3817433801-2954987127': 'AmdIde',
'S-1-5-80-258649362-1997344556-1754272750-1450123204-3407402222': 'Atdisk',
[snip]
In order to save output to a file, use the --output-file option.
dumpregistry
The dumpregistry plugin allows you to dump a registry hive to disk. It works on all
supported Windows versions (Windows XP-8.1). By default the plugin will dump all
registry files (including virtual registries like HARDWARE) found to disk, however you
may specify the virtual offset for a specific hive in order to only dump one registry at
a time. One caveat about using this plugin (or the dumpfiles plugin) is that there may
be holes in the dumped registry file, so offline registry tools may crash if they are not
made robustly to handle "corrupt" files. These holes are denoted in the text output
with lines like Physical layer returned None for index 2000, filling with NULL .
Example output is shown below:
$ python vol.py -f voltest.dmp --profile=Win7SP1x86 dumpregistry -D output
**************************************************
Writing out registry: registry.0x888101e0.no_name.reg
**************************************************
**************************************************
Writing out registry: registry.0x8cec09d0.ntuserdat.reg
Physical layer returned None for index 9000, filling with NULL
Physical layer returned None for index a000, filling with NULL
Physical layer returned None for index b000, filling with NULL
[snip]
**************************************************
Writing out registry: registry.0x8883c7d0.HARDWARE.reg
Physical layer returned None for index 2000, filling with NULL
Physical layer returned None for index 3000, filling with NULL
Physical layer returned None for index 4000, filling with NULL
[snip]
**************************************************
Writing out registry: registry.0x88c9c008.SAM.reg
**************************************************
**************************************************
Writing out registry: registry.0x8a5449d0.NTUSERDAT.reg
**************************************************
[snip]
$ file output/*
output/registry.0x888101e0.no_name.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8881c008.SYSTEM.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8883c7d0.HARDWARE.reg: data
output/registry.0x888c14e8.DEFAULT.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x88c3b898.SECURITY.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x88c9c008.SAM.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8a4c2008.NTUSERDAT.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8a5449d0.NTUSERDAT.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8c7e7008.BCD.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8cec09d0.ntuserdat.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x8d432008.SOFTWARE.reg: MS Windows registry file, NT/2000 or
above
output/registry.0x945229d0.UsrClassdat.reg: MS Windows registry file, NT/2000 or
above
output/registry.0xa019c9d0.Syscachehve.reg: MS Windows registry file, NT/2000 or
above
Notice that the HARDWARE registry has "Data" as the type. This is because the first few
cells of the registry are zeroed out. If you examine the registry with a hex editor, you
will see valid keys and values:
$ xxd output/registry.0x8883c7d0.HARDWARE.reg |grep -v "0000 0000 0000 0000 0000
0000 0000 0000" |less
0001000: 6862 696e 0000 0000 0010 0000 0000 0000 hbin............
0001020: a8ff ffff 6e6b 2c00 c1be 7203 3eba cf01 ....nk,...r.>...
0001030: 0000 0000 d002 0000 0300 0000 0100 0000 ................
0001040: 9018 0000 2801 0080 0000 0000 ffff ffff ....(...........
0001050: 7800 0000 ffff ffff 1600 0000 0000 0000 x...............
0001060: 0000 0000 0000 0000 0000 0000 0800 0000 ................
0001070: 4841 5244 5741 5245 58ff ffff 736b 0000 HARDWAREX...sk..
0001080: 7800 0000 7800 0000 2800 0000 8c00 0000 x...x...(.......
0001090: 0100 0480 7000 0000 8000 0000 0000 0000 ....p...........
00010a0: 1400 0000 0200 5c00 0400 0000 0002 1400 ......\.........
00010b0: 3f00 0f00 0101 0000 0000 0005 1200 0000 ?...............
00010c0: 0002 1800 3f00 0f00 0102 0000 0000 0005 ....?...........
00010d0: 2000 0000 2002 0000 0002 1400 1900 0200 ... ...........
00010e0: 0101 0000 0000 0001 0000 0000 0002 1400 ................
00010f0: 1900 0200 0101 0000 0000 0005 0c00 0000 ................
0001100: 0102 0000 0000 0005 2000 0000 2002 0000 ........ ... ...
0001110: 0101 0000 0000 0005 1200 0000 0000 0000 ................
0001120: a0ff ffff 6e6b 2000 3eb5 f30a 3eba cf01 ....nk .>...>...
0001130: 0000 0000 2000 0000 0500 0000 0100 0000 .... ...........
0001140: 6828 0200 701f 0080 0000 0000 ffff ffff h(..p...........
0001150: 7800 0000 ffff ffff 1c00 0000 0000 0000 x...............
0001160: 0000 0000 0000 0000 0000 0000 0900 0000 ................
0001170: 4445 5649 4345 4d41 5000 0000 0000 0000 DEVICEMAP.......
0001180: f0ff ffff 6c66 0100 0802 0000 5379 7374 ....lf......Syst
0001190: a0ff ffff 6e6b 2000 00fc 6d03 3eba cf01 ....nk ...m.>...
00011a0: 0000 0000 2000 0000 0100 0000 0000 0000 .... ...........
00011b0: 8001 0000 ffff ffff 0000 0000 ffff ffff ................
00011c0: 7800 0000 ffff ffff 0c00 0000 0000 0000 x...............
00011d0: 0000 0000 0000 0000 0000 0000 0b00 0000 ................
00011e0: 4445 5343 5249 5054 494f 4e00 0000 0000 DESCRIPTION.....
00011f0: f0ff ffff 6c66 0100 901b 0000 494e 5445 ....lf......INTE
0001200: f8ff ffff 181a 0000 a8ff ffff 6e6b 2000 ............nk .
0001210: b68f c70b 3eba cf01 0000 0000 9001 0000 ....>...........
0001220: 0300 0000 0200 0000 f012 0000 a05a 0080 .............Z..
0001230: 0800 0000 8017 0000 7800 0000 ffff ffff ........x.......
0001240: 2c00 0000 0000 0000 2a00 0000 6600 0000 ,.......*...f...
0001250: 0000 0000 0600 0000 5379 7374 656d 0000 ........System..
0001260: d0ff ffff 766b 1500 1000 0000 9002 0000 ....vk..........
0001270: 0300 0000 0100 0000 436f 6d70 6f6e 656e ........Componen
0001280: 7420 496e 666f 726d 6174 696f 6e00 0000 t Information...
[snip]
You may also dump only one registry at a time by using the virtual offset of the hive:
Physical layer returned None for index 9000, filling with NULL
Physical layer returned None for index a000, filling with NULL
Physical layer returned None for index b000, filling with NULL
Physical layer returned None for index c000, filling with NULL
Physical layer returned None for index d000, filling with NULL
Physical layer returned None for index e000, filling with NULL
Physical layer returned None for index f000, filling with NULL
Physical layer returned None for index 10000, filling with NULL
Physical layer returned None for index 11000, filling with NULL
Physical layer returned None for index 20000, filling with NULL
Physical layer returned None for index 21000, filling with NULL
$ file output/*
output/registry.0x8cec09d0.ntuserdat.reg: MS Windows registry file, NT/2000 or
above
crashinfo
Information from the crashdump header can be printed using the crashinfo
command. You will see information like that of the Microsoft dumpcheck utility.
hibinfo
The hibinfo command reveals additional information stored in the hibernation file,
including the state of the Control Registers, such as CR0, etc. It also identifies the
time at which the hibernation file was created, the state of the hibernation file, and
the version of windows being hibernated. Example output for the function is shown
below.
imagecopy
The imagecopy command allows you to convert any existing type of address space
(such as a crashdump, hibernation file, virtualbox core dump, vmware snapshot, or
live firewire session) to a raw memory image. This conversion be necessary if some of
your other forensic tools only support reading raw memory dumps.
The profile should be specified for this command, so if you don't know it already, use
the kdbgscan or imageinfo commands first. The output file is specified with the -O
flag. The progress is updated as the file is converted:
$ python vol.py -f win7_x64.dmp --profile=Win7SP0x64 imagecopy -O copy.raw
Volatility Foundation Volatility Framework 2.4
Writing data (5.00 MB chunks): |.......................................|
raw2dmp
To convert a raw memory dump (for example from a win32dd acquisition or a
VMware .vmem file) into a Microsoft crash dump, use the raw2dmp command. This is
useful if you want to load the memory in the WinDbg kernel debugger for analysis.
vboxinfo
To pull details from a virtualbox core dump, use the vboxinfo command.
Magic: 0xc01ac0de
Format: 0x10000
VirtualBox 4.1.23 (revision 80870)
CPUs: 1
vmwareinfo
Use this plugin to analyze header information from vmware saved state (vmss) or
vmware snapshot (vmsn) files. The metadata contains CPU registers, the entire VMX
configuration file, memory run information, and PNG screenshots of the guest VM.
hpakinfo
This plugin shows info from an hpak formatted memory dump created by FDPro.exe.
Header: HPAKSECTHPAK_SECTION_PAGEDUMP
Length: 0x30000000
Offset: 0x200009d0
NextOffset: 0x500009d0
Name: dumpfile.sys
Compressed: 0
hpakextract
If you have an hpak file whose contents are compressed, you can extract and
decompress the physical memory image using this plugin.
File System
mbrparser
Scans for and parses potential Master Boot Records (MBRs). There are different
options for finding MBRs and filtering output. For more information please
see Recovering Master Boot Records from Memory. While this plugin was written
with Windows bootkits in mind, it can also be used with memory samples from other
systems.
When run without any extra options, mbrparser scans for and returns information all
potential MBRs defined by signature ('\x55\xaa') found in memory. Information
includes: disassembly of bootcode (must have distorm3 installed) and partition
information. This will most likely have false positives.
If distorm3 is not installed, the -H/--hex option can be used to get the entire
bootcode section in hex instead of disassembly:
$ python vol.py -f [sample] mbrparser -H
If the physical offset of the MBR is known, it can be specified with the -o/--
offset= option for example:
$ python vol.py -f [sample] -o 0x600 mbrparser
If the md5 hash of the desired bootcode is known, one can be specified using either
the -M/--hash (the hash of bootcode up to the RET instruction) or -F/--fullhash (the
hash of full bootcode) option.
$ python vol.py mbrparser -f AnalysisXPSP3.vmem -M
6010862faee6d5e314aba791380d4f41
or
mftparser
This plugin scans for potential Master File Table (MFT) entries in memory (using
"FILE" and "BAAD" signatures) and prints out information for certain attributes,
currently: $FILE_NAME ($FN), $STANDARD_INFORMATION ($SI), $FN and $SI attributes from
the $ATTRIBUTE_LIST, $OBJECT_ID (default output only) and resident $DATA. This plugin
has room for expansion, however, and VTypes for other attributes are already
included. For more information please see Reconstructing the MBR and MFT from
Memory (OMFW 2012 slides). Options of interest include:
This plugin may take a while to run before seeing output, since it scans first and then
builds the directory tree for full file paths.
$STANDARD_INFORMATION
Creation Modified MFT Altered Access Date
Type
-------------------- -------------------- --------------------
-------------------- ----
2010-02-27 20:12:32 2010-02-27 20:12:32 2010-02-27 20:12:32 2010-02-27 20:12:32
Archive
$FILE_NAME
Creation Modified MFT Altered Access Date
Name/Path
-------------------- -------------------- --------------------
-------------------- ---------
2010-02-27 20:12:32 2010-02-27 20:12:32 2010-02-27 20:12:32 2010-02-27 20:12:32
Documents and Settings\Administrator\Cookies\ADMINI~1.TXT
$FILE_NAME
Creation Modified MFT Altered Access Date
Name/Path
-------------------- -------------------- --------------------
-------------------- ---------
2010-02-27 20:12:32 2010-02-27 20:12:32 2010-02-27 20:12:32 2010-02-27 20:12:32
Documents and Settings\Administrator\Cookies\administrator@search-network-
plus[1].txt
$DATA
0000000000: 65 78 70 0a 31 39 0a 73 65 61 72 63 68 2d 6e 65 exp.19.search-ne
0000000010: 74 77 6f 72 6b 2d 70 6c 75 73 2e 63 6f 6d 2f 0a twork-plus.com/.
0000000020: 31 35 33 36 0a 33 03 00 32 34 33 33 39 32 30 0a 1536.3..2433920.
0000000030: 33 30 30 36 32 36 30 35 0a 38 33 37 34 31 36 35 30062605.8374165
0000000040: 37 36 0a 33 30 30 36 32 35 36 39 0a 2a 0a 76.30062569.*.
***************************************************************************
[snip]
***************************************************************************
MFT entry found at offset 0x1cdbac00
Type: In Use & File
Record Number: 12079
Link count: 1
$STANDARD_INFORMATION
Creation Modified MFT Altered Access Date
Type
-------------------- -------------------- --------------------
-------------------- ----
2010-02-27 20:12:28 2010-02-27 20:12:28 2010-02-27 20:12:28 2010-02-27 20:12:28
Archive
$FILE_NAME
Creation Modified MFT Altered Access Date
Name/Path
-------------------- -------------------- --------------------
-------------------- ---------
2010-02-27 20:12:28 2010-02-27 20:12:28 2010-02-27 20:12:28 2010-02-27 20:12:28
Documents and Settings\Administrator\Local Settings\Temp\plugtmp\PDF.php
$DATA
Non-Resident
***************************************************************************
[snip]
The bodyfile output is also an option. It is recommended that the output be stored in
a file using the --output-file option, since it is quite lengthy. The following shows
creating a bodyfile using mftparser while dumping resident files. You can also see a
file of interest that is created on the system ( f.txt) which happens to be recovered in
the output directory:
$ python vol.py -f grrcon.img mftparser --output=body -D output --output-
file=grrcon_mft.body
Volatility Foundation Volatility Framework 2.4
Scanning for MFT entries and building directory, this can take a while
$ cat grrcon_mft.body
[snip]
0|[MFT STD_INFO] WINDOWS\system32\systems (Offset: 0x15938400)|
12029|---------------|0|0|0|1335579320|1335579320|1335579320|1335578463
0|[MFT FILE_NAME] WINDOWS\system32\systems\f.txt (Offset: 0x15938800)|12030|---
a-----------|0|0|0|1335578503|1335578503|1335578503|1335578503
0|[MFT STD_INFO] WINDOWS\system32\systems\f.txt (Offset: 0x15938800)|12030|---
a-----------|0|0|0|1335578503|1335578503|1335578503|1335578503
0|[MFT FILE_NAME] WINDOWS\system32\systems\g.exe (Offset: 0x15938c00)|12031|---
a-----------|0|0|0|1335578514|1335578514|1335578514|1335578514
0|[MFT STD_INFO] WINDOWS\system32\systems\g.exe (Offset: 0x15938c00)|12031|---
a-----------|0|0|0|1335579014|1335578514|1335578514|1335578514
0|[MFT FILE_NAME] WINDOWS\inf\divasrv.inf (Offset: 0x15c83000)|2192|---
a-----------|0|0|22554|1332601266|1332601266|1332601266|1332601235
[snip]
$ ls output/*15938800*
output/file.0x15938800.data0.dmp
$ cat output/*15938800*
open 66.32.119.38
jack
2awes0me
lcd c:\WINDOWS\System32\systems
cd /home/jack
binary
mput "*.txt"
disconnect
bye
The Sleuthkit mactime utility can then be used to output the bodyfile in a readable
manner:
$ mactime -b grrcon_mft.body -d -z UTC |less
[snip]
Sat Apr 28 2012 02:01:43,0,macb,---a-----------,0,0,12030,"[MFT FILE_NAME]
WINDOWS\system32\systems\f.txt (Offset: 0x15938800)"
Sat Apr 28 2012 02:01:43,0,macb,---a-----------,0,0,12030,"[MFT STD_INFO]
WINDOWS\system32\systems\f.txt (Offset: 0x15938800)"
Sat Apr 28 2012 02:01:54,0,macb,---a-----------,0,0,12031,"[MFT FILE_NAME]
WINDOWS\system32\systems\g.exe (Offset: 0x15938c00)"
Sat Apr 28 2012 02:01:54,0,m.cb,---a-----------,0,0,12031,"[MFT STD_INFO]
WINDOWS\system32\systems\g.exe (Offset: 0x15938c00)"
Sat Apr 28 2012 02:02:05,0,macb,---a-----------,0,0,12032,"[MFT FILE_NAME]
WINDOWS\system32\systems\p.exe (Offset: 0x18229000)"
Sat Apr 28 2012 02:02:05,0,...b,---a-----------,0,0,12032,"[MFT STD_INFO]
WINDOWS\system32\systems\p.exe (Offset: 0x18229000)"
Sat Apr 28 2012 02:02:06,0,m...,---a-----------,0,0,12032,"[MFT STD_INFO]
WINDOWS\system32\systems\p.exe (Offset: 0x18229000)"
Sat Apr 28 2012 02:02:17,0,macb,---a-----------,0,0,12033,"[MFT FILE_NAME]
WINDOWS\system32\systems\r.exe (Offset: 0x18229400)"
Sat Apr 28 2012 02:02:17,0,m.cb,---a-----------,0,0,12033,"[MFT STD_INFO]
WINDOWS\system32\systems\r.exe (Offset: 0x18229400)"
Sat Apr 28 2012 02:02:26,0,macb,---a-----------,0,0,12034,"[MFT FILE_NAME]
WINDOWS\system32\systems\sysmon.exe (Offset: 0x18229800)"
Sat Apr 28 2012 02:02:26,0,...b,---a-----------,0,0,12034,"[MFT STD_INFO]
WINDOWS\system32\systems\sysmon.exe (Offset: 0x18229800)"
Sat Apr 28 2012 02:02:27,0,m.c.,---a-----------,0,0,12034,"[MFT STD_INFO]
WINDOWS\system32\systems\sysmon.exe (Offset: 0x18229800)"
[snip]
Miscellaneous
strings
For a given image and a file with lines of the form <decimal_offset>:<string>,
or <decimal_offset> <string>, output the corresponding process and virtual
addresses where that string can be found. Expected input for this tool is the output
of Microsoft Sysinternals' Strings utility, or another utility that provides similarly
formatted offset:string mappings. Note that the input offsets are physical offsets
from the start of the file/image.
Sysinternals Strings can be used on Linux/Mac using Wine. Output should be
redirected to a file to be fed to the Volatility strings plugin. If you're using GNU
strings command, use the -td flags to produce offsets in decimal (the plugin does
not accept hex offsets). Some example usages are as follows:
Windows
16392:@@@
17409:
17441:
17473:"""
17505:###
17537:$$$
17569:%%%
17601:&&&
17633:'''
17665:(((
17697:)))
17729:***
EnCase Keyword Export
You can also use EnCase to export keywords and offsets in this format with some
tweaking. One thing to note is that EnCase exports text in UTF-16 with a BOM of
(U+FEFF) which can cause issues with the strings plugin. An example look at the
exported keyword file:
File Offset Hit Text
114923 DHCP
114967 DHCP
115892 DHCP
115922 DHCP
115952 DHCP
116319 DHCP
[snip]
Now tweaking the file by removing the header and tabs we have:
114923:DHCP
114967:DHCP
115892:DHCP
115922:DHCP
115952:DHCP
116319:DHCP
[snip]
We can see that it is UTF-16 and has a BOM of (U+FEFF) by using a hex editor.
$ file export.txt
export.txt: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
0000000: fffe 3100 3100 3400 3900 3200 3300 3a00 ..1.1.4.9.2.3.:.
[snip]
We have to convert this to ANSI or UTF-8. In Windows you can open the text file and
use the "Save As" dialog to save the file as ANSI (in the "Encoding" drop-down
menu). In Linux you can use iconv:
$ iconv -f UTF-16 -t UTF-8 export.txt > export1.txt
NOTE: You must make sure there are NO blank lines in your final "strings" file.
Now we can see a difference in how these two files are handled:
[snip]
NOTE: The Volatility strings output is very verbose and it is best to redirect or save to
a file. The following command saves the output using the --output-file option and
filename "win7_vol_strings.txt"
$ python vol.py --profile=Win7SP0x86 strings –f win7.dd –s win7_strings.txt
--output-file=win7_vol_strings.txt
By default strings will only provide output for processes found by walking the
doubly linked list pointed to by PsActiveProcessHead (see pslist) in addition to kernel
addresses. strings can also provide output for hidden processes (see psscan) by
using the (capital) -S switch:
$ python vol.py --profile=Win7SP0x86 strings –f win7.dd –s win7_strings.txt
--output-file=win7_vol_strings.txt -S
Also an EPROCESS offset can be provided:
$ less win7_vol_strings.txt
[snip]
[snip]
$ cat win7_vol_strings.txt | \
perl -e 'while(<>){if(/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-
5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/){print $_;}}' > IPs.txt
For all URLs:
$ cat win7_vol_strings.txt | \
perl -e 'while(<>){ if(/(http|https|ftp|mail)\:[\/\w.]+/){print $_;}}' > URLs.txt
Depending on the context, your searches will vary.
volshell
If you want to interactively explore a memory image, use the volshell command. This
gives you an interface similar to WinDbg into the memory dump. For example, you
can:
List processes
Switch into a process's context
Display types of structures/objects
Overlay a type over a given address
Walk linked lists
Disassemble code at a given address
Note: volshell can take advantage of IPython if you have it installed. This will add tab-
completion and saved command history.
>>> ps()
Name PID PPID Offset
System 4 0 0x83dad960
smss.exe 252 4 0x84e47840
csrss.exe 348 340 0x8d5ffd40
wininit.exe 384 340 0x84e6e3d8
csrss.exe 396 376 0x8d580530
winlogon.exe 424 376 0x8d598530
services.exe 492 384 0x8d4cc030
lsass.exe 500 384 0x8d6064a0
lsm.exe 508 384 0x8d6075d8
svchost.exe 616 492 0x8d653030
svchost.exe 680 492 0x8d673b88
svchost.exe 728 492 0x8d64fb38
taskhost.exe 1156 492 0x8d7ee030
dwm.exe 956 848 0x8d52bd40
explorer.exe 1880 1720 0x8d66c1a8
wuauclt.exe 1896 876 0x83ec3238
VMwareTray.exe 2144 1880 0x83f028d8
VMwareUser.exe 2156 1880 0x8d7893b0
[snip]
Now switch into Explorer's context and print the data with either db (display as
canonical hexdump) or dd (display as double-words):
>>> dd(0x779f0000)
779f0000 00905a4d 00000003 00000004 0000ffff
779f0010 000000b8 00000000 00000040 00000000
779f0020 00000000 00000000 00000000 00000000
779f0030 00000000 00000000 00000000 000000e0
779f0040 0eba1f0e cd09b400 4c01b821 685421cd
779f0050 70207369 72676f72 63206d61 6f6e6e61
779f0060 65622074 6e757220 206e6920 20534f44
779f0070 65646f6d 0a0d0d2e 00000024 00000000
>>> db(0x779f0000)
779f0000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............
779f0010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......
779f0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
779f0030 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00 ................
779f0040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 ..........L.Th
779f0050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is program canno
779f0060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 t be run in DOS
779f0070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 mode....$.......
So there is a PE at 0x779f0000 in explorer.exe. If you want to disassemble instructions
at RVA 0x2506 in the PE, do this:
>>> dt("_EPROCESS")
'_EPROCESS' (704 bytes)
0x0 : Pcb ['_KPROCESS']
0x98 : ProcessLock ['_EX_PUSH_LOCK']
0xa0 : CreateTime ['_LARGE_INTEGER']
0xa8 : ExitTime ['_LARGE_INTEGER']
0xb0 : RundownProtect ['_EX_RUNDOWN_REF']
0xb4 : UniqueProcessId ['pointer', ['void']]
0xb8 : ActiveProcessLinks ['_LIST_ENTRY']
0xc0 : ProcessQuotaUsage ['array', 2, ['unsigned long']]
0xc8 : ProcessQuotaPeak ['array', 2, ['unsigned long']]
0xd0 : CommitCharge ['unsigned long']
0xd4 : QuotaBlock ['pointer', ['_EPROCESS_QUOTA_BLOCK']]
[snip]
To overlay the EPROCESS types onto the offset for explorer.exe, do this:
If you explicitly supply an address space, the one you supplied will be used.
Imagine you're using one of the scan commands (psscan, connscan, etc.) and you
think it has picked up a false positive. The scan commands output a physical offset
(offset into the memory dump file). You want to explore the data around the
potential false positive to determine for yourself if any structure members appear
sane or not. One way you could do that is by opening the memory dump in a hex
viewer and going to the physical offset to view the raw bytes. However, a better way
is to use volshell and overlay the structure question to the alleged physical offset.
This allows you to see the fields interpreted as their intended type (DWORD, string,
short, etc.)
bioskbd
To read keystrokes from the BIOS area of memory, use the bioskbd command. This
can reveal passwords typed into HP, Intel, and Lenovo BIOS and SafeBoot, TrueCrypt,
and BitLocker software. Depending on the tool used to acquire memory, not all
memory samples will contain the necessary BIOS area. For more information, see
Andreas Schuster's Reading Passwords From the Keyboard Buffer, David
Sharpe's Duplicating Volatility Bioskbd Command Function on Live Windows
Systems, and Jonathan Brossard's Bypassing pre-boot authentication passwords by
instrumenting the BIOS keyboard buffer.
patcher
The patcher plugin accepts a single argument of '-x' followed by an XML file. The
XML file then specifies any required patches as in the following example:
<patchfile>
<patchinfo method="pagescan" name="Some Descriptive Name">
<constraints>
<match offset="0x123">554433221100</match>
</constraints>
<patches>
<setbytes offset="0x234">001122334455</setbytes>
</patches>
</patchinfo>
<patchinfo>
...
</patchinfo>
</patchfile>
The XML root element is always patchfile, and contains any number
of patchinfo elements. When the patchfile is run, it will scan over the memory once
for each patchinfo, attempting to scan using the method specified in
the method attribute. Currently the only support method is pagescan and this must be
explicitly declared in each patchinfo element.
Each pagescan type patchinfo element contains a single constraints element and a
single patches element. The scan then proceeds over each page in memory, verifying
that all constraints are met, and if so, the instructions specified in
the patches element are carried out.
The constraints element contains any number of match elements which take a
specific offset attribute (specifying where within the page the match should occur)
and then contain a hexadecimal string for the bytes that are supposed to match.
The patches element contains any number of setbytes elements which take a specific
offset attribute (specifying where with the page the patch should modify data) and
then contains a hexidecimal string for the bytes that should be written into the page.
Note: When running the patcher plugin, there will be no modification made to
memory unless the write option (-w) has been specified on the command line.
pagecheck
The pagecheck plugin uses a kernel DTB (from the System/Idle process) and
determines which pages should be memory resident (using the
AddressSpace.get_available_pages method). For each page, it attempts to access the
page data and reports details, such as the PDE and PTE addresses if the attempt fails.
This is a diagnostic plugin, usually helpful in troubleshooting "holes" in an address
space.
This plugin is not well-supported. It is in the contrib directory and currently only
works with non-PAE x86 address spaces.
timeliner
This timeliner plugin creates a timeline from various artifacts in memory from the
following sources (items in parenthesis are filters that may be used with the --
type flag in order to obtain only items of that artifact):
You can filter for any of the above options in order to have more focused output
using the --type flag:
$ python vol.py -f Win2k12x64-Snapshot3.vmsn --profile=Win2012R2x64
--kdbg=0xf800f17dd9b0 timeliner --type=_CMHIVE
Volatility Foundation Volatility Framework 2.4
1970-01-01 00:00:00 UTC+0000|[_CMHIVE LastWriteTime]| [no name]|
1970-01-01 00:00:00 UTC+0000|[_CMHIVE LastWriteTime]| \REGISTRY\MACHINE\SYSTEM|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE LastWriteTime]|
\SystemRoot\System32\Config\SOFTWARE|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE LastWriteTime]|
\SystemRoot\System32\Config\DEFAULT|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE LastWriteTime]| \REGISTRY\MACHINE\SAM|
2014-06-20 06:31:05 UTC+0000|[_CMHIVE
LastWriteTime]| \??\C:\Users\Administrator\AppData\Local\Microsoft\Windows\UsrClas
s.dat|
2013-09-15 03:33:22 UTC+0000|[_CMHIVE LastWriteTime]|
\SystemRoot\System32\Config\BBI|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE
LastWriteTime]| \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE LastWriteTime]| \REGISTRY\MACHINE\SECURITY|
2014-06-20 06:31:05 UTC+0000|[_CMHIVE
LastWriteTime]| \??\C:\Users\Administrator\ntuser.dat|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE
LastWriteTime]| \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT|
2014-06-20 06:31:29 UTC+0000|[_CMHIVE LastWriteTime]|
\Device\HarddiskVolume1\Boot\BCD|
1970-01-01 00:00:00 UTC+0000|[_CMHIVE LastWriteTime]| \REGISTRY\MACHINE\HARDWARE|
There are three options for output: default text output, bodyfile format and an Excel
2007 file. For more details see Timeliner Release Documentation (pdf) and the OMFW
2011 presentation Time is on My Side. You can also include a machine identifier in
the header with the --machine flag (this is useful when combining timelines from
multiple machines). The following shows the default text output:
$ python vol.py -f XPSP3x86.vmem timeliner
Volatility Foundation Volatility Framework 2.4
2011-10-13 04:29:21 UTC+0000|[LIVE RESPONSE]| (System time)
2010-08-22 17:38:12 UTC+0000|[IEHISTORY]| explorer.exe->Visited:
Administrator@about:Home| PID: 1196/Cache type "URL " at 0x17f5100 End: 2010-08-22
17:38:12 UTC+0000
2010-10-31 13:48:47 UTC+0000|[IEHISTORY]| explorer.exe->Visited:
Administrator@file:///C:/Documents%20and
%20Settings/Administrator/Desktop/Sparkling_Swiss-4288x2848.jpg| PID: 1196/Cache
type "URL " at 0x17f5300 End: 2010-10-31 13:48:47 UTC+0000
2010-10-31 13:49:00 UTC+0000|[IEHISTORY]| explorer.exe->Visited:
Administrator@file:///C:/Documents%20and%20Settings/Administrator/My
%20Documents/My%20Pictures/Sparkling_Swiss-4288x2848.jpg| PID: 1196/Cache type
"URL " at 0x17f6000 End: 2010-10-31 13:49:00 UTC+0000
2011-10-13 04:20:23 UTC+0000|[PROCESS]| wuauclt.exe| PID: 332/PPID: 1032/POffset:
0x0226d580
2011-10-13 04:20:23 UTC+0000|[PROCESS LastTrimTime]| wuauclt.exe| PID: 332/PPID:
1032/POffset: 0x0226d580
2010-10-29 17:08:54 UTC+0000|[Handle (Key)]| MACHINE| wuauclt.exe PID: 332/PPID:
1032/POffset: 0x0226d580
2010-08-22 17:35:38 UTC+0000|[Handle (Key)]| MACHINE\SOFTWARE\MICROSOFT\WINDOWS
NT\CURRENTVERSION\DRIVERS32| wuauclt.exe PID: 332/PPID: 1032/POffset: 0x0226d580
2010-08-22 17:35:38 UTC+0000|[Handle (Key)]| MACHINE\SOFTWARE\MICROSOFT\WINDOWS
NT\CURRENTVERSION\DRIVERS32| wuauclt.exe PID: 332/PPID: 1032/POffset: 0x0226d580
2010-10-29 16:50:27 UTC+0000|[Handle (Key)]| MACHINE\SOFTWARE\CLASSES| wuauclt.exe
PID: 332/PPID: 1032/POffset: 0x0226d580
[snip]
If you don't want to do the extra step of importing, you can use the --
output=xlsx option with --output-file=[FILE](OUTPUT) to save directly an Excel 2007
file. Note: You must have OpenPyxl installed for this.
$ python vol.py -f XPSP3x86.vmem timeliner --output=xlsx --output-file=output.xlsx
Another option is to use the --output=body option for TSK 3.x bodyfile format. You
can use this output option when you want to combine output
from timeliner, mftparser and shellbags.
By default everything except the registry LastWrite timestamps are included in the
output of timeliner, this is because obtaining the registry timestamps is quite labor
intensive. In order to add them to the output, simply add the --type=Registry option
when you run Volatility. You can also limit your focus of registry timestamps by
listing a specific registry name (like --hive=SYSTEM) or user (--user=Jim) or both (--
hive=UsrClass.dat --user=jim). These options are case insensitive