As part of my work at Blackberry Cylance, I recently analyzed malicious code embedded within WAV audio files using steganography techniques. You can see my writeup here.
Uncategorized
An Introduction To Code Analysis With Ghidra
As part of my work at Blackberry Cylance, I wrote a blog post introducing Ghidra for code analysis. You can check it out here.
Intro to Cutter for Malware Analysis
Introduction
My last blog post described an intro to radare2 for malware analysis, so it is only fair that we also cover its GUI variant, Cutter. This post will closely mirror the previous article to discuss Cutter and its usage. If you like the radare2 framework but find the command-line interface intimidating, Cutter may strike the right balance for you. Alternatively, if you are simply looking for a free graphical disassembler to perform malware analysis, Cutter is worth considering.
Installing Cutter
You can download the latest release of Cutter here. Then, simply extract it to a directory of your choosing.
I use a 64-bit Windows 10 virtual machine for my analysis, so I downloaded and ran the appropriate binary. Specifically, I’m using the Windows VM we distribute in the SANS FOR610 Reverse Engineering Malware course, so you will see references to the “REM” user in screenshots.
Analyzing a File with Cutter
Loading a binary
The first time you launch Cutter, this dialog box appears:
Beyond the typical version and About information, this window provides the opportunity to change the GUI’s theme. Clicking on the “Native Theme” dropdown allows the analyst to choose an alternative “Dark Theme.” Since dark modes/themes are all the rage these days, the latter theme is used in upcoming screenshots.
Next, we can specify the file to load into Cutter:
For this post, we will use the same Gandcab ransomware sample referenced in the last post. The sample is available here (password: malware). You can click Select to browse to the file or simply drag and drop it to this window. Then, click Open and review the Load Options:
Notice that the “Analysis” checkbox is checked by default, indicating the binary will be preprocessed – this is in stark contract to radare2, which requires the user to deliberately kick off any analysis. The sliding bar in the middle of the load options can be dragged left or right for less or more rigorous analysis, respectively. We’ll leave the default “aaa”, which generally performs a sufficient level of auto analysis. We will also leave other defaults untouched and press OK.
Once processing is complete, we see the initial window layout with a functions window and a disassembly window:
As expected, Cutter brings us to the program’s entry point, 0x4044bb.
Static File Information
Before digging into code analysis, note that the Dashboard tab provides some high level information:
While other static file analysis tools provide similar data, it is convenient to have this output readily available within Cutter.
Viewing imports
To view imported functionality, choose the “Imports” tab on the bottom:
There are many APIs we could explore, but as in the last post, we will focus on CreateToolHelp32Snapshot (not shown above). This API is used to capture a snapshot of running processes on a system. Malware often uses this snapshot to enumerate running processes and identify specific process names. To find this imported function in the import list, we can use the “Quick Filter” on the bottom and begin typing the preferred API:
Finding an API reference
Next, we will locate references to this API. First, double-click on the import above, which will take us to the entry in the Import Address Table (IAT). Next, right-click on the function name and choose “Show X-Refs” or simply hit “x” on the keyboard to view references:
The x-refs window shows two CALL instructions, which represent instructions that call CreateToolhelp32Snapshot:
Notice Cutter also conveniently includes a preview of of the reference code with a single click on each row. We could explore both references, but for this post we will only jump to the second reference by double-clicking on it. This takes us to 0x004041e9, where we see a CALL to CreateToolhelp32Snapshot:
Understanding the code
At this point, we can browse the disassembly to better understand the code. In the last post, we used radare2 commands to print summary information about the current function. One benefit of a GUI is avoiding the command-line interface, but if you’re open to launching commands on occasion, Cutter conveniently allows this by activating the console:
A text console will appear at the bottom, giving us the opportunity to enter radare2 commands. For example, we could type pdf~call to print all CALL instructions referenced in the disassembled function:
This output provides a nice summary of Windows API activity. Notice the APIs highlighted in red, which include CreateToolhelp32Snapshot, Process32First, lstrcmpiW, TerminateProcess, and Process32Next. As mentioned in the previous post on radare2, this progression of CALLs is often used to capture a snapshot of running processes, begin iterating through the list, compare process names to one or more predefined names and then terminate the process if a match is made. You may have noticed a list of process names the code is likely checking located above the CALL to CreateToolhelp32Snapshot:
Ransomware commonly checks for and terminates processes that access document files to maximize the number of files it can encrypt.
Another perspective on this code is provided via Cutter’s graph view. When viewing the code in the Dissassembly view, hit the space bar to access this alternative view. Below is an excerpt of decision points from the current function:
Focusing on the lstrcmpiW, OpenProcess and TerminateProcess CALLs in graph view provides additional insight into what happens if the program matches a process name against its predefined list. Specifically, if a string match occurs, the program will access the target process via OpenProcess and then terminate it. If a match is unsuccessful, execution will jump over the code that calls OpenProcess and TerminateProcess since those APIs are not needed.
Closing Thoughts
This article mirrored the previous post on radare2 to provide an alternative (i.e., graphical) interface for using the radare2 framework. It’s tempting to stick with one tool and sometimes uncomfortable to try others. However, even brief exposure to alternatives could be eye-opening. In the best case, you absorb a new tool or approach into your RE arsenal. In the worst, you find even more reason to love your current tool of choice.
IDA has been the gold-standard disassembler for malware analysis, but its competitors are maturing rapidly. Analysts have more options, and this means tool developers and contributors have excellent incentives to create the best tool at an affordable price. It is an exciting time to learn and perform malware analysis.
For more information on Cutter, I encourage you to explore these resources:
-Anuj Soni / @asoni
About the Author:
Anuj Soni is a Senior Threat Researcher at Cylance, where he performs malware research and reverse engineering. He is also a SANS Certified Instructor and co-author of the course FOR610:Reverse-Engineering Malware. If you would like to learn more about malware analysis strategies, join him at an upcoming SANS FOR610 course.
Intro to Radare2 for Malware Analysis
Introduction
In recent years, a variety of inexpensive or free disassemblers and debuggers have gained serious momentum, including radare2 (a.k.a. “r2”), Cutter (GUI for radare2), Binary Ninja, Hopper, and x64dbg. If you have a license for IDA Pro and are happy with the experience, you may have little reason to explore other options. However, if you are still in the early stages of your career in malware analysis, or you are working with a small budget, you may not have access to this relatively pricey product. Regardless of your background, disassembler preference, or budgetary restrictions, each tool listed above provides a different reverse engineering experience, and each is worth trying once. At the very least, a test drive can clarify your preferences and bring an appreciation for the tool(s) you choose to use.
This post focuses on an initial workflow for performing static code analysis using radare2. Specifically, it will cover how to load a PE file into radare2, identify an imported API of interest, find a reference to the API, view assembly at that location, and begin to assess the code’s purpose.
Radare2 is a project that contains multiple tools for binary analysis, and radare2 (yep, same name) is the primary tool that performs disassembling and debugging. It is command line driven, which may be daunting after extensive use of other disassemblers that provide a GUI. In fact, the official R2 book depicts the level of effort required to learn radare2 like this:
Source: https://radare.gitbooks.io/radare2book/content/first_steps/intro.html
Let there be no doubt – learning how to use radare2 is complicated. However, the best way to tackle a difficult task is to get started.
Installing Radare2
Radare2 binaries and source for a variety of operating systems are available here. I used a 64-bit Windows VM environment for my analysis, so I downloaded and ran the appropriate binary. Specifically, I’m using the Windows VM we distribute in the SANS FOR610 Reverse Engineering Malware course, so you will see references to the “REM” user.
Analyzing a File with Radare2
Loading a binary
For this post, we will use a Gandcab ransomware sample. If you want to follow along, you can download the sample here (password: malware).
To load the file into radare2, simply type radare2 , as shown below.
We now have a radare2 shell waiting for additional commands. Notice the shell indicates we are at the address 0x004044bb, which is the entry point for this executable (more on that in a moment).
To navigate an executable within radare2, you will use text-based commands to initiate processing and query information. Along the way, using the question mark (“?”) will provide help about command options. For example, type a question mark ? and hit return. Below is an excerpt of the initial output.
If you scroll down the output on your screen, you will find a reference to the i command:
The i command provides information about a file. For more detail on the type of information we can query, type i?:
For example, typing ie will provide information about the executable’s entry point. Below is an excerpt of this command’s output.
Notice the virtual address (“vaddr”) matches the address of our location within the radare2 shell, confirming that we currently reside at the executable’s entry point.
Initiating code analysis
To begin our code analysis with radare2, we must first kick off some automated analysis. Depending upon your prior exposure to radare2, you may be surprised to know that, by default, radare2 does not perform any analysis at startup. Other disassemblers and debuggers like IDA Pro and x64dbg will automatically analyze the binary to identify functions, code and data. The author of radare2 (pancake), however, takes a different approach. He details his case here, but the basic point is that radare2 aims to run on various platforms with varying levels of computing power, and it is capable of analyzing many different binary architectures. As a result, no analysis is typical, so it’s up to the analyst to determine what types of processing are relevant. While some may reject this approach, it forces the analyst to be more deliberate in their work. In fact, the entire radare2 experience reinforces this by requiring explicit commands to view information and navigate the code.
While we won’t discuss the details of all possible commands (see this resource), you can see options by typing aa? and aaa?. If you want to take a leap of faith and perform a variety of analyses against a file, I suggest using the aaa command. After executing this command, you will see a variety of output messages as radare2 analyzes the binary (excerpt below):
Viewing imports
Now that the initial auto analysis is complete, it’s time for us to manually navigate the code. One approach is to first find Windows API references that support malicious functionality. To view functions imported by the suspect binary, we can type ii:
There are many APIs we could explore, but for this post, we will focus on CreateToolHelp32Snapshot (not shown above). This API is used to capture a snapshot of running processes on a system. Malware often uses this functionality to enumerate running processes and identify specific process names. To find this imported function in the import list, type ii~CreateToolHelp32Snapshot (the tilde searches the output of ii for the specified text):
Finding an API reference
Next, we want to locate references to this API. To query this information, we will type the letters a (analysis), x (cross references), and t (find references to the specified address), followed by the address of the imported function:
In the output above, we see references to two CALL instructions, which represent instructions that call CreateToolhelp32Snapshot. We could explore both references, but for this post we will only jump to the first reference address using the s (seek) command:
Notice the address in the prompt changed to our destination address, a signal that we have arrived at the desired location. To confirm this, we can use the pd (print disassembly) command and its subcommands:
First, let’s make sure we reside at a CALL to CreateToolhelp32Snapshot using the command pd N, where N indicates number of disassembly lines to print (pardon the small text size to maintain formatting):
Notice the autogenerated comments in red are unhelpful in this case, but they are included for completeness.
Understanding the code
To view a summary of the function where we currently reside, we can type pds (print disassembly summary):
As indicated by the help information, pds focuses on strings, calls, jumps, and references to provide an overview of the function. Looking at the above output, notice the APIs CreateToolhelp32Snapshot, Process32First, lstrcmpiA, and Process32Next. This progression of CALLs is often used to capture a snapshot of running processes, begin iterating through the list, compare process names to one or more predefined names, and continue through the list, respectively.
To understand precisely how these calls are used and what decision points are encountered, we need more information about the function. We could print the entire function body with the command pdf (print disassembled function), but this prints a rather large amount of output that you have to scroll through in the terminal.
One approach to evaluating the context of the CreateToolhelp32Snapshot CALL is to view the instructions that occur right before it. To view the 10 instructions before the CALL, we can type pd -10 (only the command and disassembly are shown due to space constraints):
I mentioned earlier that when malware uses CreateToolhelp32Snapshot to capture and evaluate running processes, it often compares the process list snapshot to predefined values. It is likely this is that predefined group of process name strings. Considering this sample is ransomware, it makes sense that the malicious code would want to check for these process names, as they may have a lock on files worth encrypting.
Another approach to understanding the context of this code is to use radare2’s visual mode, which allows you to browse the assembly similar to a GUI-based disassembler. Type V to enter visual mode, and use the HJKL keys (similar to vi/vim) to navigate the code:
Since this approach allows for easy exploration of the code, it is my preferred method for code analysis. Typing a question mark will provide a help menu specific to this interface, although that output is not shown here.
Another perspective on this code and its flow of execution is achieved by entering graph mode with the command VV. Once in graph mode, the HJKL keys will allow you to browse the decision points that occur throughout the function. Below, focusing on the lstrcmpiW, OpenProcess and TerminateProcess CALLS in this more visual interface provides insight into what happens if the program matches a process name against its predefined list.
Specifically, if a string match is found, the program will access the target process via OpenProcess and then terminate it.
Closing Thoughts
This post introduced radare2 and explored a basic workflow to load a binary and begin analysis. There is certainly much more to learn about radare2, but I hope this jumpstarts your journey.
For more information on radare2, I encourage you to explore these resources:
If you would like to learn more about malware analysis strategies, join me at an upcoming SANS FOR610 course.
-Anuj Soni / @asoni
Unpacking and Correlating Qakbot
I recently wrote a post for Cylance (my employer), discussing the polymorphic features of Qakbot. You can read it here.
About the Author:
Anuj Soni is a Senior Threat Researcher at Cylance, where he performs malware research and reverse engineering. He is also a SANS Certified Instructor and co-author of the course FOR610:Reverse-Engineering Malware. If you would like to learn more about malware analysis strategies, join him at an upcoming SANS FOR610 course.