My first steps into Memory Forensics
"Memory Forensics is a practice useful in areas like incident response, malicious code analysis, network security, threat intelligence gathering.
Each function performed by an operating system or application results in a specific modifications to the computer’s memory (RAM), which can often persist a long time after the action, essentially preserving them.
Memory Forensics provide unprecedented visibility into the runtime state of the system, such as which processes were running, open connections, and recently executed commands."
I've written this blog post to introduce some fundamental skills in Memory Forensics. Over the past year, I’ve explored various tools and techniques for hunting malware in memory dumps, gaining insights into memory virtualization and the critical relationship between an operating system and its hardware.
As part of this article, I’ve included a hands-on tutorial on using the Volatility Framework to analyze Windows processes and detect potential malicious activity.
Before diving into the tools and techniques used in Memory Forensics Analysis, it's crucial to understand one of its core challenges: the Semantic Gap.
The semantic gap refers to the challenge of translating raw memory data into meaningful high-level information, such as active processes, open files, and network connections. Since memory captures only low-level representations of data structures without explicit context, forensic analysts must reconstruct the missing semantics to make sense of what is happening on a system.
One of the main difficulties is the complexity of raw memory data. Memory dumps contain unstructured and fragmented information, requiring deep system knowledge to interpret correctly. Unlike disk forensics, where data is relatively static, memory is highly volatile and constantly changing. This means that crucial forensic artifacts can be overwritten or lost, making it harder to reconstruct past system states.
Another challenge comes from the fact that each operating system, and even different versions of the same OS, has unique memory structures. This means that forensic tools must be frequently updated to accommodate changes in system internals. Additionally, attackers and malware developers use advanced techniques to obscure their presence in memory. Rootkits, direct kernel manipulation, and encryption can make it difficult to identify malicious activity or hidden processes.
Interpreting memory also requires mapping virtual memory addresses to physical memory locations, which is a complex task due to modern memory management techniques. Virtual memory allows processes to operate in an isolated space, meaning that forensic tools must accurately reconstruct these mappings to make sense of the data.
So, a Memory Dump is an unstructured stream of bytes and reading this piece of binary code is complex and it requires a lot of knowledge about how hardware and operating system works. But luckily someone spent a lot of effort to create a powerful framework to read memory dumps and, using different plugins, then obtain meaningful and readable data out of it:
before we jump into practice, let's learn some basics about how memory works in modern operating systems.
- DLLs: shared libraries that were loaded into the address space, either intentionally by the process or forcefully through library injection
- Environment Variables: stores the process’ environment variables, including paths, temp dirs, home folders..
- Process Environment Block (PEB): important structure that tells where to find several of the other items in the list
- Heaps: area containing the majority of the dynamic input that the process receives, including keystrokes or data received via network
- Thread stacks: dedicated range of process memory set aside for its runtime stack. It includes arguments, return addresses and local vars.
- Mapped Files and Application data: content from files on disk or any application data that the process need to perform its duties
- Executable: Primary body of code and read/write variables for the application
A process handle is an abstract reference that allows a process to interact with system resources such as files, registry keys, threads, or even other processes. Rather than granting direct access to these objects, the operating system provides handles as controlled access points, ensuring security and resource management.
So, A handle is a reference to an open instance of a kernel object, such as a file, restry key, mutex, process, or thread. By enumerating and analysing the specific objects a process was accessing at the time of a memory capture, it is possible to arrive at relevant conclusions
Now that we learned some basic concepts on how memory works, let's go hunt for malware in memory using Volatility Framework 3 Developer version
pip install volatility3
vol.py -f [dumpfile] windows.pslist
Carefully reading the output, identify your suspicious process and the related Process ID (PID). Our suspicious PID is 3652
Please note: Identifying the PID of a potential malicious process is essential to move to the next stages, but memory forensics analysis could begin from different starting-points to make assumptions, every person could approach differently, but for sure there are common hot areas to hunt for malware in memory, like:
- Recover command lines and process paths
- Analyse Heaps
- Inspect Environment Variables
- Detect Backdoors with standard handles
- Enumerate DLLs
- Extract PE files from memory
- Detect code injection
vol.py -f [dumpfile] windows.handles --pid 3652
- Mutexes: Mutual exclusion in memory ensures that multiple processes or threads do not access the same resource simultaneously in a way that causes conflicts or data corruption. It is achieved using synchronization mechanisms like locks, semaphores, or atomic operations to enforce exclusive access. A mutex value can be considered an IOC for known malware families
- Registry Access: Accessing and manipulating certain Registry Keys can lead to known techniques and methodologies of different attack stages
- Network Sockets: Presence of ALCP Port handle means that the process is accessing the kernel object to use the network stack of the system, so it is creating connections from some purposes
- Disk Access: a "File" handle might refer to file read\write to disk or Device and DLL access
- Timer queue: Using timers to avoid detection will generate different handles like TpWorkerFactory, IRTimer or WaitCompletitionPacket.
vol.py -f raw2.mem windows.netscan | FINDSTR "3652"
Using this IP intelligence information, I found the host 95.143.190.57 in the Russian Federation, recognized as malicious by different Vendors and Public Threat Intelligence Platforms and related to different RATs and Stealer campaigns.