CREATING A VOLATILITY PROFILE
Volatility makes use of internal operating system structures. The structures can change from one version of an operating system to the next. Volatility ships with a set of profiles from common versions of Windows. The same is not true for Linux, however. Before rushing to judge, stop to think about how many different kernel versions and variants of Linux exist in the world.
The solution for Linux systems is to create your own profile by compiling a specific program; creating a dwarf file; getting a system map file; and zipping everything together. If this sounds complicated and cumbersome, it is. Never fear, however, as I will show you how to create the profile from your mounted subject image using a shell script. This script should be placed in the same directory as the Volatility module.c and Makefile, which can be found in the tools/linux directory inside of the volatility hierarchy. The script follows.
!/bin/bash
# create-profile.sh
# Simple script to create a makefile for a Volatility profile.
Intended to be used with an image file.
As developed for PentesterAcademy # by Dr. Phil Polstra (@ppolstra) usage() { echo “Script to create a Volatility profile from a mounted image file” echo “Usage: $0 ” exit 1
} if [ $# -lt 1 ] ; then usage fi oldir=$(pwd) cd ${1}/boot
ver=$(ls System.map* | sed “s/System.map-//” | tr “\n” “|” \
| sed -nr ‘s/([a-zA-Z0-9.-]+|)*([a-zA-Z0-9.-]+|)$/\2/p’ \
| sed “s/|/\n/”) cd “${oldir}” echo “Version: ${ver}” PWD=$(pwd) MAKE=$(which make) cat <<EOF > Makefile.${ver} obj-m += module.o -include version.mk all: dwarf dwarf: module.c
${MAKE} -C ${1}/lib/modules/${ver}/build \ CONFIG_DEBUG_INFO=y M=”${PWD}” modules dwarfdump -di module.ko > module.dwarf ${MAKE} -C ${1}/lib/modules/${ver}/build M=”${PWD}” clean clean:
${MAKE} -C ${1}/lib/modules/${ver}/build M=”${PWD}” clean rm -f module.dwarf
EOF
make the dwarf file make -f Makefile.${ver} # copy the System.map file cp ${1}/boot/System.map-${ver} ./. # now make the zip zip Linux${ver}.zip module.dwarf System.map-${ver}
Let’s walk through this script. It begins with the standard she-bang, usage, and command line parameter count check. The current directory is saved on the line oldir=$(pwd), before changing to the subject’s /boot directory. The next part of the script attempts to guess the correct kernel version based on the name of the System.map file. This is complicated by the fact that there may be more than one kernel installed.
For the purposes of this script, we will assume the subject is running the latest kernel version installed. This is another reason you should run uname -a on the subject system before shutting it down. What makes the line determining the kernel version so complicated is the possibility of having more than one System.map file. Let’s break down the ver=… line.
The first command is ls System.map* which causes all of the System.map files to be output one per line. The next command, sed “s/System.map-//”, substitutes “System.map-” for nothing which essentially strips off the prefix and leaves us a with a list of kernel versions, one per line. The third command, tr “\n” “|”, substitutes (translates) newline characters to vertical pipes which puts all versions on the same line. The fourth command contains a long regular expression and a substitution command.
If you examine the regular expression, it consists of two pieces. The first part, “([azA-Z0-9.-]+|)”, matches zero or more letters, periods, numbers, and dashes that preced a vertical pipe. When combined with the second part, which is identical except for the fact that the “” has become a “$”, which causes the second part to match the last item (version with vertical pipe appended), the first part effectively matches all but the last item. The substitution command “/\2/” causes the second match (latest version) to be substituted for the entire string. Finally, one last sed command is run to change the vertical pipe back to a newline.
Once the version has been determined, the script changes back to the original directory with the line that reads cd “${oldir}”. The version is echoed to the screen. Note that the environment variables have been enclosed in curly brackets as this tends to be safer than using bare variables, i.e. $oldir, as these are sometimes misinterpreted. The current working directory and full path to the make command are then saved in the PWD and MAKE environment variables, respectively.
The line cat <<EOF > Makefile.${ver} is slightly different from our previous use of cat <<EOF. Here we have directed the output of cat to a file instead of the terminal or another program. The lines that follow, through “EOF”, are used to create a makefile. For those not familiar with makefiles, they are used to more efficiently build software by only rebuilding what is necessary. The general format for a makefile is a line that reads <target>: [dependencies] followed by a tab indented list of commands to build the target. The indented lines must use tabs and not spaces in order for the make utility to properly interpret them.
Normally a makefile is used by simply typing make [target]. In order to use this form of make, a file named Makefile must be present in the current directory. The -f option for make allows specification of an alternate makefile. This is precisely what is done in this script. The last lines of the script run make to create a dwarf file; copies the System.map file from the subject system; and then creates a zip file that is used by Volatility as a profile. The output from this script is shown in Figure 8.1.
FIGURE 8.1
Using a shell script to create a Volatility profile.
Once the profile is built, copy it to the volatility/plugins/overlays/linux directory. For my laptop, the full path is /usr/local/lib/python2.7/dist-packages/volatility-2.4py2.7.egg/volatility/plugins/overlays/linux. As shown in Figure 8.2, any valid zip file in this directory becomes a valid Volatility Linux profile. The command vol.py –info runs Volatility and lists all available profiles and other information. If you pipe the results to grep, like so vol.py –info | grep Linux, it will give you a list of Linux profiles (plus a couple other things) as shown in the figure.
FIGURE 8.2
Volatility Linux profiles. The highlighted lines show profiles automatically loaded based on the zip files in this directory.