computer forensics, computer forensics expert, mobile phone forensics, expert witness

Inside Out

Which forensic imager is the fastest?

We all face the problem of growing amounts of evidence on a regular basis. Improving raw acquisition speed is one way to limit the impact of this, and Evimetry has been consistently delivering the fastest acquisition speeds bar none since we launched two years ago.

Yet we aren’t the only solution claiming to be the “fastest” or have “unparalleled” speeds.

Led by a practitioner and forensic scientist, it is in Evimetry’s DNA to value substantiation. Our results are backed up by scientifically peer-reviewed publications and documented in our blog posts and workshops.

The following graph shows the acquisition rate of a 1TB Samsung 960 Pro NVMe drive. We used Evimetry to undertake linear acquisitions to 4x Samsung 512 GB 860 Pro SSD’s as striped images, using a 6-core Xeon-D CPU. The variable is drive allocation: we started with an empty (TRIM’ed) drive, then filled it with a Windows 10 OS install and a corpus of common corporate documents and video. These figures don’t account for verification time.

We can acquire an empty 1TB NVMe drive in 4 minutes 52s. That’s a rate of 200 GB/m, or 12 TB/h. No other product comes close to these speeds.

In the real world, suspect drives contain data rather than empty runs of 0x00, and Evimetry’s acquisition speeds depend on how much actual data is stored on the suspect drive. For a drive that is 40% utilized it takes us 7m48s (still faster than anyone else’s claim) and at 95% utilized it takes us 12m57s.

In absence of substantiation from other quarters we remain confident that we offer the fastest acquisition solution available today. We encourage you to do your own validation of both our results, and the claims of other tools.

How to analyse AFF4 linux memory images

In my last post I described Evimetry's support remote memory acquisition. In this post I'll give a quick walkthough on setting up Volatility for analysis of those images.

I prefer to make a python virtualenv specifically for working with volatility. In this example, I'm using MacOS with brew for my python (the python shipped with MacOS is broken in regard to pip's TLS authentication). Hence the -p argument.

mkdir volmem
cd volmem
virtualenv -p /usr/local/bin/python volmem
source volmem/bin/activate

Install all the dependencies with the following (the last two aren't strictly necessary, but prevent a load of complaints from Volatility).

pip install future
pip install rdflib
pip install pyblake2
pip install intervaltree
pip install expiringdict
pip install aff4-snappy
pip install pyyaml
pip install pycrypto
pip install distorm3

Pull in Volatility, the community plugins repository (where the AFF4 plugin resides), and the python AFF4 reader library. We set the python path so that the plugin can find the latter.

git clone https://github.com/volatilityfoundation/volatility
git clone https://github.com/volatilityfoundation/community
git clone https://github.com/aff4/pyaff4
export PYTHONPATH=$(pwd)/pyaff4:%PYTHONPATH%

Download the Linux profile you want to use with the memory image, and place it in Volatility's profile folder.

wget https://github.com/volatilityfoundation/profiles/raw/master/Linux/Ubuntu/x64/Ubuntu16041.zip
mv Ubuntu16041.zip volatility/volatility/plugins/overlays/linux/

cd volatility

Begin analysis. Note the usage of the --plugins line is crucial for picking up the AFF4 read plugin, as is the pythonpath environment variable we set earlier.

(volmem) neon:volatility bradley$ python vol.py --info
Volatility Foundation Volatility Framework 2.6

Profiles
--------
LinuxUbuntu16041x64 - A Profile for Linux Ubuntu16041 x64

<snip>

(volmem) neon:volatility bradley$ python vol.py --plugins=../community/AFF4 -f ~/Desktop/ImageDest/Ubuntu16041.RAM.aff4 --profile=LinuxUbuntu16041x64 linux_pslist
Volatility Foundation Volatility Framework 2.6
Offset Name Pid PPid Uid Gid DTB Start Time
------------------ -------------------- --------------- --------------- --------------- ------ ------------------ ----------
0xffff88003bd60000 systemd 1 0 0 0 0x000000003b61a000 2018-05-30 05:25:41 UTC+0000
0xffff88003bd60dc0 kthreadd 2 0 0 0 ------------------ 2018-05-30 05:25:41 UTC+0000
0xffff88003bd61b80 ksoftirqd/0 3 2 0 0 ------------------ 2018-05-30 05:25:41 UTC+0000
0xffff88003bd63700 kworker/0:0H 5 2 0 0 ------------------ 2018-05-30 05:25:41 UTC+0000

<snip>

This works equally well for newer kernels with kernel address space layout randomisation (KASLR). To test this, I created a new volatility profile for kernel 4.10 on Ubuntu 16.04.4 per the instructions at https://github.com/volatilityfoundation/volatility/wiki/Linux . You can see below the output of the linux_bash plugin run against a VM that I first used to generate the profile and then use as the target of acqusition using the Evimetry live agent.

If you can't find a profile, and haven't done it before, I'd encourage you to give it a go.  It is extremely easy to create a new one (especially using VMWare, as it breezes through the install of the the target Linux OS). All up it took me about 5 minutes to install Ubuntu 16.04.4 and create a profile for it. Don't forget to go the extra step contributing back to the community with the new profile (as I did here).

neon:volatility bradley$ python vol.py --plugins=../community/AFF4 -f ~/Desktop/ImageDest/Ubuntu16044_PhysicalMemory.aff4 --profile=LinuxUbuntu16044x64 linux_bash
Volatility Foundation Volatility Framework 2.6
Pid Name Command Time Command
-------- -------------------- ------------------------------ -------
841 bash 2018-05-31 16:08:23 UTC+0000 uname -a
841 bash 2018-05-31 16:08:23 UTC+0000 apt-get update
841 bash 2018-05-31 16:08:23 UTC+0000 apt-cache search linux-kernel
841 bash 2018-05-31 16:08:23 UTC+0000 apt-get install openssh-server
841 bash 2018-05-31 16:08:23 UTC+0000 exit
841 bash 2018-05-31 16:08:23 UTC+0000 apt-cache search linux-image
841 bash 2018-05-31 16:08:23 UTC+0000 apt-cache search kernel
841 bash 2018-05-31 16:08:23 UTC+0000 sudo bash
841 bash 2018-05-31 16:08:23 UTC+0000 uname
841 bash 2018-05-31 16:08:23 UTC+0000 cat /proc/version
841 bash 2018-05-31 16:08:23 UTC+0000 ifconfig
841 bash 2018-05-31 16:08:23 UTC+0000 apt-get install linux-image-4.10.0-14-generic
841 bash 2018-05-31 16:08:23 UTC+0000 sudo bash
841 bash 2018-05-31 16:08:23 UTC+0000 exit
841 bash 2018-05-31 16:08:23 UTC+0000 exit
841 bash 2018-05-31 16:08:23 UTC+0000 reboot
841 bash 2018-05-31 16:08:23 UTC+0000 apt-get install openssh-server
7459 bash 2018-05-31 16:21:46 UTC+0000 uname -a
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get update
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-cache search linux-kernel
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install linux-headers-4.10.0-14-generic
7459 bash 2018-05-31 16:21:46 UTC+0000 zip Ubuntu16044.zip module.dwarf /boot/System.map-4.10.0-14-generic
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install openssh-server
7459 bash 2018-05-31 16:21:46 UTC+0000 exit
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-cache search linux-image
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install dwarfdump
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-cache search kernel
7459 bash 2018-05-31 16:21:46 UTC+0000 sudo bash
7459 bash 2018-05-31 16:21:46 UTC+0000 make -C /lib/modules/4.10.0-14-generic/build CONFIG_DEBUG_INFO=y M=$PWD modules
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install build-essential
7459 bash 2018-05-31 16:21:46 UTC+0000 ls
7459 bash 2018-05-31 16:21:46 UTC+0000 uname
7459 bash 2018-05-31 16:21:46 UTC+0000 cat /proc/version
7459 bash 2018-05-31 16:21:46 UTC+0000 ifconfig
7459 bash 2018-05-31 16:21:46 UTC+0000 zip Ubuntu16044.zip module.dwarf /boot/System.map-4.10.0-14-generic
7459 bash 2018-05-31 16:21:46 UTC+0000 exit
7459 bash 2018-05-31 16:21:46 UTC+0000 cat /proc/version
7459 bash 2018-05-31 16:21:46 UTC+0000 ls
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install linux-image-4.10.0-14-generic
7459 bash 2018-05-31 16:21:46 UTC+0000 sudo bash
7459 bash 2018-05-31 16:21:46 UTC+0000 exit
7459 bash 2018-05-31 16:21:46 UTC+0000 sudo bash
7459 bash 2018-05-31 16:21:46 UTC+0000 exit
7459 bash 2018-05-31 16:21:46 UTC+0000 exit
7459 bash 2018-05-31 16:21:46 UTC+0000 dwarfdump -di ./module.o > module.dwarf
7459 bash 2018-05-31 16:21:46 UTC+0000 reboot
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install zip
7459 bash 2018-05-31 16:21:46 UTC+0000 apt-get install openssh-server
7459 bash 2018-05-31 16:21:49 UTC+0000 sudo bash
7472 bash 2018-05-31 16:21:50 UTC+0000 exit
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install openssh-server
7472 bash 2018-05-31 16:21:50 UTC+0000 sudo bash
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-cache search linux-image
7472 bash 2018-05-31 16:21:50 UTC+0000 exit
7472 bash 2018-05-31 16:21:50 UTC+0000 zip Ubuntu16044.zip module.dwarf /boot/System.map-4.10.0-14-generic
7472 bash 2018-05-31 16:21:50 UTC+0000 dwarfdump -di ./module.o > module.dwarf
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install zip
7472 bash 2018-05-31 16:21:50 UTC+0000 ifconfig
7472 bash 2018-05-31 16:21:50 UTC+0000 reboot
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install linux-headers-4.10.0-14-generic
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-cache search kernel
7472 bash 2018-05-31 16:21:50 UTC+0000 cat /proc/version
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install dwarfdump
7472 bash 2018-05-31 16:21:50 UTC+0000 zip Ubuntu16044.zip module.dwarf /boot/System.map-4.10.0-14-generic
7472 bash 2018-05-31 16:21:50 UTC+0000 make -C /lib/modules/4.10.0-14-generic/build CONFIG_DEBUG_INFO=y M=$PWD modules
7472 bash 2018-05-31 16:21:50 UTC+0000 sudo bash
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install openssh-server
7472 bash 2018-05-31 16:21:50 UTC+0000 ls
7472 bash 2018-05-31 16:21:50 UTC+0000 exit
7472 bash 2018-05-31 16:21:50 UTC+0000 ls
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install linux-image-4.10.0-14-generic
7472 bash 2018-05-31 16:21:50 UTC+0000 uname
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get update
7472 bash 2018-05-31 16:21:50 UTC+0000 uname -a
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-cache search linux-kernel
7472 bash 2018-05-31 16:21:50 UTC+0000 apt-get install build-essential
7472 bash 2018-05-31 16:21:50 UTC+0000 exit
7472 bash 2018-05-31 16:21:50 UTC+0000 sudo bash
7472 bash 2018-05-31 16:21:50 UTC+0000 exit
7472 bash 2018-05-31 16:21:50 UTC+0000 cat /proc/version
7472 bash 2018-05-31 16:21:51 UTC+0000 ls
7472 bash 2018-05-31 16:22:04 UTC+0000 ./evimetry.agent 192.168.189.1

How to acquire Linux memory images using without a driver

For a long time now, operating systems such as Windows and MacOS have prevented user space applications from accessing the raw physical memory of the machine. Physical acquisition and virtualisation approaches aside, this has led the field to require the use of kernel drivers to export physical ram for acquisition. In the linux realm, Joe Sylve's LiME is the go-to for many.

It appears not widely known that on Linux x64, acquisition of physical memory is possible without using a driver such as LiME. The prerequisite here is that /proc/kcore is enabled, which fortunately is widely the case: Ubuntu ships with it enabled by default, as does Redhat. On x64 the full physical address space is mapped into the kernel address space, and /proc/kcore exports this as a part of its virtual ELF file view.

Fun fact: /proc/kcore is big: 128 TB.

bradley@ubuntu:~$ ls -lh /proc/kcore
-r-------- 1 root root 128T Jun 8 18:44 /proc/kcore

You don't want to acquire /proc/kcore - just the relevant part.

Acquisition via this technique is something that Rekall pioneered, as far as I know (please correct me if you know better). Evimetry supports the technique in our live agent for remote acquisition. The following serves as a short howto on acquisition using currently available tools.

How to acquire: Evimetry

Copy the Evimetry linux liveagent (x64) onto the suspect Linux host, along with its security certificates. Run the agent with the IP address of a Controller or a Dead Boot or Cloud agent as the destination:

root@ubuntu:~# ./evimetry.agent 192.168.189.1
Evimetry Lightweight Agent v3.0.8, a lightweight forensic acquisition agent.
Application IP Address: 192.168.189.207
Application IP Address: fe80::20c:29ff:fed7:3540
Application MAC Address: 00:0c:29:d7:35:40
Memory Size: 971.6MiB
Memory Allocation Alignment Size: 4096
Runnable IO threads: 1
Starting device enumeration
Exported devices:
/dev/sda [20.0GiB] : VMware_Virtual_S
/dev/sda1 (ext4) [19.0GiB] /
/dev/sda2 (unknown) [975.0MiB]
/dev/sda5 (swap) [975.0MiB]
/dev/sr0 [1024.0MiB] : VMware_Virtual_SATA_CDRW_Drive
No medium found
/dev/sr1 [1024.0MiB] : VMware_Virtual_SATA_CDRW_Drive
No medium found
/dev/fd0 [4.0KiB] : Unknown Model
No such device or address
Insufficient privileges to access device!
Checking Memory Map setup.
Memory Description: [971.6MiB / 4.0GiB]
Checking Certificate setup.
Secure Communications Enabled
Starting Fabric Manager
Attempting Fabric Connection

Using the attached Evimetry Controler, acquisition is a simple GUI operation.

Acquisition using Evimetry Controller & Live Agent

This works fine for both old pre-KASLR kernels as well as newer KASLR kernels (the above was for a Ubuntu 14.04.4 x64 VM. More information is available from the following walkthrough.

How to acquire: linpmem

Using the most recent released version of linpmem (2.1post4) from the releases page,  I was able to acquire an image of a Ubuntu 14.04.1 VM with the following command.

root@ubuntu:~# ./linpmem-2.1.post4 --format map -c snappy -o image.aff4
Setting compression snappy
Imaging memory
Creating output AFF4 ZipFile.
Reading 0x8000 0MiB / 1023MiB 0MiB/s
Reading 0x3940000 57MiB / 1023MiB 227MiB/s
Reading 0x6068000 96MiB / 1023MiB 156MiB/s

<snip>

Reading 0x351d0000 849MiB / 1023MiB 247MiB/s
Reading 0x393f0000 915MiB / 1023MiB 264MiB/s
Reading 0x3df38000 991MiB / 1023MiB 300MiB/s
Adding /boot/System.map-4.4.0-31-generic as file:///boot/System.map-4.4.0-31-generic
Adding /boot/abi-4.4.0-31-generic as file:///boot/abi-4.4.0-31-generic
Adding /boot/config-4.4.0-31-generic as file:///boot/config-4.4.0-31-generic
Adding /boot/grub/ as file:///boot/grub/
E0608 12:17:35.730147 4117 aff4_directory.cc:105] Unable to find storage for AFF4Directory file:///boot/grub/
E0608 12:17:35.730480 4117 aff4_imager_utils.cc:259] Unable to find file:///boot/grub/
Adding /boot/initrd.img-4.4.0-31-generic as file:///boot/initrd.img-4.4.0-31-generic
Reading 0x8000 0MiB / 30MiB 0MiB/s
Adding /boot/vmlinuz-4.4.0-31-generic as file:///boot/vmlinuz-4.4.0-31-generic

CAVEAT: The most recent release of linpmem (linpmem-2.1.post4) failed for the Ubuntu 14.04.4 VM I tested. See github issue.

How to analyse

My next post will describe how to analyse the images created above.

Announcing Evimetry Lab: changing the game for in-lab forensics

When it comes to preserving evidence, DF labs generally fall into two camps. Those that  acquire in the field, and those that collect evidence in the field,  only later doing acquisition in-lab. Over the last two years, Evimetry's product offerings have been primarily aimed at the former. Practitioners have benefited from the fastest in-field acquisitions, while at the same time enabling meaningful analysis work to occur while waiting for acquisition complete.

Evimetry Lab, announced last week at the EnFuse conference, changes the game for the latter group. This groundbreaking approach enables analysis and time-consuming processing tasks (such as indexing) to begin immediately after acquisition begins. The traditional delay between waiting for acquisition to complete prior to beginning processing is removed, leading to processing tasks completing hours earlier, and answers sooner.

Evimetry Lab Delivers answers hours sooner.

How much sooner? The comparison above shows a time-consuming indexing run using NUIX completing hours earlier when using Evimetry Lab as opposed to traditional forensic imaging workflows. There is also some live analysis using EnCase thrown in good measure.

Want more info? Check out the Evimetry Lab in more detail, or send us an email.

Simple Deadboot provisioning and acquisition with Evimetry

We have just shipped two releases of Evimetry: v3.0.7 (in our stable stream) & v3.1.5 (in our pre-release stream). Recent releases bring native Deadboot media creation, and introduce an improved Deadboot Imager UI.

Native Deadboot Media Creation.

We can now create Evimetry Deadboot USB's directly from the Controller, and for larger drives, use the additional space for evidence storage. With a single hard drive serving both as an Evimetry Deadboot and Evidence Repository, scarce USB ports are freed up on target devices, workflow is simplified, and the number of devices to manage limited.

Creation of a Deadboot USB flash drive in the Controller.

Small USB flash drives are setup solely as a Deadboot, just like our former workflow.

Read more about this feature here.

Improved Deadboot Imager UI.

For a while now the Deadboot agent has included a simple ASCII console-based Imager application. This is useful for acquiring single computers, when it is either inconvenient or unfeasable to use the Controller and a network.

While we love the retro feel and simplicity of an ASCII/curses interface, the world is no longer friendly to text-mode UI's, with high-DPI monitors and text-mode free UEFI implementations meaning that text-mode no longer works everywhere. A graphical window based UI is now necessary.

Acquisition almost completed using Evimetry Imager

In the v3.1.3 pre-release we launched a graphical Imager application, and in today's prerelease (v3.1.5) the layout of the Imager UI has been refined.

Pulling it all together.

The following video demonstrates the workflow of preparing a Deadboot USB and then subsequent acquisition of a 500G NVMe drive in under 6 minutes.

More information.

Full release notes are available via the releases page. The software may be downloaded from the portal.