Talk With an Expert

The Analysis of User Data In VADs: Extraction of Precise Data in Notepad Memory And Hunting For Malware Behavior

Authored byAbdelrhman Mohamed
Abdelrhman Mohamed

This blog was coauthored by Nithin Chenthur Prabhu and Abdelrhman Mohamed.

Notepad is a common tool for windows users to jot down important notes or messages quickly. Beyond text files, Notepad can also open files in various known and unknown formats. However, over the years, adversaries have exploited Notepad as part of their malicious strategies, sometimes even disguising their activities by masquerading malicious processes as Notepad.

Given this trend, it’s important to understand what resides in Notepad’s process memory region. Advanced Persistent Threats (APTs) like Cozy Bear, Double Dragon, and Lazarus have utilized Notepad for process injection, DLL sideloading, shellcode or payload injection, and process hollowing.

We will look into methods for extracting user data from Notepad’s process memory and analyzing it for signs of malicious behavior.

To being our tests, we’ll use a Windows 10 virtual machine as a test environment. We launched Notepad and typed: “Abdelrhman and Azr43LKn1ght”.

If necessary, we can close Notepad, as its process will remain in memory for a short time. The first step is to capture the workstation’s memory using tools like FTK Imager’s Memory Capture, DumpIt.exe, or Magnet RAM Capture.

If the memory dump is not in .dmp format, it must be converted for compatibility with WinDbg. Tools like Volatility and MemProcFS can assist with this conversion. Once the memory dump (e.g., <file>.dmp ) is ready, we can process to debug it using WinDbg to analyze the captured Notepad process for signs of malicious behavior.

Before diving into the analysis, let’s examine the structure of memory in Windows. The operating system uses the _EPROCESS structure to represent a process. Each process has its own linear address space, called the Virtual Memory Space or Virtual Address Space, which is completely isolated from other processes.

This address space includes several key components:

  • The core process executable: The main binary file of the process.
  • Loaded modules: A list of all associated Dynamic Link Libraries (DLLs) an shared libraries.
  • Process stack: Memory used for function calls and local variables.
  • Process heaps : Memory areas for dynamic memory allocation.
  • Virtual Address Descriptors (VADs): Regions of memory allocated by the process.

The structure of _EPROCESS is:

The PsActiveProcessHead is a global kernel variable that holds the address of the first process in the list of active processes.

The Process Environment Block (PEB) is a pointer in kernel mode that references an address in user mode. It holds critical information about a process, including:

  • Pointers to the process's DLL lists.
  • The current working directory.
  • Command-line arguments.
  • Environment variables.
  • Details of heaps.
  • Handles for standard input/output streams.

VadRoot is the root node of the VAD tree. The VAD tree holds detailed information about all memory segments allocated to a process. This includes the original access permissions which are read, write, or execute and whether a file is mapped to the memory region.

To begin analyzing the Notepad process, we first nee to locate the _EPROCESS block associated with notepad.exe. This can be achieved using the !process command in WinDbg:

!process 0 0 notepad.exe

The !process extension provides information about the specified process or all processes, including the _EPROCESS block. Here’s a breakdown of the command argument:

  • First 0 argument specifies the process option, which in this case is set to 0, meaning "all process contexts."
  • Second 0 argument specifies the "flags" parameter. A flag value of 0 means "minimal output."

We now know the _EPROCESS block’s address of notepad.exe is ffff8701845ce340

.process /r /p ffff8701845ce340

This command sets the debugger’s context to the specific process, notepad.exe. The /r switch tells WinDbg to reload the user-mode symbols and modules for the specified process. The /p switch forces the debugger to synchronize its process state with the target, halting the process execution to provide an accurate view of its memory and current state.

Before looking at the VAD tree, let’s first look at the PEB.

The -s flag provides a summary of all the heaps, including details like total size, number of segments, number of blocks, and other statistics. This flag is useful for getting an overall picture of the heap usage in the process.

The -v flag is used for more detailed output to the command, such as specific heap flags, debugging information, and metadata about each heap. This level of detail can help in understanding the state and properties of each heap in-depth.

The -a flag is used to display all memory blocks allocated in the heap, including their sizes, addresses, and other properties. This is useful for finding patterns, such as unusual memory blocks or potential injected code.

Now we can look into the heap we analyzed.

0000021f6a060740  0000021f6a060750  0000021f6a060000  0000021f6a060000        30       740        10  busy

0000021f6a060770  0000021f6a060780  0000021f6a060000  0000021f6a060000        20        30         0  free

0000021f6a060790  0000021f6a0607a0  0000021f6a060000  0000021f6a060000        20        20        10  busy

This will be the same as the size and allocations we calculated.

We also have to parse all the subsegments. The offset of LFH Heap will be in the same heap's FrontEndHeap, which is 0x21f69dc0000.

dt _LFH_HEAP 0x21f69dc0000

Now, let’s look at the heap contents. For this we can use db 0000021ef85b2ad0 L80.

Now, we have successfully extracted the desired information from memory! This method can be applied to any file opened in notepad.exe, making it straightforward to recover any file opened in notepad.exe from a memory image.

Now, let’s make a custom notepad-like application. This will provide better understanding of heap allocations.

Let’s do that on real malware with the malware sample of brbbot.exe.

1 Find Process _EPROCESS (core).

2 Set Debugger Process context.

3. Now, let’s look into all the heap allocations.

As this is an actual malware process without any user defined heap allocations, we need to check all heaps associated with the process, not just the user_flag or extra heaps. The first heap address is 0000000001300000, and last heap address is 00000000016f5fd0. It’s better to view all the contents of the particular heap allocation. To do this, we can use the WinDbg command: db 0000000001300000  L 80000.

Further analysis on the malware’s heap allocations shows that it maintains a network connection with the threat actor’s server. During its execution in the system’s background, the malware sends encrypted data to the attacker’s server.

Takeaways and Applications

In this blog post, we explored heap memory management within Windows, focusing on the structure and functionality of _HEAP_ENTRY and the significance of its various flags in determining the state of memory allocations. We learned:

  • What is heap memory allocation in Windows and how it is managed.
  • The structure of process memory in Windows.
  • How to manually analyze heap allocation and subsegment allocations.
  • The process of decoding _HEAP_ENTRY and understanding its associated flags and their uses.
  • The role of heap protections and how to analyze user-defined and program-defined heap allocations.

The ability to manually parse heap allocations allows for deeper insights into application behavior. This understanding enables more informed decisions regarding reverse engineering and digital forensics and incident response (DFIR) analysis of malwares and other Windows applications.

As we continue to navigate the complexities of memory management, the insights gained from these structures will remain invaluable for enhancing Windows core analysis skills.

Explore more and stay ahead in the ever-evolving field. Join the SANS Community today to stay connected to the latest insights and innovations.