Skip to content

monkeywave/XFRM-Inspector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 Data Forensic 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 addresses Identification of VPN tunnel endpoints
Security policies with selectors Reconstruction of traffic routing decisions
Tunnel/Transport mode configuration Determination of encapsulation methodology
Lifetime counters (bytes/packets) Quantification of SA usage and activity periods
Network namespace identifiers Attribution 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 installation
cd /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

Option Applicable Plugins Description
--ip-style XfrmState, XfrmPolicy Output format compatible with iproute2 utilities
--wireshark XfrmState Wireshark ESP SA import format
--json-output XfrmState JSON format for automation
--verbose XfrmState Include lifetime counters and timestamps
--netns-inum N All Filter by network namespace inode number
--show-expired XfrmState Include expired Security Associations
--show-all XfrmShow Show 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

Architecture Symbol-Dependent Symbol-Independent
x86_64 Supported Supported
ARM64 (AArch64) Supported Supported
x86 (32-bit) Supported Limited

Supported Cryptographic Algorithms

Encryption Algorithms

Kernel Identifier Wireshark Designation Reference
cbc(aes) AES-CBC RFC 3602
rfc4106(gcm(aes)) AES-GCM RFC 4106
cbc(des3_ede) 3DES-CBC RFC 2451
ctr(aes) AES-CTR RFC 3686
rfc7539(chacha20,poly1305) CHACHA20-POLY1305 RFC 7634

Authentication Algorithms

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

Kernel Data Structures

xfrm_state (Security Association)

struct xfrm_state {
    possible_net_t      xs_net;      // Network namespace reference
    struct hlist_node   bydst;       // Hash linkage by destination
    struct hlist_node   byspi;       // Hash linkage by SPI
    struct xfrm_id      id;          // SPI, protocol, destination
    struct xfrm_selector sel;        // Traffic selector
    struct xfrm_lifetime_cfg lft;    // Lifetime configuration
    struct xfrm_lifetime_cur curlft; // Current usage counters
    struct xfrm_algo    *ealg;       // Encryption algorithm
    struct xfrm_algo_auth *aalg;     // Authentication algorithm
    struct xfrm_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)

struct xfrm_policy {
    possible_net_t      xs_net;      // Network namespace reference
    struct hlist_node   bydst;       // Hash linkage
    struct xfrm_selector sel;        // Traffic selector
    u32                 priority;    // Policy priority
    u8                  type;        // Policy type
    u8                  dir;         // Direction (in/out/fwd)
    struct xfrm_tmpl    xfrm_vec[];  // Template array
    int                 xfrm_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

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages