Note
Although this repo can be used to execute other binaries, the whole focus was on running the mimikatz.exe executable. This is for demonstration and testing purposes, as mimikatz.exe is a well-known post-exploitation tool.
-
Stegnography: Hiding PE payloads in PNG/JPG/JPEG/BMP/GIF files using Discrete Wavelet Transform (DWT) with Quantization Index Modulation (QIM) and Error-Correcting Codes (ECC). It is worth noting that the Reed-Solomon Error Correction Algorithm implemented by the PE loader is based on SRI-CSL/jel.
-
Utilizing The GPU For Memory Scanners Evasion: Using the D3d11 library, the implementation moves the injected PE payload into the GPU memory when it's idle, hiding it from memory scanners.
-
Thread Stack Spoofing: Based on Cobalt-Strike/CallStackMasker, the code searches for a suitable thread stack and masks the thread running the PE payload whenever the payload is in GPU memory.
-
Syscalls Tampering: Maldev-Academy/TrapFlagForSyscalling is used to invoke tampered syscalls relying on the Trap Flag.
-
Handles API Set Dlls using ajkhoury/ApiSet.
-
Loads the required payload DLLs in a random sequence to help against sequence-based image-load notifications (if any).
-
Uses AES-NI from Intel.AES-NI to encrypt the PE payload sections before affloading them to the GPU memory, and decrypt them after fetching them from there.
-
Counts prime numbers for a specified duration as a method to delay execution. This technique is not executed by default.
-
Unhooks loaded Dlls from the
\knownDlls\directory without usingRWXmemory permissions. This technique is not executed by default, as some EDRs were able to detect the logic. -
If not using the aforementioned Syscalls Tampering technique, the implementation will use HellsHall. Additionally, in the DLL unhooking routine, the implementation utilizes
win32u.dllto execute thesyscallinstruction, asntdll.dll's text section will beRW, which blocks us from jumping to asyscallinstruction there. -
Overwrite EDR C's VEH that is used to handle
STATUS_GUARD_PAGE_VIOLATIONexceptions, as this vendor was found to be usingPAGE_GUARDpermissions to trigger exceptions when accessing fake DLLs:
The code is refactored from mannyfreddy in the Introduction to Vectored Handler Manipulation module.
-
Manually fetching resource section payloads, avoiding APIs like
FindResourceWandLoadResource.
RunPeFile is the main binary file that will execute the provided EXE from the stored PNG file(s) in its resource section. Some notes when compiling RunPeFile:
- Using the Configuration.h header file, one can add and remove features.
- Define the _DEBUG macro to enable the debug mode. Or compile in Debug mode.
- In the repository, the current
RunPeFileimplementation will runmimikatz.exe. - One should utilize the
FileConstructor.pyscript to update the payload delivered byRunPeFile.
The FileConstructor.py script is the main script used to generate PNG files containing the DWT-encoded EXE payload. These PNGs are placed in the EncodedPngs directory, from which the updated RunPeFile project embeds them into the resource section of the compiled binary. Each EXE is split into multiple chunks, with every chunk embedded into its own PNG image. As a result, you'll see several PNG files that all display the same picture. This chunking is necessary because the steganography method (based on DWT combined with Reed–Solomon error correction) typically cannot fit an entire EXE payload into a single image (depending on the size/pixels in the PNG, as well as the size of the payload). This script relies on the NUM_SPLIT_PARTS constant to determine how many chunks the input EXE will be split into.
FileConstructor.py handles the Visual Studio Project files of RunPeFile, as well as the chunking logic. It calls the DwtStegPeFileToPng.py script to do the actual payload embedding.
Examples of calling FileConstructor.py are:
# Adds the embedded PNG(s) to the 'RunPeFile\RunPeFile.vcxproj' project by dafault:
python.exe .\FileConstructor.py --pe mimikatz.exe --png memes\cat.png
# Adds the embedded PNG(s) to the 'XYZ\XYZ.vcxproj' project:
python.exe .\FileConstructor.py --pe mimikatz.exe --png memes\cat.png --project XYZ\XYZ.vcxproj
The DwtStegPeFileToPng.py script is the main script that handles implementing the DWT algorithm to encode a given file into a specified PNG one. It is a stand-alone script and can be used in other scenarios, but in this repository, it's called through the FileConstructor.py script only. Below is how DwtStegPeFileToPng.py can be called:
usage: DwtStegPeFileToPng.py [-h] (--encode | --decode) --png PNG --output OUTPUT [--file FILE] [-v]
DWT-based steganography tool for hiding files in PNG images
options:
-h, --help show this help message and exit
--encode Encode/embed a file
--decode Decode/extract a file
--png PNG PNG image file
--output OUTPUT Output file path
--file FILE File to embed (required for --encode)
-v, --verbose Verbose output
The ExtractPePayloadFromPng project is a standalone tool for pulling payloads out of PNG files. It can handle single images, or, when given the PNG containing the first chunk of a split PE file, it will reconstruct the full payload across all related PNGs. For example, calling ExtractPePayloadFromPng.exe like this:
.\ExtractPePayloadFromPng.exe --i ..\..\EncodedPngs\mimikatz_part01.png --o mimikatz.exe
Will pull the full mimikatz.exe binary from the PNG files located under the EncodedPngs directory.
- The Stack spoofing technique implemented was tested on Windows 11 only.
- To move the PE payload sections back and forth from and to the GPU memory, one should have a Direct3D-11 capable GPU (discrete or integrated), a WDDM 1.1+ driver, and have the DirectX 11 runtime installed.
- Only x64 PE payloads are supported.
Note
Some EDRs required further tweaks to the code for a successful bypass. Some features were enabled or disabled depending on the security vendor encountered.
Bypassing Pesieve version 0.4.1.1 with the following command:
.\pe-sieve64.exe /data 4 /refl /iat 3 /obfusc 3 /shellc 4 /threads /pid XXXX


