Recently, a PowerShell script came across my lab and I thought it might be worthwhile showing others how to handle this type of payload. Many PowerShell frameworks exist that allow pen-testers and attackers alike to build payloads with ease. The two I see most often are:
- Cobalt Strike - https://www.cobaltstrike.com/
- PowerShell Empire - https://github.com/EmpireProject/Empire
The Script
So let's just dive right in. What does a Powershell payload look like? Figure 1: Original PowerShell script
When starting any malware analysis, I tend to look for low hanging fruit. In this case, I see a few things that interest me:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx. The key parts of for the function call are:

- "[Byte[]]$mK = [System.Convert]::FromBase64String” followed by a Base64 encoded text.
- "kernel32.dll VirtualAlloc" followed by: "$mK.Length,0x3000, 0x40"
- "kernel32.dll CreateThread"
- "kernel32.dll WaitForSingleObject"
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx. The key parts of for the function call are:
- dwSize (Set to the length of the shellcode)
- flAllocationType (Set to 0x3000, which is MEM_COMMIT | MEM_RESERVE (0x3000). This reserves and commits an allocation in one step.
- flProtect (Setting the allocated region of memory to 0x40. This means PAGE_EXECUTE_READWRITE)
The Script (Layer 2)
Now that we have a basic understanding of what’s going to happen with this Base64 encoded payload, let's move forward and begin decoding it. As stated in my previous blog post (https://blog.stillztech.com/2018/06/introduction-to-malware-analysis.html), I’m going to use CyberChef to help me decode this data. These are the steps I took:- I copied the Base64 encoded payload from the PowerShell script to CyberChef.
- After that, I selected the “From Base64” option, followed by “To Hex” for your recipe. You can just drag and drop them into place.
- Then I clicked the “Save to file” option in the bottom right pane to save the shellcode to disk. If all goes well, your CyberChef view should look like this:
Figure 2: CyberChef decoding base64 and convert the output to hex


Figure 6: Scdbg output on initial launch
Since we want to start executing the shellcode at the very beginning, we pass the value of “0” to the console window and press enter to continue execution. Once completed, you should see the following output below:

Figure 7: Scdbg console after completed emulation of shellcode
So what’s happening here?! If you read from top to bottom, you can see the first four API calls. Let’s map them out and add in the MSDN context below:
https://www.sublimetext.com/
http://www.ollydbg.de/
http://www.kahusecurity.com/?p=12724 <-- this tool is amazing!
The Shellcode
Cool, now that we have our shellcode saved to a text file, we need to run it. Before we do that, I wanted to show what this raw hex actually means. The best way I can show you is to load this hex file, “download.dat” (default output name from CybeChef), into OllyDbg. You can do this by clicking on “View > File” from your OllyDbg window. Once the hex file is loaded into OllyDbg, you should see the following screen below: Figure 3: Hex view of the shellcode inside of OllyDbg v1
If we go a step further and click on “Disassemble”, you should see the following:

Figure 4: Hex dump converted to machine instructions
What you’re seeing in the figure above, are the raw instructions for the CPU. I won’t go into detail on how to break down and understand these instructions, but just know that this shellcode is giving the CPU a set of raw instructions to execute. The easiest way I know how to analyze shellcode is to execute it. To do this, two options come to mind:

If we go a step further and click on “Disassemble”, you should see the following:
Figure 4: Hex dump converted to machine instructions
What you’re seeing in the figure above, are the raw instructions for the CPU. I won’t go into detail on how to break down and understand these instructions, but just know that this shellcode is giving the CPU a set of raw instructions to execute. The easiest way I know how to analyze shellcode is to execute it. To do this, two options come to mind:
- (Harder) Using OllyDbgv1 (see appendix) with the “Olly Advanced” plugin, we first load a binary into memory (i.e. “notepad.exe” for example). Once notepad is loaded into OllyDbg, we can then allocate memory inside this program for our shellcode and change the execution to begin at the start of this code.
- (Easier) Using the tool “scdbg”, we can load in the shellcode and run it to see what the program outputs. This tool, as described on its website (see appendix), “is a shellcode analysis application built around the libemu emulation library. When run it will display to the user all of the Windows API the shellcode attempts to call.” After downloading “scdbg”, copy both the program and shellcode (named “download.dat” by default from CyberChef) to your malware VM. Once you’ve copied these files to your malware VM, launch “gui_launcher.exe”. Using the browser button or drag and drop, load the shellcode into “scdbg”. I’ve also enabled a few switches in the GUI, as outlined below:
Figure 5: Loaded hex dump payload inside of scdbg
The last part is running the shellcode. Just click “Launch” and a new console window should appear:
Figure 6: Scdbg output on initial launch
Since we want to start executing the shellcode at the very beginning, we pass the value of “0” to the console window and press enter to continue execution. Once completed, you should see the following output below:
Figure 7: Scdbg console after completed emulation of shellcode
So what’s happening here?! If you read from top to bottom, you can see the first four API calls. Let’s map them out and add in the MSDN context below:
- LoadLibrary:
- MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
- Purpose: Used to load the library ws2_32. This DLL is the “WinSock” library. We can gain further insight into its functions by reviewing the link: https://docs.microsoft.com/en-us/windows/desktop/WinSock/winsock-functions
- WSAStartup:
- MSDN: https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsastartup
- Purpose: “The WSAStartup function initiates use of the Winsock DLL by a process.”
- WSASocket:
- MSDN: https://docs.microsoft.com/en-us/windows/desktop/api/Winsock2/nf-winsock2-wsasocketa
- Purpose: “Creates a socket that is bound to a specific transport-service provider.”
- Parameters: You may have noticed the parameters are being passed to this function. If you review the MSDN docs for this function, you can translate the parameters into the following:
- af=2: “The Internet Protocol version 4 (IPv4) address family.”
- tp=1: “SOCK_STREAM” -> TCP
- proto=0: “If a value of 0 is specified, the caller does not wish to specify a protocol and the service provider will choose the protocol to use.”
- group=0: “No group operation is performed.”
- flags=0: “A set of flags used to specify additional socket attributes. No flags are being set.”
- Connect:
- MSDN: https://docs.microsoft.com/en-us/windows/desktop/api/Winsock2/nf-winsock2-connect
- Purpose: “Establishes a connection to a specified socket.”
- Parameters: You may have noticed the parameters are being passed to this function. If you review the MSDN docs for this function, you can translate the parameters into the following:
- h=c8
- host=10.95.73.57: “The host this shellcode will connect back to”
- port=4444: “The port this shellcode will call back to”
Summary
What we know:- The PowerShell script decodes a Base64 encoded payload and converts it into a byte array.
- The PowerShell script allocates memory for the byte array and marks this region as Read/Write/Execute.
- The PowerShell script then changes execution to this allocated region and begin executing.
- Shellcode payload attempts to establish a TCP connection to the host “10.95.73.57” over port “4444”.
Appendix: Tools
http://sandsprite.com/blogs/index.php?uid=7&pid=152https://www.sublimetext.com/
http://www.ollydbg.de/
http://www.kahusecurity.com/?p=12724 <-- this tool is amazing!
Comments
Post a Comment