This post walks through the analysis of the execution of 2 chunks of shell codes which are part of the file "51edea56c1e83bcbc9f873168e2370af", that lead to the decoding and unpacking of the stage 1 dropper.
Identify, Extract and Decode the First Chunk of Shell Code
After analyzing the byte distribution of the file, you would realize that there large portions of text that are hex encoded strings. Visually inspect the file from top-down, disregard strings that are not repetitive sequences of one or two bytes and disregard strings that are not within the hex encoding byte range (0x0 to 0xF). You should arrive at the first chunk of shell codes at line 105 of the file. Refer to the post Red October [Hex Code Analysis] for more details on analyzing hex codes.
|The first chunk of shell code.|
Analyzing Shell Code in IDA
Because shell codes do not come in the structure of a PE file, IDA will treat the file as a binary file and not resolve any functions, imports or exports. It would be helpful to look at the strings, and resolve functions within the shell code; after which you would arrive at the function of interest at 0xF1.
|Handy IDAPython script for iterating through unknown/unexplored lines of code, checking if they are bad addresses and converting them to functions if possible. Remember to change the segment name in the first line.|
*script was modified from a sample found here
Notice the first line of the function sub_F1, it is comparing a value on the stack with the string "T@TP". Note that the values on the stack are stored in little endian, as such, the actual value compared is "PT@T". Remember this string. Now note the "pusha" instruction at 0x13A; this instruction pushes the contents of the general-purpose registers onto the stack (read more here), and is typically done before an unpacking/decrypting routine.
|Function of interest found at 0xF1.|
XOR Decoding Routine
After the registers are saved using the "pusha" instruction, the function proceeds to a xor decoding routine at 0x13D, with the xor key being used at 0x165.
|A broad look at the xor decoding loop.|
|The xor key is 0xB6.|
Extracting and Decoding the Second Chunk of Shell Code
Now lets take the information learned during the analysis of the first shell code and use it on the file "51edea56c1e83bcbc9f873168e2370af". Notice that the first chunk of shell code looks for a string "PT@T". This string can actually be found in the file, and is used to mark the offset for the second chunk of shell code. We also know that the second chunk of shell code goes through a XOR ^ 0xB6 decoding routine.
|The string "PT@T" marks the offset for the second chunk of shell code.|
|Extract and XOR ^ 0xB6 decode the second chunk of shell code.|
Analyzing the Second Chunk of Shell Code
Now that we have the second chunk of shell code on hand, repeat the steps taken when analyzing the first chunk - look at strings, resolve functions and then analyzing the functions to determine what the shell code does. Just a note that in some cases, the shell codes may not resolve to any meaningful functions, in that case, you'll have to analyze the assembly code without the logical representations of functions and subroutines. Following the described steps, you'll arrive at the function sub_E0.
|Function of interest found at 0xE0.|
We find a similar flow as that of the first chunk of shell code. The instruction at 0x14A is comparing a value on the stack with the string "iNYD". Note that the values on the stack are stored in little endian, as such, the actual value compared is "DYNi". Follow the function flow and find the "pusha" instruction at 0x218 and subsequently the start of the xor decoding routine at 0x21B and the xor key 0xDE being used at 0x23D.
|Note the string comparison of "DYNi" at 0x14A.|
|XOR ^ 0xDE at offset 0x23D.|
Extracting and Decoding the Packed Dropper
Based on the information gathered from analyzing the second chunk of shell code, we can proceed to extract and decode the packed dropper. Find the string "DYNi", extract the bytes and XOR ^ 0xDE decode them to get the packed dropper binary.
|Locating the packed dropper.|
|After extracting the bytes, XOR ^ 0xDE decode them.|
|You will find the packed dropper file with a suggested name "msmx21.exe".|
|Remove the first 10 bytes and you will have the result is the packed binary msmx21.exe.|