Skip to content

Latest commit

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

XFRM-Inspector: Volatility 3 IPsec/XFRM Memory Forensics Plugins

Memory forensics plugins for extracting IPsec Security Association (SA) and Security Policy (SP) data from Linux kernel memory images.

Abstract

These plugins enable the extraction of cryptographic key material and configuration metadata from the Linux kernel's XFRM subsystem (s. XFRM Intro), which implements the IPsec protocol suite. The extracted data facilitates retrospective decryption of captured network traffic and provides forensic visibility into encrypted communication channels.

Forensic Applications

The plugins address several forensic use cases:

Extracted DataForensic Application
ESP encryption keys (AES, 3DES, ChaCha20)Decryption of ESP-encrypted IPsec packets
Authentication keys (HMAC-SHA256, HMAC-SHA1)Verification of packet integrity and detection of tampering
Security Parameter Index (SPI)Correlation of memory-resident keys with captured network traffic
Source/Destination addressesIdentification of VPN tunnel endpoints
Security policies with selectorsReconstruction of traffic routing decisions
Tunnel/Transport mode configurationDetermination of encapsulation methodology
Lifetime counters (bytes/packets)Quantification of SA usage and activity periods
Network namespace identifiersAttribution of VPN configurations to containers or namespaces

Installation

Prerequisites

  • Volatility 3 Framework (version 2.10.0 or later)
  • Python 3.8 or later
  • Linux memory dump in supported format (LiME, ELF core, etc.)
  • ISF symbol file for the target kernel (for symbol-dependent plugins)

Method 1: Direct Installation (Recommended)

Copy the plugin files directly to the Volatility 3 plugins directory:

# Navigate to Volatility 3 installationcd /path/to/volatility3
# Copy plugin files
cp -r /path/to/XFRM-Inspector/src/linux/xfrm.py \
volatility3/framework/plugins/linux/
cp -r /path/to/XFRM-Inspector/src/linux/xfrm_nosymbols.py \
volatility3/framework/plugins/linux/

Method 2: External Plugin Path

Specify the plugin directory at runtime using the -p flag:

python3 vol.py \
-p /path/to/XFRM-Inspector/src \
-f memory.dump \
linux.xfrm.XfrmState

Note: When using an external plugin path, ensure the directory structure does not conflict with built-in Volatility packages. If import errors occur, use Method 1 instead.


Plugin Overview

linux.xfrm.XfrmState

Extracts Security Association Database (SAD) entries containing cryptographic keys and SA metadata.

Output Formats:

  • Tabular format (default)
  • ip xfrm state compatible format (--ip-style)
  • Wireshark ESP SA format (--wireshark)
  • JSON format (--json-output)

linux.xfrm.XfrmPolicy

Extracts Security Policy Database (SPD) entries defining traffic selectors and policy rules.

Output Formats:

  • Tabular format (default)
  • ip xfrm policy compatible format (--ip-style)

linux.xfrm.XfrmShow

Unified plugin providing combined SAD and SPD output per network namespace, analogous to executing ip xfrm state followed by ip xfrm policy.

Key Features:

  • By default, only shows namespaces containing XFRM states or policies (reduces noise)
  • Displays process names using each namespace (e.g., charon[13070]) for easier identification
  • Provides a summary of how many namespaces have XFRM content
  • Use --show-all to include empty namespaces

linux.xfrm_nosymbols.XfrmStateNoSymbols

Symbol-independent plugin utilizing physical memory scanning for environments lacking debug symbols. Still experimental.

Requirements

Symbol-Dependent Plugins (XfrmState, XfrmPolicy, XfrmShow)

  • Linux memory image (LiME, /proc/kcore, or equivalent)
  • ISF symbol file generated via dwarf2json or obtained from Volatility symbol repositories

Symbol-Independent Plugin (XfrmStateNoSymbols)

  • Linux memory image (LiME format recommended)
  • Supported kernel versions: 5.x, 6.x (ARM64, x86_64)

Installation

Method 1: Plugin Path Specification

python3 vol.py -p /path/to/volatility_plugins \
-s /path/to/symbols \
-f memory.dump \
linux.xfrm.XfrmState

Method 2: Volatility Integration

cp -r linux/ /path/to/volatility3/volatility3/framework/plugins/

Usage Examples

Security Association Extraction

# Tabular output
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmState
# Output matching 'ip xfrm state' format
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmState --ip-style
# Wireshark ESP decryption format
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmState --wireshark > esp_keys.txt
# JSON output for programmatic processing
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmState --json-output > states.json
# Filter by network namespace
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmState --netns-inum 4026532324

Security Policy Extraction

# Tabular output
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmPolicy
# Output matching 'ip xfrm policy' format
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmPolicy --ip-style

Unified SAD/SPD View

# Default: only shows namespaces with XFRM content, includes process info
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmShow
# Show all namespaces including empty ones
python3 vol.py -p /path/to/plugins -s /path/to/symbols \
-f memory.dump linux.xfrm.XfrmShow --show-all

Symbol-Independent Extraction

python3 vol.py -p /path/to/plugins \
-f memory.dump linux.xfrm_nosymbols.XfrmStateNoSymbols

Command-Line Options

OptionApplicable PluginsDescription
--ip-styleXfrmState, XfrmPolicyOutput format compatible with iproute2 utilities
--wiresharkXfrmStateWireshark ESP SA import format
--json-outputXfrmStateJSON format for automation
--verboseXfrmStateInclude lifetime counters and timestamps
--netns-inum NAllFilter by network namespace inode number
--show-expiredXfrmStateInclude expired Security Associations
--show-allXfrmShowShow all namespaces including empty ones (default: only with content)

Output Format Specifications

Tabular Format (XfrmState)

Offset NetNS Proto SPI Src Dst Mode EncAlgo EncKey AuthAlgo AuthKey
0xffff0000fc5c9040 4026532324 ESP 0x30d8d4c4 10.0.0.1 10.0.0.2 tunnel cbc(aes) 851b63... hmac(sha256) e06e68...

Tabular Format (XfrmPolicy)

Offset NetNS Dir Priority Src Dst Templates
0xffff0000c4b6a000 4026532324 in 367231 10.0.0.2/32 10.0.0.1/32 1

ip xfrm state Format

src 10.0.0.1 dst 10.0.0.2
proto esp spi 0xbee395c6 reqid 1 mode tunnel
replay-window 0 flag af-unspec
auth-trunc hmac(sha256) 0x8b6b946640cbacac... 128
enc cbc(aes) 0x76b4fd85af668aaa...
anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000

ip xfrm policy Format

src 10.0.0.2/32 dst 10.0.0.1/32
dir in priority 367231
tmpl src 10.0.0.2 dst 10.0.0.1
proto esp reqid 1 mode tunnel

XfrmShow Output

Showing 2 of 9 namespaces with XFRM content (use --show-all to see all)
=== Network Namespace: 4026532505 (charon[13070], tcpdump[13717]) ===
src 10.0.0.1 dst 10.0.0.2
proto esp spi 0xc8d22bd1 reqid 1 mode tunnel
replay-window 0 flag af-unspec
auth-trunc hmac(sha256) 0x24b88656be2a856a... 128
enc cbc(aes) 0xddd9bea883ce8355...
anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
src 10.0.0.2/32 dst 10.0.0.1/32
dir in priority 367231
tmpl src 10.0.0.2 dst 10.0.0.1
proto esp reqid 1 mode tunnel

Note: The process names in parentheses (e.g., charon[13070]) identify which applications are using each network namespace, facilitating correlation with VPN configurations or container boundaries.

Wireshark ESP SA Format

"esp","10.0.0.1","10.0.0.2","0xbee395c6","AES-CBC [RFC3602]","0x76b4fd85...","HMAC-SHA-256-128 [RFC4868]","0x8b6b9466..."

JSON Format

{
"plugin": "linux.xfrm.XfrmState",
"timestamp": "2025-12-20T14:08:32.903356",
"states": [
{
"offset": "0xffff0000fd9b8d00",
"netns_inum": 4026532324,
"protocol": "ESP",
"spi": "0xbee395c6",
"src_addr": "10.0.0.1",
"dst_addr": "10.0.0.2",
"mode": "tunnel",
"reqid": 1,
"encryption": {
"algorithm": "cbc(aes)",
"key_len_bits": 256,
"key_hex": "76b4fd85af668aaad336bb168128636e..."
},
"authentication": {
"algorithm": "hmac(sha256)",
"key_len_bits": 256,
"key_hex": "8b6b946640cbacac8719cb8c334fb0c2..."
}
}
]
}

Wireshark Integration

To decrypt captured IPsec traffic using extracted keys:

  1. Generate keys in Wireshark format: --wireshark > esp_keys.txt
  2. In Wireshark, navigate to Edit, Preferences, Protocols, ESP
  3. Select Edit adjacent to ESP SAs
  4. Import the generated file or enter entries manually

Symbol File Generation

Using dwarf2json

dwarf2json linux --elf /path/to/vmlinux > linux-$(uname -r).json

Symbol File Placement

volatility3/symbols/linux-6.8.0-generic-arm64.json

Architecture Support

ArchitectureSymbol-DependentSymbol-Independent
x86_64SupportedSupported
ARM64 (AArch64)SupportedSupported
x86 (32-bit)SupportedLimited

Supported Cryptographic Algorithms

Encryption Algorithms

Kernel IdentifierWireshark DesignationReference
cbc(aes)AES-CBCRFC 3602
rfc4106(gcm(aes))AES-GCMRFC 4106
cbc(des3_ede)3DES-CBCRFC 2451
ctr(aes)AES-CTRRFC 3686
rfc7539(chacha20,poly1305)CHACHA20-POLY1305RFC 7634

Authentication Algorithms

Kernel IdentifierWireshark DesignationReference
hmac(sha256)HMAC-SHA-256-128RFC 4868
hmac(sha1)HMAC-SHA-1-96RFC 2404
hmac(sha384)HMAC-SHA-384-192RFC 4868
hmac(sha512)HMAC-SHA-512-256RFC 4868
xcbc(aes)AES-XCBC-MAC-96RFC 3566

Kernel Data Structures

xfrm_state (Security Association)

structxfrm_state {
possible_net_txs_net; // Network namespace referencestructhlist_nodebydst; // Hash linkage by destinationstructhlist_nodebyspi; // Hash linkage by SPIstructxfrm_idid; // SPI, protocol, destinationstructxfrm_selectorsel; // Traffic selectorstructxfrm_lifetime_cfglft; // Lifetime configurationstructxfrm_lifetime_curcurlft; // Current usage countersstructxfrm_algo*ealg; // Encryption algorithmstructxfrm_algo_auth*aalg; // Authentication algorithmstructxfrm_algo_aead*aead; // AEAD algorithm// Additional fields omitted
};

The upstream definition of the original structure is in the Linux kernel source (include/net/xfrm.h, Linux v5.10.46), starting at line 149. See: [xfrm.h @ v5.10.46 (L149)][xfrm-h].

xfrm_policy (Security Policy)

structxfrm_policy {
possible_net_txs_net; // Network namespace referencestructhlist_nodebydst; // Hash linkagestructxfrm_selectorsel; // Traffic selectoru32priority; // Policy priorityu8type; // Policy typeu8dir; // Direction (in/out/fwd)structxfrm_tmplxfrm_vec[]; // Template arrayintxfrm_nr; // Template count// Additional fields omitted
};

Symbol-Independent Plugin Technical Details

The XfrmStateNoSymbols plugin employs the following methodology:

  1. Physical memory scanning for algorithm name patterns (e.g., "cbc(aes)", "hmac(sha256)")
  2. Structure validation at each pattern match location
  3. Key material extraction from validated xfrm_algo structures
  4. Reverse pointer traversal to locate parent xfrm_state structures
  5. Deduplication of extracted keys

Limitations:

  • Extended execution time due to full memory scan requirements
  • Reduced metadata availability for keys in vmalloc regions
  • Potential inclusion of residual keys from freed memory

Troubleshooting

No Security Associations Found

  1. Verify symbol file compatibility with kernel version
  2. Remove network namespace filter to search all namespaces
  3. Confirm IPsec tunnels were active at time of memory acquisition
  4. Enable verbose logging with -v or -vv flags

Symbol Resolution Errors

Regenerate symbol file using dwarf2json with a vmlinux binary containing DWARF debug information.

References

About

Linux IPsec SAD/SPD (XFRM) Recovery for Volatility 3

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages