Reversing the Ransomware. Forensic lessons By Hackfreaks.
BROUGHT TO YOU BY HACKFREAKS OFFICIAL
Content of the article
In this article, we examine a malicious file using the Ransomed lab from CyberDefenders as an example . We will learn how to manually unpack the code, determine the technique for injecting malware into a process, and answer a series of questions.
We are presented with the following scenario: the organization was hacked, the SOC team found the downloaded executable file. Our task is to investigate it and develop indicators of compromise for subsequent detection.
INFO
Investigation of a malicious file must be carried out in an isolated environment. How to create a laboratory for malware analysis is described in detail in the article “ Code under supervision. We are creating a virtual laboratory for malware analysis. ”
So, we download the malware and begin to investigate it. Based on the results of solving the case, it is necessary to answer several questions, but I will only show how to solve it, and I will not give answers. It is better to repeat the whole process yourself to understand and consolidate the material.
TOOLS
To investigate a malicious file, we will use the following software.
- DIE is a program for detecting file types.
- PeStudio is a program for finding artifacts of executable files.
- IDA Pro is an interactive disassembler used for reverse engineering.
- Wireshark is a network traffic analysis tool.
- Burp Suite - used as a transparent proxy server to analyze the interaction of a malicious file via the HTTPS protocol.
- Loki Scanner is an IOCs scanner.
- YaraEditor is a program for testing and creating YARA rules.
- ApiLoger is a utility for analyzing the WinAPI functions called by the malware under investigation.
- x64dbg is an open source Windows debugger for malware analysis.
We will analyze the malicious module in four stages:
STATIC ANALYSIS
First of all, we will get the MD5 hash sum of the executable file and check it for VirusTotal . By MD5 a2f33095ef25b4d5b061eb53a7fe6548 VirusTotal gives us primary information about the executable file .
Next, we will feed the file under investigation to the DIE utility and find out which compiler and linker was used to create the malware, and also determine whether it is packaged or not.
So, we have learned that the malicious module was developed in C/C++ and compiled for 32-bit operating systems. DIE identifies the packer using downloaded signatures, but does not identify the manual packer. To do this, you need to look at the entropy of the file by sections.
INFO
What is the entropy of an executable file is described in the article Entropy. How Chaos Helps Look for Viruses .
The entropy value is 7.677, which means the file is packed. It can be seen from the figure above that the file under study has four sections, the entropy of the section .text is 7.844.
Let's load the file into the PeStudio utility to find all kinds of artifacts. We are interested in file compilation timestamps, loaded libraries, resources used, version information of the executable file, characteristic strings, as well as debug information and assembly file (Manifest). All this will be useful to us when creating a file signature.
We are interested in the string C:\moz\vidaj.pdb for creating a detection rule. At this stage, we found out that the executable file is packed, and we got characteristic strings.
Before proceeding with dynamic analysis, let's study the behavior of the malicious module. At this stage, we will identify network interaction with the control server, as well as the Windows API functions used.
Let's run the INetSim utility in a virtual machine Kali Linux. We will also run the Burp Suite to analyze the interaction over HTTPS and listen to the network traffic of the interaction using Wireshark.
Let's start Api Loger, select the executable file chalenge.exe and start writing logs.
The executable uses the function IsDebbugerPresent for the purpose of anti-debugging. Then the running process is read using the function ReadProcessMemory, the function VirtualAllocEx allocates memory and the data is written to the buffer in the process 's address space WriteProcessMemory. This mechanism is similar to the process injection technique ProcessHollowing.
Now let's look at network traffic.
As you can see from the figure above, the executable interacts with the following domains: api.2ip[.]ua, kotob[.]top, tzgl[.]org.
You Burp Suite can see the interaction over the HTTPS protocol.
To determine the IP address, the executable file makes a request to , and then downloads the executable file https://api.2ip.uafrom the resource .https://tzgl.org/files/1/build3.exe
As we remember, INetSim has stub files. After a request to the tzgl.org downloaded file build3.exe is launched.
Since we have assembled a laboratory for analyzing malicious files, in our case, a stub file for the INetSim utility is loaded. An HTTP request to the resource was also detected tzgk.org.
Using the Process Hacker 2 utility, let's examine the behavior of a running file.
As you can see from the figure, the process challenge.exe starts child processes build2.exe and build3.exe, which, in turn, start conhost.exe.
Next, all files that are assigned the extension .shgv. At the end of each encrypted file, the same structure is stored, which contains the identifier and data in the base64.
At this stage, we have identified the network interaction of the malicious file, and also discovered the technique of injecting into the Process Hollowing process.
Malicious authors often use the Windows API functions to allocate memory in order to further load a payload into this place that will unpack the executable code. So, our task is to detect this piece of code and find out what privileges were given to it. Next, we will go through the code step by step in search of the unpacking function.
After downloading the file, press F9 and get to the entry point of the executable file.
We are interested in the VirtualAlloc function , whose main task is to allocate memory in the process address space.
To do this, press Ctrl + G, type VirtualAlloc and go to this section of code.
Set a breakpoint at the input to this function (F2 key).
We go down step by step below (F8), find the exit section of this function and get to the next section of the code.
After exiting the function , the address of the allocated memory is stored VirtualAlloc in the register . EAX 029E0000The function then call 2836512 writes code to the allocated address space, the instruction jmp dword ptr ss:[ebp-4] is used to pass execution to the shellcode. Let's stop at this instruction, right-click, select the transition to the memory card and see what rights are used for the allocated memory at ss:[ebp-4].
As you can see from the figure above, the allocated memory has ERW read, write, and execute permissions. Next, we get to the section of executable code at the address allocated using the Windows API function VirtualAlloc.
Here, the malicious code obtains the addresses of functions in the libraries user32.dll, kernel32.dll, ntdll.dll.
If you scroll down, 16 functions are loaded from the kernel32 library: WinExec, CreateFile, WriteFile, CloseHandle, CreateProcessA, GetThreadContext, VirtualAlloc, VirtualAllocEx, VirtualFree, ReadProcessMemory, WriteProcessMemory, SetThreadContext, ResumeThread, WaitForSingleObject, GetModuleFileNameA, GetCommandLineA.
Let's talk about the method that the malware uses to hide strings from the explorer - Stack Strings. The main idea behind this method is to push the string onto the stack one character at a time. Usually, a block of memory is allocated for this, then, using an instruction, MOV a character is placed in the allocated area.
After that, the malware calls the RegisterClassExA function , and then confuses two lines - saodkfnosa9uin and mfoaskdfnoa. Go down below in the code, and you will see the described process.
During behavioral analysis, we found that after running the file, a child process is created, into which execution is transferred, and the functions , , , , and kernel32.dll are loaded from the library . This means that the malicious module uses the Process Hollowing technique.CreateProcessAVirtualAllocExGetThreadContextWriteProcessMemorySetThreadContextResumeThread
This is the name of one of the popular methods of injecting malicious code into process memory. To achieve this, the malware removes legitimate code from the memory of the target process and overwrites this memory space with its executable file.
First, the malware creates a new process in suspended mode with the ( ) and ( ) CreateProces flags . The main thread of the new process is in a suspended state and is waiting for the function to be called . The target process's memory is then disabled using either and the contents of the legitimate file are replaced with the malicious payload.CREATE_SUSPENDED0x00000004CREATE_NO_WINDOW0x08000000ResumeThreadZwUnmapViewOfSectionNtUnmapViewOfSection
Now that the memory is disabled, the loader allocates new memory for the malicious code with VirtualAllocEx and uses WriteProcessMemory to write each of the malware sections into the target process space. Next, the malicious module calls SetThreadContextto point the entry point to the new section of code it has written. At the end, the malware resumes the suspended thread by calling ResumeThreadto bring the process out of the suspended state.
We go down the code using the key F8and get to the next section of the code.
The register ECX contains the address of the CreateProcessA function , which is executed with the parameter dwCreationFlagsequal to 0x08000004.
The next step is to allocate memory using the VirtualAlloc.
Memory is allocated at 001F0000. Let's move on to the dump and see that it is still empty.
The next step calls the GetThreadContext function to get the thread context.
The ReadProcessMemory function is called to get a process handle.
The ZmUnmapViewOfSection function is called , which unmaps the target process's memory.
Finally, the VirtualAllocEx function is called to allocate memory for the malicious module.
The called function has five arguments, which we see on the stack: a process handle, a pointer to the address of the code area, the size of the allocated area, the type of memory allocation, and the memory protection for the allocated area. As you can see from the stack, the parameter 0x00003000 means MEM_COMMIT (0x00001000) | MEM_RESERVE (0x00002000). The value 0x00000040 (PAGE_EXECUTE_READWRITE) tells us that execution, write and read access is allowed in the selected area.
The address 0x00400000 indicates the address where the malicious code will be located. Next, the NtWriteVirtualMemory function is called .
The call occurs with the following parameters presented on the stack.
The value 0x00000270 is the handle to the process, 0x00400000 is the base address to write to in the specified process, 0x29915A0 is the address of the buffer that contains the content to write to the process's address space, 0x00000400 is the size to write to the process.
Here, the malicious code writes each segment of the executable file to a new address space. Below is the contents of the stack each time the function is called NtWriteVirtualMemory.
We go down below and see the execution of the WriteProcessMemory function , which is used to write from the buffer to the address space of the process.
The stack contains the following data.
The value 0x029016EC is the address that contains the data to write.
The SetThreadContext function is then called to create a context for the specified thread, and the ResumeThread function is called to resume the new executable.
Before executing the function, ResumeThread we will get a dump of the created process. To do this, we will use the ScyllaHide plugin . Click on the "Modules → Scylla" tab.
The next step is to analyze the unpacked code in IDA Pro, which has a convenient plugin HexRays for decompiling the code. It is necessary to find a key generation code for encrypting files and an encryption algorithm, but such a study is beyond the scope of our article.
At the current stage, we managed to unpack the malicious module, we figured out the technique Process Hollowing in the code. Now we need to develop indicators of compromise.
Let's create a simple YARA rule for malware detection. When creating signatures for this ransomware family, it is necessary to analyze many files and find common parts of code and lines. And for this, the useful mkYARA plugin in IDA Pro can come in handy.
description = "Detect malware ransomware"
uint16(0) == 0x5A4D and all of them
We will also write indicators of compromise (IOCs) that can be loaded into Loki Scanner and Suricata.
- MD5: a2f33095ef25b4d5b061eb53a7fe6548
- SHA1: b38a8cb06507adb966dfdb809403f8f7f64ca534
- URLs: https://api[.]2ip[.]ua
,https://tzgl[.]org/files/1/build3.exe,http://tzgl[.]org/fhsgtsspen6/get[.]php? pid=AD4334DBE387EF198B77CC7408B38C8F&first=false` - Domains:
api.2ip.ua,kotob.top,tzgl.org
CONCLUSION
In this lab, we unpacked a malicious file and examined its behavior. During the dynamic analysis, we disassembled the technique of introducing into the Process Hollowing process, developed our own indicators of compromise. We found out that the malicious file belongs to ransomware whose main task is to encrypt important data in order to demand a ransom.
READ MORE PAID ARTICLE FOR FREE : HERE