Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/halpomeranz/lmg

Script for automating Linux memory capture and analysis
https://github.com/halpomeranz/lmg

Last synced: 2 months ago
JSON representation

Script for automating Linux memory capture and analysis

Lists

README

        

Linux Memory Grabber
A script for dumping Linux memory and creating Volatility(TM) profiles.
Hal Pomeranz ([email protected]), 2020-02-01

THANKS!
=======

"If I have seen further it is by standing on the shoulders of giants."
~ Issac Newton

There are a lot of people who deserve thanks for making this simple
little tool possible:

-- The good folks at Microsoft for making AVML available

-- Joe Sylve for his work on LiME

-- The entire Volatility(TM) development team for their ongoing work.
I'd like to particularly recognize Andrew Case who answered a number
of pesky questions from me during development of my tool.

-- David Anderson for his ongoing support of libdwarf and dwarfdump

-- Matt Suiche from MoonSols. When I was putting my tool together,
my design goal was "make it as easy to use as DumpIt" (if you need
to capture Windows memory, I know of no easier to use tool).
So thanks for the inspiration, Matt!

-- People who have provided ideas and code to make the tool better:

Julien -- Alternate output/build directories and case ID labels,
abort if not running as root
Jonathon Poling -- similar ideas to Julien's
Jeff Bryner -- Creating volatilityrc files for each capture

The community is better for all of these efforts. I have chosen to make
my tool available under the Creative Commons "Attribution" License (CC BY),
in order to make it as widely available as possible.

ABOUT THE TOOL
==============

To analyze Linux memory, you first need to be able to capture Linux
memory. AVML works great, but if your system doesn't have /proc/kcore
or /dev/crash then you will need Joe Sylve's Linux Memory Extractor (LiME).
But you need to have a LiME module compiled for the kernel of the
system where you want to grab RAM.

Volatility(TM) is great at analyzing Linux memory images. But it needs
a profile that matches the system where the memory was captured.
Building a profile means compiling a C program on the appropriate system
and using dwarfdump to get the addresses of important kernel data structures.
You also need a copy of the System.map file from the /boot directory.

Now if you happen to have a duplicate of your target system, you can
build the Volatility(TM) profile on the clone and if necessary build
LiME to capture and analyze memory from your target. But there are
many situations where a duplicate of your target system is not
available. So you may have to build your Volatility(TM) profile and
LiME on your target machine.

And this is not for the faint of heart. There are a number of steps,
and some fairly low-level Linux commands involved. My goal was to
create a package that could be installed (by an expert) on a thumb drive
and distributed to agents in the field. The user of the thumb drive
should be able to plug the thumb drive in, run a single command,
and successfully acquire a memory image of the target machine and
a working Volatility(TM) profile. The result is my lmg (Linux Memory
Grabber) script.

ON FORENSIC PURITY
==================

If you're a stickler for forensic purity, this is probably not the
tool for you. Let's discuss some of the ways in which my tool interacts
with the target system:

Removable Media -- The tool is designed to be run from a portable USB
device such as a thumb drive. You are going to be plugging a writable
device into your target system, where it could potentially be targeted
by malicious users or malware on the system. The act of plugging the
device into the system is going to change the state of the machine
(e.g., create log entries, mtab entries, etc). If the device is not
auto-mounted by the operating system, the user must manually mount the
device via a root shell.

Compilation -- Creating a Volatility(TM) profile involves compiling code
on the target machine. So does building LiME when AVML doesn't work.
So gcc will be executed, header files read, libraries linked, etc.
lmg tries to minimize impact on the file system of the target machine
by setting TMPDIR to a directory on the USB device lmg runs from.
This means that intermediate files created by the compiler will be
written to the thumb drive rather than the local file system of the
target machine.

Dependencies -- In order to compile kernel code on Linux, the target
machine needs a working development environment with gcc, make, etc
and all of the appropriate include files and shared libraries.
And in particular, the kernel header files need to be present on
the local machine. These dependencies may not exist on the target.
In this case, the user is faced with the choice of installing
the appropriate dependencies (if possible) or being unable to
build the Volatility(TM) profile for the system.

Malware -- lmg uses /bin/bash, gcc, zip, and a host of other programs from
the target machine. If the system has been compromised, the applications
lmg uses may not be trustworthy. A more complete solution would be
to create a secure execution environment for lmg on the portable USB
device, but was beyond the scope of this initial proof of concept.

Memory -- All of the commands being run will cause the memory of the
target system to change. The act of capturing RAM will always create
artifacts, but in this case there is extensive compilation, file system
access, etc in addition to running a RAM dumper.

All of that being said, lmg is a very convenient tool for allowing
less-skilled agents to capture useful memory analysis data from
target systems.

Note that if AVML fails, lmg will look for an already existing LiME module
on the USB device that matches the kernel version and processor
architecture of the target machine. If found, lmg will not bother to
recompile. Similarly, you may choose to not have lmg create the
Volatility(TM) profile for the target in order to minimize the impact
on the target system.

lmg uses relative path names when invoking programs like gcc and zip.
So if you wish to run these programs from alternate media, simply update
$PATH as appropriate before running lmg.

USING LMG
=========

First, prepare a thumb drive according to the instructions in the
INSTALL document provided with lmg.

When you wish to acquire RAM, plug the thumb drive into your target
system. On most Linux systems, new USB devices will get automatically
mounted under /media. Let's assume yours ends up under /media/LMG.

Now, as root, run "/media/LMG/lmg". This is interactive mode and
the user will be prompted for confirmation before lmg builds a LiME
module for the system and/or creates a Volatility(TM) profile.
If you don't want to be prompted, use "/media/LMG/lmg -y".

Everything else is automated. After the script runs, you will have
a new directory on the thumb drive named

".../capture/-YYYY-MM-DD_hh.mm.ss"

lmg supports a -c option for specifying a case ID directory name to be
used instead of the default "-YYYY-MM-DD_hh.mm.ss" directory.

Whatever directory name is used, the directory will contain:

-YYYY-MM-DD_hh.mm.ss-memory.lime -- the RAM capture
-YYYY-MM-DD_hh.mm.ss-profile.zip -- Volatility(TM) profile
-YYYY-MM-DD_hh.mm.ss-bash -- copy of target's /bin/bash
volatilityrc -- prototype Volatility config file

The volatilityrc file defines the appropriate locations for the captured
memory and plugin. See the USAGE EXAMPLE below for how to use this file.

The copy of /bin/bash is helpful for determining the address of the shell
history data structure in the memory of bash processes in the memory capture.
See https://github.com/volatilityfoundation/volatility/wiki/Linux-Command-Reference#linux_bash
for further details on how to use this executable (or reference the USAGE EXAMPLE
below).

Note that there may be times when you do not wish to write data to the media
that you are running lmg from-- for example if the lmg tools are on read-only
media like a DVD-ROM. lmg supports a -d option to specify a different output
directory. By default, all compilation will happen in the target directory,
but the user may specify an alternate compilation directory with -B.

USAGE EXAMPLE
=============

Here is an example of using the lmg tool, which includes using Volatility(TM)
directly off the thumb drive to analyze the captured image. On my test
machine, the thumb drive was at /dev/sdb and it was not auto-mounted by
my operating system. So I did everything manually.

1) Getting root and mounting the thumb drive
--------------------------------------------

[root@localhost ~]$ sudo -s
[sudo] password for lab:
[root@localhost lab]# mkdir -p /mnt/usb
[root@localhost lab]# mount /dev/sdb1 /mnt/usb

2) Running lmg
--------------

[root@localhost lab]# /mnt/usb/lmg -y
AVML is /mnt/usb/avml/avml-x86_64
Dumping memory in "lime" format to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55
This could take a while...Done!
Grabbing a copy of /bin/bash...Done!
Writing volatilityrc to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55...Done!
make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean
make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64'
make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64'
rm -f module.dwarf
make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build CONFIG_DEBUG_INFO=y M="/mnt/usb/volatility-master/tools/linux" modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64'
CC [M] /mnt/usb/volatility-master/tools/linux/module.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /mnt/usb/volatility-master/tools/linux/module.o
see include/linux/module.h for more information
CC /mnt/usb/volatility-master/tools/linux/module.mod.o
LD [M] /mnt/usb/volatility-master/tools/linux/module.ko
make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64'
dwarfdump -di module.ko > module.dwarf
make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean
make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64'
CLEAN /mnt/usb/volatility-master/tools/linux/.tmp_versions
CLEAN /mnt/usb/volatility-master/tools/linux/Module.symvers
make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64'
adding: module.dwarf (deflated 90%)
adding: boot/System.map-4.18.0-147.3.1.el8_1.x86_64 (deflated 79%)

3) Running linux_banner plugin to test capture, leveraging the prototype volatilityrc
-------------------------------------------------------------------------------------

[root@localhost lab]# cd /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# ls
localhost.localdomain-2020-02-01_08.16.55-bash
localhost.localdomain-2020-02-01_08.16.55-memory.lime
localhost.localdomain-2020-02-01_08.16.55-profile.zip
volatilityrc
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_banner
Volatility Foundation Volatility Framework 2.6.1
Linux version 4.18.0-147.3.1.el8_1.x86_64 ([email protected]) (gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)) #1 SMP Fri Jan 3 23:55:26 UTC 2020

4) Use the captured copy of /bin/bash to dump shell history with linux_bash
---------------------------------------------------------------------------

[root@localhost localhost.localdomain-2020-02-01_08.16.55]# gdb localhost.localdomain-2020-02-01_08.16.55-bash
GNU gdb (GDB) Red Hat Enterprise Linux 8.2-6.el8_0
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from localhost.localdomain-2020-02-01_08.16.55-bash...Missing separate debuginfo for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash
Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/b6/858d77c486b7b596f22956149bbc9f8058d98d.debug
Reading symbols from .gnu_debugdata for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash...(no debugging symbols found)...done.
(no debugging symbols found)...done.
(gdb) disass history_list
Dump of assembler code for function history_list:
0x00000000000ccea0 <+0>: endbr64
0x00000000000ccea4 <+4>: mov 0x24b09d(%rip),%rax # 0x317f48
0x00000000000cceab <+11>: retq
End of assembler dump.
(gdb) quit
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_bash -H 0x317f48
Volatility Foundation Volatility Framework 2.6.1
Pid Name Command Time Command
-------- -------------------- ------------------------------ -------
13822 bash 2020-01-30 20:25:39 UTC+0000 uname -a
13822 bash 2020-01-30 20:25:39 UTC+0000 ls
13822 bash 2020-01-30 20:25:39 UTC+0000 sudo -s
13822 bash 2020-01-30 20:25:39 UTC+0000 fg
[... more output not shown ...]