Skip to main content

Analyzing obfuscated powershell with shellcode

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:

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:
  • "[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"
What's happening here is that the Base64 encoded payload is being decoded and converted into a byte array and later assigned to the variable “$mk”. The script then calls the function “VirtualAlloc”, exported from “kernel32.dll”. If we take a look at the MSDN docs for this function, we can gain additional insight into its parameters: The key parts of for the function call are:

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 (, I’m going to use CyberChef to help me decode this data. These are the steps I took:
  1. I copied the Base64 encoded payload from the PowerShell script to CyberChef.
  2. After that, I selected the “From Base64” option, followed by “To Hex” for your recipe. You can just drag and drop them into place.
  3. 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

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:
  1. (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.
  2. (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:
The “connect” function uses the structure “SOCKETADDR”, outlined here:


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 “” over port “4444”.

Appendix: Tools <-- this tool is amazing!


Popular posts from this blog

Analyzing and detecting web shells


Web shell hunting: Meet the web shell analyzer


Introduction to Malware Analysis
