Bridging memory and network forensics with XFRM inspection
I still remember the clear division of labor in the early days of incident response. You had the network analysts staring at scrolling walls of packets, and the host analysts knee-deep in disk images and memory dumps. The two teams usually sat in the same room and drank the same terrible coffee, but they spoke entirely different languages. That siloed approach worked reasonably well when threats were simple and unencrypted. Today, it is a reliable recipe for failure. The gap between network and host forensics becomes painfully obvious the moment encryption enters the chat. A compromised gateway funneling data through an encrypted tunnel is a nightmare for network analysts. They can see the packets, but the payload is just mathematical noise. Meanwhile, the memory analyst has the keys sitting in RAM, but no packets to apply them to. Bridging this gap has always been a manual and deeply frustrating process.

That dynamic changed significantly in recent weeks. The results of the Volatility Plugin Contest highlighted a fundamental shift in how we handle these investigations, with the XFRM Inspector plugin standing out as a practical bridge between these two worlds. For years, I have argued that treating network and memory as separate disciplines leaves massive blind spots in an investigation. If an attacker establishes an IPsec VPN tunnel from a compromised Linux server to exfiltrate data, your standard packet capture is practically useless. You need the session keys to decrypt Encapsulating Security Payload (ESP) traffic. Historically, getting those keys meant relying on live extraction tools or hoping the attacker left debugging logs enabled, which rarely happens. Now, we can pull the exact cryptographic material needed directly from a memory dump, effectively turning an opaque network capture into a cleartext playbook of the attacker’s actions.
The blind spot of encrypted tunnels
Network forensics has always suffered from a visibility problem. We deploy sensors at choke points, capture terabytes of traffic, and feed it into massive analytics engines. But as privacy advocates and security architects pushed for ubiquitous encryption, the traditional network intrusion detection systems went dark. Attackers noticed this trend and adapted. They stopped using custom, noisy command and control protocols and started blending into the background radiation of legitimate enterprise traffic. If your infrastructure relies heavily on site-to-site VPNs, a rogue IPsec tunnel established by an Advanced Persistent Threat group looks identical to your daily operational traffic.
When you open a packet capture of this traffic in Wireshark, you see the IP headers, you see the ESP protocol identifier, and then you see a wall of encrypted bytes. There are no patterns to match with YARA rules, no strings to extract, and no file signatures to identify. The network analyst is effectively locked out. The standard incident response playbook often dictates that you should isolate the host and pull a memory dump. The host analyst then runs Volatility 3 to look for rootkits, injected threads, or suspicious network connections. They might see that a process is listening on a specific port, but without the context of the data flowing through that port, determining the scope of the breach becomes an exercise in educated guessing.
The real prize in a memory dump of a compromised network appliance or gateway is not just the list of running processes. It is the cryptographic state of the machine. Every active encrypted connection requires the operating system to hold the decryption keys in memory. If you can locate those keys, you can retroactively decrypt the packet captures collected by your network sensors. This concept is not new for TLS traffic, where extracting the master secrets log from memory has been a standard technique for years. However, dealing with kernel-level VPN tunnels like IPsec on Linux has remained a notoriously difficult challenge due to how the operating system handles packet transformation.
Digging into the Linux XFRM framework
To understand how to extract these keys, you have to understand how the Linux kernel handles IPsec. It does not use a standalone daemon running in user space to encrypt every individual packet. That approach would be incredibly slow and inefficient, causing massive latency overhead for high-throughput connections. Instead, it relies on a kernel subsystem called the XFRM framework, pronounced “transform”. The XFRM framework is responsible for altering packets as they pass through the networking stack, applying encryption, decryption, and authentication based on a set of predefined rules.
When a VPN connection is established, the key exchange daemon (like strongSwan or Libreswan) negotiates the cryptographic parameters with the remote peer over UDP port 500 or 4500. Once the negotiation is complete, the user-space daemon hands the actual encryption keys and algorithms down to the Linux kernel. The kernel stores these details in data structures known as Security Associations (SAs). An SA contains everything needed to process an IPsec packet, including the source and destination IP addresses, the Security Parameter Index (SPI), the encryption algorithm (such as AES-GCM), the authentication algorithm (such as HMAC-SHA256), and the raw cryptographic keys themselves.
These structures live deep within the kernel memory space. If you have root access to a live system, you can dump this information using userland utilities like the ip xfrm command.
# Displaying active Security Associations on a live Linux system
ip xfrm state
The output of this live command exposes exactly what we will later look for in the raw memory dump:
src 192.168.10.5 dst 10.0.0.1
proto esp spi 0x0c3a2b1f reqid 16384 mode tunnel
replay-window 0 flag af-unspec
auth-trunc hmac(sha256) 0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e 128
enc cbc(aes) 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b
anti-replay context: seq 0x0, oseq 0x14, bitmap 0x00000000
But in a forensic scenario, you are rarely interacting with a live, uncompromised system. You are staring at a static file containing a snapshot of physical memory. The challenge for a memory forensic investigator is locating the xfrm_state structures within the vast, unstructured expanse of a raw memory dump. Because Linux kernel layouts change depending on the specific kernel version and compilation options, you cannot just search for a static memory address or a simple magic byte sequence. You need a tool that understands the internal geometry of the kernel.
Extracting keys from the void
This is exactly the problem that the new Volatility 3 plugin solves. The XFRM Inspector does not rely on blind string searching or unreliable heuristics. It leverages the debug symbols of the Linux profile to locate the XFRM state tables systematically. When you run the plugin against a memory dump, it walks the internal lists maintained by the kernel networking stack, parses each xfrm_state structure it finds, and extracts the critical cryptographic parameters.
To execute the recovery, you invoke the plugin by pointing it at your acquired Linux memory image and specifying the appropriate Symbol File:
python3 vol.py -f /path/to/linux_memory.raw linux.xfrm_inspector.XfrmInspector
The plugin maps out the underlying kernel structures by parsing the C structs defined in the kernel source, specifically targeting the hash tables that house the active transforms. The recovered output presents the structure cleanly:
Volatility 3 Framework v2.5.2
Filtering: Kernel modules and structures
SPI Proto Source Destination Algorithm Key (Hex)
----------- ------ --------------- --------------- ----------- ----------------------------------------------------------------
0x0c3a2b1f ESP 192.168.10.5 10.0.0.1 AES-CBC 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b
HMAC-SHA256 9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e
0x0f2b3a4c ESP 10.0.0.1 192.168.10.5 AES-CBC 8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e
HMAC-SHA256 1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a
Seeing this tool in action is a reminder of why memory forensics remains such a powerful discipline. Attackers can delete logs, they can hide their binaries using rootkits, and they can obfuscate their network traffic. But they cannot change the fundamental reality that the operating system must know how to decrypt the packets to function. If the tunnel is active, the keys are in memory, and if the keys are in memory, they can be extracted.
I often think back to my early days working with older hardware, back when I first learned to code on a Commodore 16. In those days, you had to know exactly what was residing in every specific memory address. If you wanted the machine to do something, you poked a value directly into a register. The abstraction layers we have today are incredible, but they often make us forget that underneath the slick interfaces and automated EDR solutions, it is still just bytes in RAM. The XFRM framework is complex, but at its core, it is just a structured list of keys waiting to be read by anyone who knows the correct offset. The developers behind this plugin have done the hard work of mapping those offsets for us, allowing investigators to focus on the analysis rather than the reverse engineering of kernel structures.
If you are setting up your analysis environment, make sure your Volatility 3 installation is fully updated and that you have a solid understanding of how to generate Linux symbol tables (ISF files) for the specific kernel version you are investigating. I have previously discussed the nuances of building a Volatility profile for Linux and Linux memory capture and analysis, and that groundwork is an absolute prerequisite for making this technique work reliably. A wrong profile means wrong offsets, which means you pull garbage data instead of your AES keys.
Bringing the keys back to Wireshark
Extracting the keys from memory is only half the battle. The true value of this technique is realized when you hand those keys back to the network analyst. Wireshark has robust built-in support for decrypting ESP traffic, provided you can supply it with the correct Security Associations. This is where the bridge between the two disciplines is finally completed.
Instead of dealing entirely with the graphical user interface during large-scale automation, you can map the recovered Volatility artifacts directly into Wireshark’s command-line counterpart, tshark. This allows for rapid programmatic translation of raw packet captures using the extracted keys:
tshark -r encrypted_traffic.pcap \
-o "esp.enable_encryption_decryption:TRUE" \
-o "esp.sa_1:IPv4/*/*/*,192.168.10.5,10.0.0.1,0x0c3a2b1f,AES-CBC [16 bytes],0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d,HMAC-SHA-256-128 [32 bytes],0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e" \
-Y "http or ssh"
The moment you apply these parameters, whether in the GUI or via the command line, the wall of noise vanishes. The packets that were previously tagged simply as ESP payload suddenly reveal their true nature. You might see the cleartext HTTP requests used to download secondary payloads, the SSH sessions used for lateral movement, or the proprietary command and control beacons of a custom backdoor. It is a profoundly satisfying experience. You have effectively traveled back in time, removing the encryption layer from a network capture long after the connection was terminated.
This decryption capability fundamentally changes how you approach threat hunting on compromised gateways. Instead of just noting that an unauthorized VPN tunnel existed, you can perform a full packet inspection on the attacker’s traffic. You can extract the exact commands they ran, the files they stole, and the internal IP addresses they targeted. This level of granular visibility is the difference between writing an incident report that assumes data was likely exfiltrated, and one that provides a definitive, legally sound list of every compromised asset and stolen document.
Breaking the operational silos
The development of tools like the XFRM Inspector represents more than just a technical achievement in memory forensics. It represents a necessary evolution in how we structure our incident response teams. We can no longer afford to maintain strict boundaries between network analysis, memory forensics, and malware reverse engineering. The modern threat landscape requires a fluid approach where an artifact extracted from RAM immediately informs the analysis of a packet capture, which in turn provides the network indicators needed to hunt for the malware on disk.
When regulations like the Digital Operational Resilience Act (DORA) and the NIS2 Directive demand rigorous incident reporting and demonstrable resilience, you cannot rely on guesswork. You need to provide concrete evidence of what occurred during a breach. If your security architecture relies on encryption to protect data in transit, you must also have the capability to decrypt that traffic during an investigation. Relying solely on endpoint logs is insufficient when the endpoint itself is compromised and actively manipulating the telemetry it sends to your SIEM.
The integration of memory and network forensics is not just a theoretical exercise for CTF competitions. It is a critical operational requirement. As attackers continue to hide in encrypted tunnels and memory-resident payloads, our investigative techniques must cross the same boundaries. We need host analysts who understand network protocols and network analysts who know how to read a memory dump. The tools to bridge these disciplines are finally available, and the excuse that the traffic was encrypted is no longer acceptable when the keys were sitting in RAM the entire time.