DAMM
Differential Analysis of Malware in Memory
Install / Use
/learn @504ensicsLabs/DAMMREADME
DAMM
An open source memory analysis tool built on top of Volatility. It is meant as a proving ground for interesting new techniques to be made available to the community. These techniques are an attempt to speed up the investigation process through data reduction and codifying some expert knowledge.
Table of Contents
Features <a name="features"/>
- ~30 Volatility plugins combined into ~20 DAMM plugins (e.g., pslist, psxview and other elements are combined into a 'processes' plugin)
- Can run multiple plugins in one invocation
- The option to store plugin results in SQLite databases for preservation or for "cached" analysis
- A filtering/type system that allows easily filtering on attributes like pids to see all information related to some process and exact or partial matching for strings, etc.
- The ability to show the differences between two databases of results for the same or similar machines and manipulate from the cmdline how the differencing operates
- The ability to warn on certain types of suspicious behavior
- Output for terminal, tsv or grepable
Usage <a name="usage"/>
NOTE: Most DAMM output looks better piped through 'less -S' (upper 'S') as in:
# python damm.py <some DAMM functionality> | less -S (for default output format)
python damm.py -h
usage: damm.py [-h] [-d DIR] [-p PLUGIN [PLUGIN ...]] [-f FILE] [-k KDBG]
[--db DB] [--profile PROFILE] [--debug] [--info] [--tsv]
[--grepable] [--filter FILTER] [--filtertype FILTERTYPE]
[--diff BASELINE] [-u FIELD [FIELD ...]] [--warnings] [-q]
DAMM v1.0 Beta
optional arguments:
-h, --help show this help message and exit
-d DIR Path to additional plugin directory
-p PLUGIN [PLUGIN ...]
Plugin(s) to run. For a list of options use --info
-f FILE Memory image file to run plugin on
-k KDBG KDBG address for the images (in hex)
--db DB SQLite db file, for efficient input/output
--profile PROFILE Volatility profile for the images (e.g. WinXPSP2x86)
--debug Print debugging statements
--info Print available volatility profiles, plugins
--tsv Print screen formatted output.
--grepable Print in grepable text format
--filter FILTER Filter results on name:value pair, e.g., pid:42
--filtertype FILTERTYPE
Filter match type; either "exact" or "partial",
defaults to partial
--diff BASELINE Diff the imageFile|db with this db file as a baseline
-u FIELD [FIELD ...] Use the specified fields to determine uniqueness of
memobjs when diffing
--warnings Look for suspicious objects.
-q Query the supplied db (via --db).
Supported plugins <a name="plugins"/>
See #python damm.py --info
apihooks callbacks connections devicetree dlls evtlogs handles idt injections messagehooks mftentries modules mutants privileges processes services sids timers
Example <a name="example"/>
Supply a profile as in Volatility, a memory image and a list of plugins to run (or 'all') to get terminal output:
python damm.py --profile WinXPSP2x86 -f memory.dmp -p processes | less -S
(or python damm.py --profile WinXPSP2x86 -f memory.dmp -p processes dlls modules)
(or python damm.py --profile WinXPSP2x86 -f memory.dmp -p all)
processes
offset name pid ppid prio image_path_name create_time exit_time threads session_id handles is_wow64 pslist psscan thrdproc pspcid csrss session deskthrd command_line
0x25c8830 System 4 0 8 59 403 False True True True True False False False
0x225ada0 alg.exe 188 668 8 C:\WINDOWS\System32\alg.exe 2010-10-29 17:09:09 UTC+0000 6 0 107 False True True True True True True True C:\WINDOWS\System32\alg.exe
0x2114938 ipconfig.exe 304 968 8 2011-06-03 04:31:35 UTC+0000 2011-06-03 04:31:36 UTC+0000 0 0 False True True False True False False False
0x2086978 TSVNCache.exe 324 1196 8 C:\Program Files\TortoiseSVN\bin\TSVNCache.exe 2010-10-29 17:11:49 UTC+0000 7 0 54 False True True True True True True True "C:\Program Files\TortoiseSVN\bin\TSVNCache.exe"
0x22df020 smss.exe 376 4 11 \SystemRoot\System32\smss.exe 2010-10-29 17:08:53 UTC+0000 3 19 False True True True True False False False \SystemRoot\System32\smss.exe
...
To make these results persist in a SQLite db, just supply a filename for the db:
python damm.py --profile WinXPSP2x86 -f memory.dmp -p processes --db my_results.db
This will print results to the terminal as well as store them in 'my_results.db'
To see the results again:
python damm.py -p processes --db my_results.db
(Note that you no longer need the memory image or to specify a profile, and the listing will come out pretty close to instantly regardless of how long the original processing took.)
If you later wish to see processes and other plugins:
python damm.py --profile WinXPSP2x86 -p processes dlls modules --db my_results.db
Will:
- consult the db for the 'processes' output
- run the 'dlls' and 'modules' plugins
- display the results
- store the new results in the db
Once you have stored some data in a db, you can query it with the -q switch
python damm.py -q --db my_results.db
profile: WinXPSP2x86
memimg: WinXPSP2x86/stuxnet.vmem
COMPUTERNAME: JAN-DF663B3DBF1
plugins: processes dlls modules
Plugins have attributes that can have types for filtering, e.g., for processes: (use --info to see for all plugin attributes)
offset
name : string
pid : pid
ppid : pid
image_path_name : string
command_line : string
create_time
exit_time
threads
session_id
handles
is_wow64
pslist
psscan
thrdproc
pspcid
csrss
session
deskthrd
These attributes and types can be leveraged by the differencing and filtering functions of DAMM
Differencing <a name="differencing"/>
To use the differencing engine, create 2 databases from 2 distinct memory images, such as one from before and one from after a piece of malware is executed
python damm.py --profile WinXPSP2x86-f before.dmp -p processes --db before.db
python damm.py --profile WinXPSP2x86 -f after.dmp -p processes --db after.db
Then use the --diff option for the baseline db (here, the db from the uninfected memory image).
python damm.py -p processes --db after.db --diff before.db
processes
Status offset name pid ppid prio image_path_name create_time exit_time threads session_id handles is_wow64 pslist psscan thrdproc pspcid csrss session deskthrd command_line
New 0x17d22e0 pythonw.exe 1256 1940 8 2013-10-31 23:23:14 UTC+0000 2013-10-31 23:23:19 UTC+0000 0 -268370093 False False True False False False False False
Changed 0x18b4d38 svchost.exe 1080 692 8 2013-10-31 17:21:26 UTC+0000 66->71 False False True False False False False False
Changed 0x1915198 winlogon.exe 648 376 13 2013-10-31 17:21:25 UTC+0000 24->26 False False True False False False False False
Changed 0x1900120 services.exe 692 648 9 2013-10-31 17:21:25 UTC+0000 16->18 False False True False False False False False
Changed 0x18b0360 svchost.exe 1124 692 8 2013-10-31 17:21:26 UTC+0000 5->6 False False True False False False False False
Changed 0x1875490 explorer.exe 1636 1596 8 2013-10-31 17:21:27 UTC+0000 13->14 False False True False False False False False
...
The results look similar to the 'processes' plugin output above, but there are some differences:
- Only results that are new in 'after.db' or that are in both dbs but have some attributes that changed from 'before.db' are displayed (the output here is snipped).
- Results that are only in the 'after.db' have 'New' in the first ('Status') column
- Results in that have changed between the dbs have a 'Status' of 'Changed', and, importantly, denote the changes DAMM detected with '->': in the last line of output above the number of threads has changed.
Unique ID Manipulation <a name="unique-id"/>
In order to determine which processes exist in both memory captures above, behind the scenes certain attributes of processes are used to make a unique identifier for each. For example, by default
