Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

© SANS Institute 2018

CourseE x aRoadmap
m in ing S e l f - Def en di n g Mal war e

FOR610.1: Malware Analysis


Debugger Fundamentals
Detection and Data Protection
FOR610.2: Reversing Malicious Code
Unpacking Process Hollowing
FOR610.3: Malicious Web and
Detecting the Document Files
Analysis Toolkit
FOR610.4: In-Depth Malware Analysis
Handling Misdirection Techniques
FOR610.5: Examining Self- Defending
Unpacking Malware
by Anticipating Actions
FOR610.6: Malware Analysis Tournament
Appendix: More Unpacking by Anticipating
FOR610 | REVERSE-ENGINEERING MALWARE38
Actions

We're in Section 5, Examining Self-Defending Malware, of the FOR610 course. Our next module is titled
Unpacking Process Hollowing.

38
© SANS Institute 2018

Unpacking Process Hollowing

FOR610 | REVERSE-ENGINEERING MALWARE39

In this course module, we will examine a powerful technique that builds upon the core process injection
methods and introduces a few nuances that you need to be able to handle when examining malware. This
technique is one of the many approaches malware authors use in an attempt to protect their code from
detection and analysis.

© 2018 Lenny Zeltser 39


© SANS Institute 2018
Take a look at WinHost32.exe by starting with behavioral analysis.

A suspicious file WinHost32.exe was discovered on an enterprise system


EXERCISE 5.4 in the user %Use
Start the Windows and Linux VMs and revert to clean snapshots.
Extract WinHost32.exe from day5\winhost32.zip and place it in C:\Users\REM on your W
Use Wireshark, Process Hacker, Process Monitor, and ProcDOT to get a sense of the spec
▫ What network and process activities catch your interest?
▫ We won't spend a lot of time on this, because our later focus will be on code analysis, but these steps form a reasona

FOR610 | REVERSE-ENGINEERING MALWARE40

Before we take a close look at the primary subject of this course module, let's become familiar with the
specimen called WinHost32.exe from the behavioral perspective. We will examine several aspects of this
malicious program from the code perspective, but let's observe its infection behavior to understand what
actions it takes when it begins running on a system. This file was discovered on an enterprise system in
the victim's %UserProfile% folder.

To start, please make sure your Windows and REMnux virtual machines are active. Revert them to clean
snapshots, if necessary, to restore their pristine state. On your Windows REM Workstation, please
extract contents of the day5\winhost.zip file. Place the WinHost32.exe file contained in that archive into
the
%UserProfile% folder on your Windows system, which is C:\Users\REM. Because the sample was
initially found in the %UserProfile% folder, it's best to put it in the same location when infecting the
laboratory system.

Launch Wireshark on REMnux by running wireshark & in the terminal window. On Windows
REM Workstation, launch Process Hacker. Then, launch Process Monitor, direct it to pause capture
(Ctrl+E) and clear its log (Ctrl+X).

The upcoming slides provide step-by-step instructions for observing the specimen's effects on the system.
If you don't need that level of guidance, feel free to spend a few minutes performing these steps on your
own. You'll need to activate the monitoring tools, infect the system, and allow the specimen to run for at
least half a minute or so. When ready, stop your monitoring tools. Export the Process Monitor log in
CSV format, and then load it in ProcDOT and review the resulting graph. Also, take a look at the
network activities captured by Wireshark. Overall, what network and process activities catch your
interest?
40 © 2018 Lenny Zeltser
© SANS Institute 2018
Infect your Windows REM Workstation with WinHost32.exe.

Start Wireshark on REMnux and activate capture.


Start Process Hacker and Process Monitor on the Windows VM and activate capture in Pr
Double-click on WinHost32.exe to infect the Windows VM.
Terminate the WinHost32.exe process after about half a minute.
Pause capture in Process Monitor and Wireshark.
Export the Process Monitor log in CSV format and load the file into ProcDOT.
Examine the Wireshark log and the ProcDOT graph.
FOR610 | REVERSE-ENGINEERING MALWARE41

Start Wireshark on REMnux. Activate its capture capabilities by pressing Ctrl+E.

On your Windows VM, start Process Hacker. Also, start Process Monitor and allow it to start capturing
events. Then, double-click on WinHost32.exe to infect your Windows REM Workstation.

Process Hacker will show WinHost32.exe as an active process. Allow the specimen to run for about half
a minute, and then terminate it using Process Hacker.

Pause capture in Process Monitor (Ctrl+E) and Wireshark (Ctrl+E).

Export the Process Monitor log in CSV format and load it into ProcDOT. Instructions for accomplishing
this are in the upcoming slides. Examine the graph that ProcDOT generates.

Examine the Wireshark log; you should see that the infected system attempted to use DNS to resolve the
hostname google.com.

© 2018 Lenny Zeltser 41


© SANS Institute 2018

FOR610 | REVERSE-ENGINEERING MALWARE42

The screenshot on the top of this slide shows the active WinHost32.exe process in Process Hacker, which
appeared after the specimen was executed on the Windows virtual machine. To terminate it, right-click
on its listing in Process Hacker and select Terminate (Del).

The Process Monitor screenshot on this slide resembles what you should see after directing this tool to
pause capture. After pausing the capture, select File > Save… (Ctrl+S), and select Comma-Separated
Values (CSV) as the format, as shown on this slide. Select the path that allows you to easily locate the
resulting file, such as the Desktop folder. Then, click OK.

42 © 2018 Lenny Zeltser


© SANS Institute 2018

FOR610 | REVERSE-ENGINEERING MALWARE43

Before leaving Process Monitor, take a look at the summary of the processes that left their "footprint" in
the tool's log when the specimen was active on the system. To do that, select Tools > Process Tree…
(Ctrl+T) in Process Monitor. You will see the window that resembles the one shown on this slide.

Note that there were, apparently, two WinHost32.exe processes. The first one, with process ID 6120, ran
for a relatively short time. It spawned a child WinHost32.exe process, which was assigned process ID
4592. (On your system, process IDs will probably be different.)

© 2018 Lenny Zeltser 43


© SANS Institute 2018
1 2

FOR610 | REVERSE-ENGINEERING MALWARE44

Next, open ProcDOT on your Windows REM Workstation. Load the CSV log file that you saved from
Process Monitor into ProcDOT. To do this, press the "…" button in the Procmon area. This is shown
as step 1 on this slide.

After loading the file, click the "…" button in the Launcher area, as shown in step 2.

Select the WinHost32.exe instance whose PID corresponds to the process ID you saw in Process
Monitor's Process Tree as the first malicious process. In our example, that's PID 6120, but your process
ID will probably be different. Double-click on that entry, as shown in step 3.

Finally, click the Refresh button in ProcDOT, as shown in step 4, to generate the graph.

44 © 2018 Lenny Zeltser


© SANS Institute 2018
The specimen launched a child instance of itself and attempted to resolve google.com durin

4752
[1] [2]
WinHost32.exe (PID: 6120) 2196 WinHost32.exe (PID: 4592)

FOR610 | REVERSE-ENGINEERING MALWARE45

The top of this slide shows the graph that ProcDOT generated to summarize the infection activities
captured in the Process Monitor log. Although the specifics of your graph might be slightly different, you
should see the initial WinHost32.exe instance launching a child process with the same name. Your graph
might also display some registry activities associated with the child process, which you might have
investigated if you had more time, and determined that they were false positives.

The bottom of this slide shows the relevant excerpt from the Wireshark log. The infected system
initiated a DNS query, attempting to resolve the hostname google.com. Because we didn't have a DNS
server in our environment, it received the Destination unreachable (Port unreachable) response. (The IP
addresses in your lab will probably be different from what's captured on this slide's screenshot.)

© 2018 Lenny Zeltser 45


© SANS Institute 2018
Why did the specimen bother launching a child process, rather than simply running under

Terminate the specimen if it's still running and exit the behavioral tools, so we can contin
Load WinHost32.exe in IDA and examine the code that it uses to launch a process to spot
Use the Imports tab to spot the CreateProcessA reference, and then locate the code that m

EXERCISE 5.5

FOR610 | REVERSE-ENGINEERING MALWARE46

Our observations showed that the specimen replaces its original WinHost32.exe by a child instance of
what appears to be the same process. This behavior seems a bit strange and unusual. What benefits does
the malicious program derive from performing this action? Let's investigate how WinHost32.exe
launches the process in case, at the code level, we come across anything interesting.

Terminate the malicious process, if you haven't done so already, and exit the tools you used to perform
behavioral analysis.

Then, load WinHost32.exe in IDA and locate the code that the specimen uses to launch a process. If you
navigate to IDA's Imports tab, you will notice a reference to CreateProcessA, which allows programs to
launch processes. The steps to locate the code that makes this API call are documented on the next slide,
but if you already know how to proceed, do so before turning the page.

46 © 2018 Lenny Zeltser


© SANS Institute 2018
"4" as the dwCreationFlags parameter to CreateProcessA corresponds to CREATE_SUSP

FOR610 | REVERSE-ENGINEERING MALWARE47

Double-click on the CreateProcessA line in the Names tab shown on the previous slide. IDA will bring
you to the area in the program shown on the top of this slide. Click on CreateProcessA to highlight it
and press the "x" key. IDA will bring up the xrefs window shown on the top-right of this slide. Though
the window shows two lines, both mention the same address, indicating that CreateProcessA is actually
called from a single location in the program. Double-click on any of the two lines in the xrefs window
to go to that location.

IDA will bring you to the part of the program shown in the bottom half of this slide. The call to
CreateProcessA takes place at offset 4021A2. You might need to scroll up a bit to see all the parameters
that the program supplies to this API call.

Note the dwCreationFlags parameter, which is being pushed to the stack at 40218C. Its value is being set
to 4. According to Microsoft's documentation, this value corresponds to the flag
CREATE_SUSPENDED. When invoked this way, CreateProcessA will launch the process such that its
primary thread is "created in a suspended state and does not run until the ResumeThread function is
called." (See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx.)

Launching a process in a suspended state is not a common occurrence and contributes to the pattern we
will continue to explore over the next few slides.

© 2018 Lenny Zeltser 47


© SANS Institute 2018 What's being invoked via EDI?

A bit further in the code, we see calls to VirtualAllocEx and WriteProcessMemo

FOR610 | REVERSE-ENGINEERING MALWARE48

Scroll down a little in the code after the call to CreateProcessA, looking at CALL instructions.

Specifically, note that at 40220D, the specimen calls VirtualAllocEx. As we covered earlier in the course,
the value of 0x40 being supplied to this API call via the flProtect parameter stands for
PAGE_EXECUTE_READWRITE. (See https://msdn.microsoft.com/en-
us/library/windows/desktop/aa366786.aspx.)

Also, at 402237, there is a call to WriteProcessMemory; the specimen accomplishes this by invoking the
function whose address is in the EBP register after moving the address of WriteProcessMemory into
EBP at 40221E.

The use of VirtualAllocEx together with WriteProcessMemory in this manner is consistent with the code
injection pattern we covered earlier in the course.

Shortly before the call to VirtualAllocEx, the specimen includes the instruction call edi at
offset 4021F7, as captured on the top of this slide. Let's determine which function is being invoked
by this instruction.

48 © 2018 Lenny Zeltser


© SANS Institute 2018
Scroll up to see what's written into EDI to investigate which function the specimen calls via

Scroll up, looking for the nearest instruction that specifies the EDI register as its destinat
You'll see mov edi, eax at offset 40214F, which saves the result returned by GetProcAd
The function name that GetProcAddress is resolving is NtUnmapViewOfSection, which w

FOR610 | REVERSE-ENGINEERING MALWARE49

The previous slide showed the instruction call edi at offset 4021F7. Click the EDI register on that
line to highlight it, and then scroll up in IDA to locate the nearest instruction that specifies EDI as its
destination register. You will encounter mov edi,eax at offset 40214F, shown on the top of this slide.
To establish what function is being executed by call edi, we need to determine what is being placed
into EDI by this MOV instruction.

Prior to mov edi,eax, we see a call to GetProcAddress. After this call, EAX contains the result
returned by GetProcAddress, as is common with most functions. GetProcAddress determines the address
of the specified function exported by the specified DLL. Knowing this address allows the program to
execute the function. According to Microsoft, this API call requires two parameters outlined below. (See
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212.aspx.)

1. The hModule parameter is the handle to the DLL where the function is implemented. A
program can obtain this handle by calling LoadLibrary.
2. The other parameter, called lpProcName, is the name (or ordinal value) of the function that
the program wants to locate. In most cases, this is a string that represents the function's name.

Prior to the GetProcAddress call, the specimen invokes LoadLibraryW. This API call, which loads the
designated DLL and returns a handle to the DLL, requires the path to the DLL as the parameter. Our
specimen supplies this parameter by pushing the pointer to the string "ntdll.dll" at 40213D. This API call
returns the handle to the loaded DLL in the EAX register, which is pushed to the stack via the instruction
at 402148 as the hModule parameter.

The instruction at 402138 pushes the pointer to the string "NtUnmapViewOfSection" to the stack. This
corresponds to the lpProcName parameter that GetProcAddress will use. That means that
GetProcAddress will return in EAX the address of the NtUnmapViewOfSection function, which the
program will move to EDI and execute at 4021F7 via the instruction call edi. The malware author
probably loaded this DLL and located this function during runtime to avoid having it appear in the
malicious file's import table.

© 2018 Lenny Zeltser 49


© SANS Institute 2018
The API calls we observed form the code injection pattern known as process hollowing, pro

CreateProcess or its variations: Launches a suspended child process; which program th


NtUnmapViewOfSection or ZwUnmapViewOfSection: Deallocates (hollows out) v
VirtualAllocEx or its variations: Allocates memory space in the child process to make r
WriteProcessMemory or its variations: Writes (injects) new code into the new allocate
ResumeThread: Awakens the child process to run injected code.

FOR610 | REVERSE-ENGINEERING MALWARE50

The API calls we just observed in WinHost32.exe contribute to a stealthy code injection pattern known
as process hollowing, process replacement or RunPE. This technique is described in the book Malware
Analyst's Cookbook (http://www.malwarecookbook.com) in the chapter "Memory Forensics with
Volatility." The book's authors explain that in this technique, malware launches a process in a suspended
state, and then deallocates the memory containing that program's code (hollows it out), and replaces it
with the body of the new malicious program.

The key API calls used to accomplish this are outlined on this slide. In addition, before calling
ResumeThread, this technique requires the specimen to make call GetThreadContext (or its variations
NtGetContextThread/ZwGetContextThread) and SetThreadContext (or its variations
NtSetContextThread/ZwSetContextThread) API calls before calling ResumeThread. Three APIs direct
the new thread to execute code starting with the beginning of the injected contents. You can see these
API calls in our specimen as you scroll toward the call to ResumeThread at 4022CA.

Although the launched process ends up executing the code that was just injected into it, an analyst
taking a cursory look at that process might mistake it for the original program. Process hollowing can
conceal malicious code inside processes that appear legitimate to hide malware. To accomplish this,
malware would spawn a legitimate program, for instance, csrss.exe, hollow it out, and replace its code
with malicious code. This method could also be used for stealthy unpacking, which is probably what is
happening in the case of WinHost32.exe.

For additional information about this injection technique, see:


• https://trustwave.com/Resources/SpiderLabs-Blog/Analyzing-Malware-Hollow-Processes
• http://autosectools.com/process-hollowing.pdf
• Practical Malware Analysis, Chapter 12, by Michael Sikorski and Andrew Honig

50 © 2018 Lenny Zeltser


© SANS Institute 2018
We can think of process hollowing as the specimen unpacking code into another (temporar

To unpack a program, we can allow it to extract its code and dump it from memory as it p
A practical way to do that with process hollowing is to set a breakpoint on the call to Writ
Dump memory contents that the specimen injects into its child, which is the lpBuffer para
In preparation, note the address of the WriteProcessMemory call in IDA (402237), so you

FOR610 | REVERSE-ENGINEERING MALWARE51

One way to think about process hollowing is to view it as a way for the specimen to unpack code into
another (temporarily suspended) process, rather than extracting this code into its own memory space. A
practical way to unpack such malware to obtain the unpacked code is to extract it from memory by
catching the specimen after it completes the unpacking and before it has the opportunity to execute the
unpacked code. This approach, at a high level, is consistent with the unpacking methodology we
discussed in an earlier section of the course.

To catch the specimen at the right moment, we can use a debugger to set a breakpoint on the call to
WriteProcessMemory. One of the parameters to this API call (the third one) is named lpBuffer, which
specifies a "pointer to the buffer that contains data to be written in the address space of the specified
process." (See https://msdn.microsoft.com/en-us/library/windows/desktop/ms681674.aspx.) We can see in
IDA that the specimen pushes this parameter to the stack at offset 402234 shortly before calling
WriteProcessMemory at 402237.

After setting the breakpoint at that call to WriteProcessMemory, we'll run the specimen in the
debugger, giving it the opportunity to unpack its code and, presumably, place it into lpBuffer. We will
then use the debugger to extract (dump) that unpacked code from memory.

© 2018 Lenny Zeltser 51


© SANS Institute 2018
Pause the specimen before it calls WriteProcessMemory.

Load WinHost32.exe from C:\Users\REM into x32dbg.


Use Ctrl+G to go to 402237, where you'll find call ebp that invokes WriteProcessMemo
Set a breakpoint there via right-click, Breakpoint > Toggle (F2).

Then, run to reach the breakpoint via Debug > Run (F9).

FOR610 | REVERSE-ENGINEERING MALWARE52

Minimize IDA. Load WinHost32.exe from C:\Users\REM into x32dbg. As expected, the debugger will
pause at the specimen's entry point, giving you a chance to set breakpoints.

Based on the analysis we performed in IDA in the previous slides, we know that the call to
WriteProcessMemory where we wish to set a breakpoint is at 402237. Go there by pressing Ctrl+G,
typing "402237" and pressing OK. You will find yourself in the code shown in the top screenshot on this
slide. As we saw earlier, the specimen uses call ebp to invoke WriteProcessMemory at 402237.
Right- click on that line and select Breakpoint > Toggle (F2). The debugger will highlight the offset of
this instruction to indicate that the breakpoint has been set.

By the way, if we didn't know the address of the call to WriteProcessMemory, we could use the
debuggers SetBPX command to set a breakpoint at the beginning of the WriteProcessMemory function,
as we've done earlier in the course with other API calls.

After setting a breakpoint on offset 402237, run the specimen by selecting Debug > Run (F9) in x32dbg.
WinHost32.exe will begin executing and pause after reaching the breakpoint. At this point, your screen
will resemble the screenshot shown at the bottom of this slide.

By the way, prior to debugging WinHost32.exe, you should have checked whether this file's dynamic
base flag is disabled to avoid dealing with ASLR, as we discussed in Section 4 of the course. If
necessary, you would have used tools such as CFF Explorer and setdllcharacteristics to disable dynamic
base. In this case, we didn't ask you to check for this property in the interest of saving time; the malicious
file does not have dynamic base enabled, so you don't need to disable it.

52 © 2018 Lenny Zeltser


© SANS Institute 2018
Follow the lpBuffer parameter in the debugger's Dump area.

Once x32dbg pauses on the breakpoint, select the third parameter in the area of the CPU
This parameter, represented by [esp+8], corresponds to lpBuffer.
It was supplied via push ebx prior to the call.
Right-click and select Follow […] in Dump to view memory contents.
The address in your lab might be different from the one below.

FOR610 | REVERSE-ENGINEERING MALWARE53

Once the debugger pauses on the call to WriteProcessMemory, we can look for the contents that the
specimen is attempting to write into the targeted process. As mentioned previously, these contents reside
in the lpBuffer parameter. We saw in IDA that this parameter was pushed to the stack three PUSH
instructions prior to the CALL (via push ebx). This isn't surprising, since Microsoft's documentation
for WriteProcessMemory indicates that lpBuffer is the third parameter.

Look at the region of x32dbg that's in the middle of the right side of the CPU tab. This is where the
debugger shows the arguments being passed to the function. The lpBuffer parameter is the third one. To
select it, click the parameter labeled 3, which is represented by [esp+8]. After selecting it, right click
there and select Follow […] in Dump. The memory address stored in the square brackets in your lab
might be different than the one shown on the slide.

As discussed, the contents being injected into the targeted process are stored at the address that was
pushed to the stack as the lpBuffer parameter to WriteProcessMemory. Based on what we see in x32dbg,
this parameter is 2500000 in the example captured on this slide, though the address in your lab might be
different. In the example shown on this slide, the third parameter resides at offset 19FAA0 and stores
there the memory address 2500000. Therefore, the Dump region of the CPU tab would now display
contents at 2500000, though the address in your lab might be different.

© 2018 Lenny Zeltser 53


© SANS Institute 2018
Examine unpacked memory contents that the specimen is about to inject into the child pr

The Dump region contains contents that start with a PE header.


This is the executable file being injected into the child process.
Right-click there and select Follow in Memory Map.

FOR610 | REVERSE-ENGINEERING MALWARE54

After you follow the instructions outlined in the previous slide, look at the Dump area of the CPU tab
captured on this slide. That's the region in the bottom-left corner of the CPU tab. In our example, it
shows the contents that the specimen is about to inject into the targeted process.

If you glance at the ASCII column of the Dump area, you'll notice the strings "MZ" and "This program
cannot be run in DOS mode." They suggest that this part of memory probably contains a PE header,
which is most likely a part of a normal Windows executable file. We can use x32dbg to extract this file
from memory, dumping it into the file system for further analysis.

To do that, right-click in the Dump area and select Follow in Memory Map, which will allow you to look
at information about this memory region in the debugger's Memory Map.

54 © 2018 Lenny Zeltser


© SANS Institute 2018
Extract unpacked memory contents that the specimen is about to inject into the child proce

The Memory Map will highlight the region you were viewing in the Dump area of the CPU
Right-click on that region (starts with 2500000) and select Dump Memory to File.
Save the file to the Desktop under a name winhost32-dumped.exe.

FOR610 | REVERSE-ENGINEERING MALWARE55

When the debugger brings you to the Memory Map tab, you will see information about the memory
regions that comprise the debugged process. The debugger will automatically highlight the memory
region at which you were looking in the Dump. It begins at offset 2500000, as shown on this slide, but
the address in your lab might be different. To extract that memory region's contents, right-click on its line
and select Dump Memory to File. In the dialog box that appears navigate to the folder that you can
conveniently access later, such as the Desktop, assign a name to the file that x32dbg is about to generate,
such as winhost32-dumped.exe, and click Save.

© 2018 Lenny Zeltser 55


© SANS Institute 2018
Examine the dumped file to confirm that it's unpacked.

Load winhost32-dumped.exe in PeStudio and examine key properties, such as strings and
This appears to be a valid Windows executable with interesting strings that we couldn't se
You could continue with further static and dynamic analysis.

FOR610 | REVERSE-ENGINEERING MALWARE56

After extracting the code as described in the preceding slides, you should confirm that it does represent an
executable file that appears unpacked. One way to do that is to load the winhost32-dumped.exe file in
PeStudio to perform a bit of static properties analysis.

PeStudio will succeed at parsing the file as a Windows executable, allowing you to examine its properties
such as imports, sections, and key PE header fields. When looking at the file's strings, you'll see many
unprotected risky-looking strings that were not visible in the original WinHost32.exe file, further
confirming that you're looking at an unpacked file.

One of these strings, included in the screenshot on this slide, represents several URLs that are probably
malicious. Another string that's in the winhost32-dumped.exe, though it's not visible on this slide, is
"google.com," which we observed the specimen using when we performed behavioral analysis in the
beginning of this course module. Neither of these strings was visible in the original WinHost32.exe file.

You could now continue examining the specimen by performing further behavioral and code analysis
of winhost32-dumped.exe, though we will end our analysis at this point, at least for now.

56 © 2018 Lenny Zeltser


© SANS Institute 2018
Process hollowing combines packing with code injection.

We unpacked WinHost32.exe using a combination of the unpacking and code injection-re


It's often practical to extract the unpacked code from memory when you think the specim
API calls NtUnmapViewOfSection or ZwUnmapViewOfSection indicate the likely use of p
Malware authors try to conceal these API calls, for instance, by loading them during runti

FOR610 | REVERSE-ENGINEERING MALWARE57

In this module, we learned how process hollowing works to combine packing and code injection methods
into a powerful technique that can complicate the process of detecting and examining malware. The way
in which this technique allows malware to replace contents of a process with those that are unrelated to
its original form can be quite confusing to individuals who are not familiar with process following.

Conveniently, we were able to build upon the approaches covered in earlier course sections when we
discussed unpacking and code injection to learn how to extract malicious code from memory after the
specimen had a chance to unpack it and before the code had the opportunity to execute inside the child
process.

We learned that the risky API call that malware uses to hollow out contents of its child process is
NtUnmapViewOfSection or its alternative ZwUnmapViewOfSection. We also saw other API calls that
contribute to the process hollowing pattern, such as CreateProcess, that invoked in a way that launched
the child in suspended state and ResumeThread, which "wakes up" the child process after its memory
contents have been replaced with the unpacked code.

We also saw how malware authors attempt to conceal their use of some API calls by purposefully
excluding them or the DLLs in which they're implemented from the specimen's import table. The
resulting programs need to load the DLLs, if necessary, and resolve the necessary API function names
during runtime, complicating static analysis process. This technique can be seen as yet another way in
which malware attempts to defend itself from analysts.

© 2018 Lenny Zeltser 57

You might also like