In this module
MF1.3 Linux Acquisition with LiME and AVML
From MF1.2 you know how WinPmem captures Windows memory: a signed driver loads into the kernel, reads physical pages, and writes a raw image. Linux acquisition uses the same physical-memory-read approach but with a fundamentally different delivery mechanism — a loadable kernel module (LiME) or a userspace tool that avoids the module requirement entirely (AVML). Both have constraints Windows practitioners don't expect.
Linux memory acquisition is harder than Windows memory acquisition for one reason: kernel module version coupling. WinPmem ships a single binary that works across Windows 10 and 11 builds because the driver interface is stable. LiME is a loadable kernel module (LKM) that must be compiled against the exact kernel headers for the target system's running kernel. A module built for 5.15.0-91-generic will not load on 5.15.0-92-generic. One patch-level difference and the module refuses to insert.
This version-coupling means you can't carry a single LiME binary the way you carry WinPmem. You either pre-build modules for every kernel version in your environment (feasible for a fleet of identical Ubuntu servers, nightmarish for a heterogeneous estate), build on the target at acquisition time (requires build-essential and kernel headers on a system you're trying to not modify), or use AVML — Microsoft's acquisition tool that reads /proc/kcore from userspace and avoids the kernel module requirement entirely.
This sub covers both tools: LiME for when you can match the kernel version (which includes the course's Target-Linux VM, where you control the kernel), and AVML for when you can't. By the end, you'll have captured memory from your Target-Linux VM and verified it parses in Volatility 3.
Deliverable: Ability to capture Linux memory using LiME (compile, load, capture, verify) and AVML (download, execute, verify), understand when each is appropriate, troubleshoot kernel-version mismatch errors, and produce a verified Linux memory image from your Target-Linux VM.
LiME — kernel module acquisition
This section covers the tool the course uses for Linux captures. The kernel-module architecture is LiME's strength and its constraint — understand both before you compile.
LiME (Linux Memory Extractor) is a loadable kernel module that reads physical memory through the kernel's internal page-mapping interface. Because it runs inside the kernel, it has the same level of access as the kernel itself — no page is off-limits, no mapping is restricted. This gives LiME the highest-fidelity read possible on a Linux system.
The cost is version coupling. Linux kernel modules are compiled against specific kernel headers, and the resulting .ko file contains a vermagic string that must exactly match the running kernel's version. insmod checks this string before loading the module and rejects mismatches. There is no cross-version compatibility, no "close enough" — the version must be identical down to the patch level and any distribution-specific suffix.
For the course's Target-Linux VM (Ubuntu 22.04 with a kernel you control), this isn't a problem. You install the kernel headers for your running kernel, compile LiME, and the module loads.
For production incident response against a server whose kernel version you didn't prepare for, this is a significant constraint. The options are: pre-build LiME modules for every kernel version in your fleet and carry them on your IR toolkit USB drive, compile on the target (which requires build-essential and headers, adding forensic footprint), or use AVML instead.
LiME supports three output modes. Disk output writes to a local file in LiME's own format, which Volatility 3 reads natively:
sudo insmod lime.ko "path=/evidence/mem.lime format=lime"Raw padded output writes a raw image with zero-filled gaps for non-addressable physical ranges — similar to WinPmem's raw output but for Linux:
sudo insmod lime.ko "path=/evidence/mem.raw format=padded"Network output streams the memory image over a TCP socket to a remote listener, avoiding any disk writes on the target:
# On analysis workstation (listener):
nc -l -p 4444 > target.lime
# On target (sender):
sudo insmod lime.ko "path=tcp:4444 format=lime"Network capture is LiME's killer feature for minimal-footprint acquisition: the module loads, reads memory, streams the data to your analysis workstation, and unloads without ever writing to the target's filesystem.
AVML — userspace acquisition without kernel module constraints
This section covers the alternative when LiME's kernel-version coupling makes it infeasible. AVML trades slightly higher smear for dramatically broader compatibility.
AVML (Acquire Volatile Memory for Linux) is Microsoft's open-source Linux memory acquisition tool. Unlike LiME, AVML runs entirely in userspace — it reads memory through /proc/kcore, a pseudo-file the kernel exposes that represents physical memory as a virtual file.
Because AVML doesn't load a kernel module, it doesn't have a version-coupling constraint. The same AVML binary works on any Linux kernel that exposes /proc/kcore, which is most standard distributions.
The tradeoff is fidelity. A userspace read through /proc/kcore goes through the kernel's page-fault handler and mapping infrastructure rather than reading physical pages directly. AVML's capture is subject to slightly more smear than LiME's kernel-level read, because the userspace read path is longer and involves more kernel scheduling points.
In practice, the difference is small on systems with reasonable load — both tools produce images with comparable analysis results. The difference matters most on heavily loaded servers where the extra scheduling overhead produces measurably more torn structures.
AVML's constraint is that /proc/kcore must be accessible. Some hardened distributions restrict access (setting it to mode 0400 or disabling it via CONFIG_PROC_KCORE=n). Containerised environments and minimal kernel configurations may not expose it at all. When /proc/kcore isn't available, you're back to LiME or hypervisor-based acquisition.
The command is straightforward — download the static binary, make it executable, run with root:
sudo ./avml /evidence/target-linux.limeAVML writes LiME-format output by default, which Volatility 3 reads natively. No compilation step, no kernel headers, no version matching. Hash the output immediately after capture.
When to use which — the Linux acquisition decision
This section gives you the decision rule. Don't memorise it — understand why each branch exists, and the decision falls out naturally.
The decision between LiME and AVML maps to the same fidelity-footprint-feasibility frame from MF1.1, with Linux-specific constraints layered on top.
Use LiME when you control the kernel version or have pre-built the module. The course lab is the canonical example: you installed Ubuntu 22.04 on Target-Linux, you know the kernel version, you can compile LiME against it. Production environments where you maintain a fleet of identical servers (same distribution, same kernel, same patch level) are similarly suited — pre-build LiME modules for your fleet's kernel versions and carry them on the IR toolkit. LiME's kernel-level read provides the highest fidelity, and the network output mode provides the lowest disk footprint.
Use AVML when you can't match the kernel version. Heterogeneous server estates, unfamiliar systems during incident response, cloud VMs where you don't control the kernel build, containerised environments where you have host access but not the kernel headers — AVML's single-binary portability solves the version-coupling problem. The fidelity tradeoff is acceptable for most investigations.
Use hypervisor-based acquisition (MF1.4) when you have hypervisor access. Same logic as Windows: zero guest footprint, zero version coupling, highest fidelity. VMware .vmem capture works identically for Linux guests and Windows guests.
This procedure runs against your MF0.9 Target-Linux VM (Ubuntu 22.04). You'll compile LiME, load the module, capture memory to a local file, and verify the image parses in Volatility 3.
The situation. Northgate Engineering's RHEL 8.9 database server triggered a Sentinel alert for anomalous outbound traffic at 03:47. The SOC lead wants memory. The server is a physical host (no hypervisor), running kernel 4.18.0-513.24.1.el8_9.x86_64. Your IR toolkit has pre-built LiME modules for Ubuntu 22.04 kernels but not RHEL 8.9. You have root SSH access. You also have the AVML static binary on your toolkit USB.
The choice. Compile LiME on the target (requires installing kernel-devel and gcc on a production database server during an active incident), use your pre-built LiME module (wrong kernel version, won't load), or use AVML.
The correct call. AVML. The pre-built LiME module won't load — RHEL 8.9's kernel is a different version entirely from your Ubuntu 22.04 builds. Compiling LiME on the target is technically possible but forensically costly: yum install kernel-devel gcc modifies the target's package state, writes to disk, and increases the forensic footprint on a system you're trying to preserve. AVML avoids both problems — it's a single static binary, no compilation, no package installation, and it reads through /proc/kcore without kernel-version coupling. Document the decision: "LiME not used due to kernel-version mismatch (pre-built for Ubuntu, target is RHEL 8.9); AVML selected to avoid modifying production server's package state during active incident."
The operational lesson. Pre-building LiME modules only helps for the kernels you anticipated. A heterogeneous fleet — Ubuntu on workstations, RHEL on servers, Amazon Linux on EC2 — means you either maintain LiME builds for every kernel in your estate (expensive) or carry AVML as the universal fallback (pragmatic). Most IR teams do both: LiME for the kernels they know, AVML for everything else.
The myth. To capture Linux memory, you need to compile LiME on the target server, which means installing a compiler and kernel headers on a system that's part of an active investigation. The compilation changes the system state, which means the acquisition is forensically compromised before it begins. Linux memory acquisition is therefore fundamentally less forensically sound than Windows acquisition.
The reality. The myth is true only if LiME is your only option and you didn't pre-compile. Three alternatives avoid target-side compilation entirely. Pre-compiled LiME modules (built on a matching-kernel system in advance and carried on the IR toolkit) load with insmod — no compilation on target. AVML runs as a static binary with no compilation step at all. Hypervisor-based acquisition (MF1.4) captures the VM's memory from outside the guest and touches nothing inside it.
The forensically strongest Linux acquisition path is hypervisor suspension for VMs, followed by pre-compiled LiME or AVML for physical hosts. Compiling on the target is the last resort, not the default, and it's still forensically defensible if documented correctly — the compilation footprint is identifiable and excludable, the same way WinPmem's own process is identifiable in a Windows capture. The claim that Linux acquisition is "less sound" than Windows conflates the worst-case method with the only method.
Try it — Capture Target-Linux memory with LiME and verify in Volatility 3
Setup. Your MF0.9 Target-Linux VM running Ubuntu 22.04, with SSH access and root privileges. Internet access on the VM for apt install and git clone (if you haven't already installed the prerequisites).
Task. Execute the full Guided Procedure above: install prerequisites, compile LiME, load the module with format=lime, unload, hash, transfer to the analysis workstation, re-hash, and run vol -f target-linux-baseline.lime linux.banner. Confirm the banner's kernel version matches uname -r on Target-Linux.
Expected result. A LiME-format image approximately equal to Target-Linux's RAM size (2 GB default). Matching SHA-256 hashes on both systems. linux.banner output showing the Ubuntu 22.04 kernel version string. This is your Linux baseline image — keep it alongside the Windows baseline from MF1.2.
If your result doesn't match. If insmod fails with "Invalid module format," the kernel version mismatch is the cause — verify uname -r matches the .ko filename exactly. If linux.banner fails with "Unable to determine OS," Volatility 3 may be missing the ISF (Intermediate Symbol Format) for your kernel build — check the Volatility 3 symbol pack or generate a custom ISF with dwarf2json from the kernel's debug symbols package (linux-image-$(uname -r)-dbgsym).
You should be able to do the following without referring back to this sub. If you can't, the sections to re-read are noted.
You've set up the lab and captured your first clean baselines.
MF0 built the three-VM lab and established the memory forensics landscape. MF1 taught acquisition with WinPmem and LiME, integrity verification, and chain of custody. From here, you execute attacks and investigate what they leave behind.
- 8 attack modules (MF2–MF9) — process injection, credential theft, fileless malware, persistence, kernel drivers, Linux rootkits, timeline construction, and a multi-stage capstone
- You run every attack yourself — from Kali against your target VMs, then capture memory and investigate your own attack's artifacts with Volatility 3
- MF9 Capstone — multi-stage chain (initial access → privilege escalation → credential theft → persistence → data staging), three checkpoint captures, complete investigation report
- The lab pack — PoC kernel driver and LKM rootkit source code, setup scripts, 21 exercises, 7 verification scripts, investigation report templates
- Cross-platform coverage — Windows and Linux memory analysis in one course, with the timeline module integrating evidence from both
Cancel anytime