“Good work on that last assignment!” Your boss seems delightfully cheery today. “The client was very impressed by your skills and has requested that you help them with another engagement.”
This is great news, you are already impressing your boss.
“They recently found some malware on their servers, and want you to provide a report on its behaviors. From what I’ve seen, our team has never encountered some of these malware before…”
This seems like less great news.
“Anyways, I expect a report on my desk in 2 weeks!”
It seems like its back to reading the documentation for you.
Assignment
The purpose of this assignment is to evaluate your ability to find certain behaviors of a piece of malware using various static and dynamic malware analysis tools.
You will need to use the malware lab environment we have provided to create a report on all of the trigger commands and behaviors of each command for the provided malware. Please refer to the tutorial presentation to get started!
Feel free to adjust the VM’s memory space after download.
In your report, you will need to answer the following questions:
- exe (60 points):
- What is the address/name of the target function(s)? Please fill out what categories the target function is a member of, as well as its data references, and description of what the basic blocks do in the Excel sheet.
- What trigger words/partial commands spur the binary to act? Please submit the Angr script you used to find these keywords. If they are CNC commands, please use a different row in the Excel sheet and exclude those categories/behaviors from the target function row.
- What behaviors did you find during concrete execution? Please fill this out in the Excel sheet as well as provide proof in the form of a screenshot.
- exe (30 points):
- What is the address/name of the target function(s)? Please fill out what categories the target function is a member of, as well as its data references, and description of what the basic blocks do in the Excel sheet.
- What trigger words/partial commands spur the binary to act? Please submit the angr script you used to find these keywords. If they are CNC commands, please use a different row in the Excel sheet and exclude those categories/behaviors from the target function row.
- What behaviors did you find during concrete execution? Please fill this out in the Excel sheet as well as provide proof in the form of a screenshot.
- exe (10 points + 10 bonus):
- We don’t know what kind of malware this is ourselves and would like you to find out! At the very least, we would like you to statically analyze 10 candidate functions and see if you can find the target function and fill out the necessary rows in the Excel sheet.
- You will get extra points if you find triggering commands and succeed in concretely executing the binary in your VM.
VM Link:
GoogleDrive:https://drive.google.com/open?id=1a_1U2UQKQ0268NApFnFHfV2HETZZEu4ZLinks to an external site.
MD5hash: 72ff81b5b73b2297c8d64f0c09ecc03d
Supplementary Material:
Lab 2_Supplementary_Material.pdf
Deliverables
Please submit a .tar.gz file containing the report, Angr scripts and proof of concrete execution. Name this “[username]_lab02.tar.gz”. Please include the following in this .tar.gz file:
- A report in the form of an Excel sheet on all commands for the malware and the behavior of each command. This will be graded based on the completeness of your investigation. The template can be found here: xlsxDownload lab02_report.xlsx.
- A detailed writeup about each steps you took to explore these malware. Name this “writeup.pdf”.
- A folder for each malware (at least the first 2), each named malware[#], containing:
- Proof of concrete execution for the first two malware in the form of screenshots that display the result of the behavior. Name each of the screenshots so that it is obvious as to what the screenshot is displaying.
- Angr scripts for each malware (at least for the first 2). These should be called “malware[#]_inputs.py” (python3 script)
Sample Structure after unzip:
- dzhang377_lab02/
- malware1/
- py
- {jpg/png/…}
- {jpg/png/…}
- …
- malware2/
- py
- {jpg/png/…}
- {jpg/png/…}
- …
- malware3/
- py
- {jpg/png/…}
- {jpg/png/…}
- …
- xlsx
- malware1/
Warning:
Please don’t run the malware on your own computer! We are not responsible if you do. Only execute it inside the Windows VM we are provided. These are real world malware samples.
Overview
- Basics of Malware Analysis
○ View assembly in disassembler
○ Find dispatcher code
○ Symbolic analysis
○ Dynamic analysis
- Malware Obfuscation
- Further Reading
Basics of Malware Analysis
Viewing code in disassembler
- You can manually analyze a binary via disassembler (i.e. Ghidra, IDA, etc.)
- All variable and function names stripped
- Manually reading assembly instructions
- Gives a good overview of what the code does
Viewing code in disassembler (cont.)
- Example:
○ In the VM, Ghidra is located at ~/ghidra_9.1.1_PUBLIC/
○ After you cd into that directory, run Ghidra with ./ghidraRun
○ A project has already been created for you, so all you need to do is import the binary to the project by clicking File > Import File > Select binary to import
Viewing code in disassembler (cont.)
- Example (cont.)
○ Code will be presented as assembly instructions on the left half of the interface and reconstruction C instructions on the right half of the interface
○ For this project, being able to read assembly is not required, but can be helpful
■ Generally, assembly instructions come in the form of an instruction name followed by 1, 2, or 3 operands
■ For example, the PUSH instruction will push a value onto the stack. Since you can only push 1 item to the stack at a time, the instruction takes 1 operand
■ This operand can be a value or the name of a register: the value will be pushed to the stack if a value is used as the operand while the value inside the register will be pushed to the stack if the register is chosen as the operand instead
■ i.e. “PUSH %eax” means that the computer will push the value inside the EAX register to the top of the stack. Now, if you get the value at %esp (the stack pointer) or pop a value off of the stack, you will get whatever value you just pushed
○ A good reference for x86 assembly can be found here
○ In the folders on the very left of the UI, you can find all the functions within the binary. Explore these to find out more about what the malware will do (not necessary)
Find dispatcher code
- C&C malware uses dispatching logic to figure out what it will do on the victim machine given a command from the control server
- Usually, this is encapsulated in a function with many logic switches
- A helper script is provided to find dispatcher logic at
~/ghidra_9.1.1_PUBLIC/support/analyze.sh
- Run shell script like so: ./analyze.sh [path/to/binary]
- Will output candidate function addresses that may point to basic blocks that look like dispatching logic at ./output.txt
- Must open binary with Ghidra before running script!
Find dispatcher code (cont.)
- With these function candidates, check manually to see which function actually is the dispatching logic
- Example:
- This snippet checks some parameter against some suspicious-looking strings, and calls one (or more) function(s) using that parameter if true that execute malicious code, so this function is a strong candidate
Symbolic Analysis
- Once the dispatching logic is found, you can now analyze the exact behaviours of this malware since the dispatching logic is basically the heart of the actions that a C&C malware will take
- To find every single action that the dispatching function can do, click the “Display function” button in the toolbar to see a CFG, and will help identify basic blocks of code that you will want to target during symbolic execution
- A basic block is a block of code that does not have a branch statement except at the end of the block
- Very similar to testing code in software engineering, in which you want to make sure you have maximum branch coverage
- Example: sample.exe
- Our goal is to find what arguments from the command server will trigger the dispatching logic for this malware sample
○ We first need to find what we can tweak in our input to this function so that it will behave differently
○ In the binary, we find that the execution of the dispatching logic (not function) is dependent on the value stored at %eax
○ Looking at the C representation of these basic blocks confirms this observation, given the big if-statement being dependent on the “pcVar1” variable
○ In our C representation, we can also see that the “pcVar1” variable is dependent on the 1st parameter of the function, giving us a candidate to symbolically represent!
- Example: sample.exe
- Thankfully, there already is a script that can help us symbolically execute the dispatching function in the binary once you specify the location in the script
○ The script is found at ~/Desktop/symbolic_execution/sample_inputs.py
○ All we need to do is give it the start of the function (0x804d32) and the address at which we want our program execution to end up
○ In this case, we wish to end up at the function call inside the if-statement at 0x804dde because we believe that it will execute malicious behaviour
○ We can easily find these addresses by clicking specific lines in our C code representation on the right and the address will be highlighted on the left
○ Now, if we execute python sample_inputs.py –start 0x804d32 –end 0x804dde, it will print 1 parameter for the dispatching function that will hit the inside of the if-statement
- Example: sample.exe
- The script uses a bitvector in the claripy library found in the Angr framework
○ Again, we will use a simulation manager like the one used in Lab 1 with a claripy solver
○ However, we will specify a call state to call the specific dispatching function with the argument that we will inject ourselves
■ target_state = proj.factory.call_state(start, sym_arg_1)
○ Then, the code will symbolically execute dispatching function again and again until an the symbolic argument causes the program to reach the inside of the if-statement, and we now find one such argument of the dispatcher!
Print out the argument that allowed the execution engine to reach the target address
- Example: sample.exe
- If we ran this script as-is again, we will have the same result
○ Thus, if we want to find all such inputs from the command server that will trigger the dispatcher logic, we must put inverse constraints on the function argument after we find each new command
○ We can do this one of two ways:
■ Adding a constraint before evaluation (i.e. before .explore() is called)
- Can be done with add_constraints(sym_arg_1…)
■ Adding a constraint after evaluation
- Can be done with found[0].solver.add(sym_arg_1 ….)
- Then we call found[0].solver.eval()
○ This way, we will iteratively find each triggering parameter
Dynamic Analysis
- Now that we know how to trigger each dispatching behaviour, we need to find out what each command will do
- We can either read the code, or we can see the behaviour live
- Since this is still malware, it is not good to simply run the binary in any environment, so we will want to run it in a sandbox
- Dynamic analysis engines help keep track of the specific actions that a binary takes during its execution
- One such dynamic analysis engine is called DynamoRIO
Dynamic Analysis (cont.)
- Example: sample.exe
○ After logging into the Windows sandbox, we can find DynamoRIO already installed
○ This is a dynamic execution engine that not only keeps tracks of the actions being taken by the binary when run inside of the engine, you can customize the actions it takes upon reaching a certain behaviour from the binary
○ These customizations can be found in C:\code\concrete_executor
○ For sample.exe, we would like to change libcall_handler.cpp to change what the engine will do when a function is called
○ First, we would like to specify the function (i.e. the dispatcher function) we want to wrap and start monitoring from
○ Then, we would like to wrap the input before the function is called so we can define the input to a given function
○ Of course, we will need to add these method traces to the .h file to follow C++ convention
Symbolic Analysis (cont.)
Dynamic Analysis (cont.)
- Example: sample.exe
○ Once this code has been changed, we first rebuild the scripts with .\build.bat
○ Now, we can python run.py to run the dynamic analysis engine
○ Once the execution is complete, we can view the output of the engine in the folder you specified
○ In the below example, our input caused the malware to attempt to read many files
○ Of course, it is never going to be that easy as some functions may require extra logic in order to execute fully
○ If nothing happens after executing with a correct input, you may need to go back to the disassembled code to see if there are any additional requirements to fully analyze the malware behaviour
Malware Obfuscation
Common Obfuscation Techniques
- Packing (i.e. UPX)
- Writing bad code (forget everything you learned in software engineering) ● Encryption
Further Reading
x86 Assembly Resources
Introduction to Assembly
x86 Assembly/X86 Instructions – Wikibooks, open books for an open world
Symbolic Execution Resources
Claripy (not as important, but check #claripy-asts if you want to find other constructs you can use to constrain the solver)
Claripy – angr Documentation
Solver Engine (#constraint-solving is helpful for figuring out how to set constraints)
Solver Engine – angr Documentation
Dynamic Analysis Resources
System overview https://dynamorio.org/dynamorio_docs/overview.html Existing tools based on DynamoRIO:
https://dynamorio.org Tutorial:
https://dynamorio.org/tutorials/ Library tracing:
https://github.com/mxmssh/drltrace DynamoRIO discussion group:
https://groups.google.com/g/dynamorio-users Code Manipulation API:
drwrap_wrap:(primary function that students need to use in project 2 dynamic analysis) https://dynamorio.org/dynamorio_docs/page_drwrap.html
list of sample use cases for dynamoRIO https://dynamorio.org/dynamorio_docs/API_samples.html



