acquire

acquire is a tool to quickly gather forensic artefacts from disk images or a live system into a lightweight container. This makes acquire an excellent tool to, among others, speed up the process of digital forensic triage. acquire uses dissect to gather forensic artefacts from the raw disk, if possible.

The most basic usage of acquire is as follows:

$ sudo acquire

The tool requires administrative access to read raw disk data. However, there are some options available to use the local operating systems’s filesystem as a fallback option. (e.g --fallback or --force-fallback)

Filesystem acquisition

acquire gathers artefacts based on modules. These modules contain paths or globs that acquire attempts to gather from a filesystem. acquire can execute multiple modules at once. Instead of specifying modules manually, it’s possible to use a predefined collection known as a profile. These profiles (used with --profile) are full, default, minimal and none. Depending on the detected operating system, acquire collects different artefacts.

The following list shows the modules belonging to each profile.

full profile:
  windows: NTFS, EventLogs, Registry, Tasks, PowerShell,
           Prefetch, Appcompat, PCA, Misc, ETL, Recents,
           RecycleBin, Drivers, Syscache, WBEM, AV, BITS,
           DHCP, DNS, ActiveDirectory, RemoteAccess,
           ActivitiesCache, History, NTDS, QuarantinedFiles,
           WindowsNotifications, SSH, IIS
  linux  : Etc, Boot, Home, SSH, Var, History, WebHosting
  bsd    : Etc, Boot, Home, SSH, Var, BSD
  esxi   : Bootbanks, ESXi, SSH, VMFS
  osx    : Etc, Home, Var, OSX, OSXApplicationsInfo, History,
           SSH

default profile:
  windows: NTFS, EventLogs, Registry, Tasks, PowerShell,
           Prefetch, Appcompat, PCA, Misc, ETL, Recents,
           RecycleBin, Drivers, Syscache, WBEM, AV, BITS,
           DHCP, DNS, ActiveDirectory, RemoteAccess,
           ActivitiesCache
  linux  : Etc, Boot, Home, SSH, Var
  bsd    : Etc, Boot, Home, SSH, Var, BSD
  esxi   : Bootbanks, ESXi, SSH, VMFS
  osx    : Etc, Home, Var, OSX, OSXApplicationsInfo

minimal profile:
  windows: NTFS, EventLogs, Registry, Tasks, PowerShell,
           Prefetch, Appcompat, PCA, Misc
  linux  : Etc, Boot, Home, SSH, Var
  bsd    : Etc, Boot, Home, SSH, Var, BSD
  esxi   : Bootbanks, ESXi, SSH
  osx    : Etc, Home, Var, OSX, OSXApplicationsInfo

Profile none is a special case where no module gets collected. Profiles can be used in combination with --dir, --file or --glob to collect specific user-defined paths from a target. These arguments do the following:

  • --dir: Collects a directory recursively.

  • --file: Collects one specific file.

  • --glob: Collects any file or directory that matches the specific glob pattern. (e.g /path*/test would collect for example /path1/test and /path_to_other_test_file/test)

You can specify these arguments multiple times for every file, directory or glob you want to collect.

Volatile acquisition

Use --volatile-profile to obtain artefacts that are not persistent on disk but are located in memory. Volatile Windows artefacts are stored under the $metadata$ folder in the resulting archive. Windows volatile artefacts are gathered through the use of internal Windows commands and Python’s ctypes interface. For Linux systems, /proc and /sys are gathered and stored under /proc/1/... or /sys/fs/... respectively in the resulting archive.

Volatile Profiles

Like regular profiles, the volatile profiles allow you to run predefined groups of volatile modules. These profiles, are default, extensive and none, where none is the default. As with --profile, what gets collected depends on the detected operating system.

The following list shows the modules that belong to each volatile profile.

default profile:
  windows: Netstat, WinProcesses, WinProcEnv, WinArpCache,
           WinRDPSessions, WinDnsClientCache

extensive profile:
  windows: Netstat, WinProcesses, WinProcEnv, WinArpCache,
           WinRDPSessions, WinDnsClientCache
  linux  : Proc, Sys
  bsd    : Proc, Sys
  esxi   : Proc, Sys

Both --volatile-profile and --profile can be used simultaneously and configured separately from each other.

Deployment

Since acquire leverages Dissect to do its data collection, it can be used in different scenarios and ways.

One way is to use acquire on targets that are supported by dissect.target, for example VMDK or E01 disk images. This gives you a smaller forensic container for analysis. This can be useful in scenarios where you may have several thousand virtual machine backups you want to analyze, but don’t have the time (or storage) to fully copy them all. You can perform your initial analysis and triage on the acquire container, and collect a copy of the full VM at a later stage if you require.

Besides various disk images, dissect.target also supports a local target, which is the host machine it’s currently running on. This is the default target for acquire. For example, on Windows this means that \\.\PhysicalDrive0 and friends are opened and the filesystem on it is parsed using Dissect. On Linux systems this will be /dev/sda, on ESXi /vmfs/devices/disks/vml.*, etc. By parsing straight from the raw disk devices, we ensure we bypass any file locks and filesystem drivers.

So how do you go about running acquire on a separate system? It’s hardly practical to install Python and Dissect on a compromised machine. At Fox-IT we have an internal solution for this, but fortunately there are also public options, such as PyOxidizer and PyInstaller. Unfortunately, however, neither support cross platform executable creation.

PyOxidizer

PyOxidizer is a relatively new Python application packer that integrates heavily with Rust. It has a lot of exciting options and functionality, at the cost of a fairly large executable size and complex configuration options.

A major benefit of PyOxidizer is that, by default, it runs all of its Python code completely from memory, no file extraction necessary. This can result in the preservation of important filesystem artefacts.

Since dissect.target dynamically locates its plugins, we have to pre-generate a list of all plugins for it to work when running in a self-contained executable.

Example usage of PyOxidizer with acquire:

$ pip install pyoxidizer
$ pyoxidizer init-config-file my-acquire-bin
$ cd my-acquire-bin
## Edit pyoxidizer.bzl with your favourite text editor and see below for the minimal required changes
$ target-build-pluginlist > /path/to/src/dissect.target/dissect/target/plugins/_pluginlist.py
$ pyoxidizer build

The minimal required changes to be made to the make_exe() function in the pyoxidizer.bzl file are as follows:

policy.resources_location_fallback = "filesystem-relative:prefix"
python_config.run_module = "acquire.acquire"
exe.add_python_resources(exe.pip_install(["/path/to/src/dissect.target", "acquire"]))

This is just a very basic example. There are a lot more settings to tweak and optimizations to be made, but those are left as an exercise to the reader.

PyInstaller

PyInstaller has been around for a long time and can be considered the de facto utility for packaging Python into executables, for both legitimate and malicious purposes. It has a lot less options to play with than PyOxidizer, but it’s considerably easier to use and the resulting binaries are a lot smaller.

A major downside of PyInstaller is that you have to either ship multiple files or use the --onefile option, which extracts files to a temporary directory on the filesystem. This can destroy forensic filesystem artefacts, so keep that in mind when using PyInstaller.

Similar to PyOxidizer, we also have to pre-generate a list of plugins for PyInstaller.

Example usage of PyInstaller with acquire:

$ pip install pyinstaller
$ target-build-pluginlist > /path/to/src/dissect.target/dissect/target/plugins/_pluginlist.py
$ pyinstaller /path/to/src/acquire/acquire.py --hidden-import dissect --collect-submodules dissect --onefile

This is again a very basic example. More optimized PyInstaller builds are left as an exercise to the reader.

Usage

acquire - CLI interface

acquire [-h] [-o OUTPUT | -of OUTPUT_FILE] [-ot {tar,dir,zip}] [--compress | --no-compress]
        [--compress-method {lzma,gzip,deflate,bzip2,xz}] [--encrypt | --no-encrypt]
        [--gui [GUI]] [-l LOG] [-L LOADER] [-p {full,default,minimal,none}]
        [--volatile-profile {full,default,none}] [-f FILE] [-d DIRECTORY] [-g GLOB]
        [--disable-report] [--child CHILD] [--children | --no-children]
        [--skip-parent | --no-skip-parent] [--force-fallback | --no-force-fallback]
        [--fallback | --no-fallback] [-u | --auto-upload | --no-auto-upload]
        [--upload UPLOAD [UPLOAD ...]] [--no-proxy] [-K KEYCHAIN_FILE] [-Kv KEYCHAIN_VALUE]
        [--sys | --no-sys] [--proc | --no-proc] [--proc-net | --no-proc-net]
        [-n | --ntfs | --no-ntfs] [-r | --registry | --no-registry]
        [--netstat | --no-netstat] [--devices | --no-devices]
        [--win-processes | --no-win-processes] [--win-proc-env | --no-win-proc-env]
        [--win-arp-cache | --no-win-arp-cache] [--win-rdp-sessions | --no-win-rdp-sessions]
        [--winpmem | --no-winpmem] [--winmem-files | --no-winmem-files]
        [-e | --eventlogs | --no-eventlogs] [-t | --tasks | --no-tasks]
        [-ad | --active-directory | --no-active-directory] [-nt | --ntds | --no-ntds]
        [--etl | --no-etl] [--recents | --no-recents] [--startup | --no-startup]
        [--data-files | --no-data-files] [--large-files | --no-large-files]
        [--recyclebin | --no-recyclebin] [--drivers | --no-drivers]
        [--exchange | --no-exchange] [--mssql | --no-mssql] [--iis | --no-iis]
        [--prefetch | --no-prefetch] [--appcompat | --no-appcompat] [--pca | --no-pca]
        [--syscache | --no-syscache] [--win-notifications | --no-win-notifications]
        [--bits | --no-bits] [--wbem | --no-wbem] [--dhcp | --no-dhcp] [--dns | --no-dns]
        [--win-dns-cache | --no-win-dns-cache] [--powershell | --no-powershell]
        [--thumbnail-cache | --no-thumbnail-cache] [--text-editor | --no-text-editor]
        [--misc | --no-misc] [--av | --no-av] [--quarantined | --no-quarantined]
        [--edr | --no-edr] [--history | --no-history] [--remoteaccess | --no-remoteaccess]
        [--webhosting | --no-webhosting] [--wer | --no-wer] [--etc | --no-etc]
        [--boot | --no-boot] [--home | --no-home] [--private-keys | --no-private-keys]
        [--ssh | --no-ssh] [--docker | --no-docker] [--var | --no-var] [--bsd | --no-bsd]
        [--osx | --no-osx] [--osx-applications-info | --no-osx-applications-info]
        [--bootbanks | --no-bootbanks] [--esxi | --no-esxi] [--vmfs | --no-vmfs]
        [--activities-cache | --no-activities-cache] [--glob-to-hash GLOB_TO_HASH]
        [--ext-to-hash EXT_TO_HASH] [--dir-to-hash DIR_TO_HASH]
        [--hash-func {md5,sha1,sha256}] [--hashes | --no-hashes]
        [--handle-types [{ALPC Port,Callback,Desktop,Device,Directory,Driver,EtwRegistration,Event,File,FilterConnectionPort,IoCompletion,IRTimer,Job,Key,KeyedEvent,Mutant,Mutex,Partition,Process,Section,Session,Semaphore,SymbolicLink,Timer,Thread,Token,TpWorkerFactory,Type,WaitCompletionPacket,WindowStation,Unknown} ...]]
        [--handles | --no-handles] [-v]
        [TARGETS ...]

acquire positional arguments

  • TARGETS - Targets to load (default: ['local'])

acquire optional arguments

If no target is specified, 'local' is used.

If no options are given, the collection profile 'default' is used.