mirror of
https://github.com/MaorSabag/NaX
synced 2026-06-28 15:01:11 +00:00
c0fc8d878b
Position-independent C2 beacon for Adaptix Framework with: - PIC shellcode beacon (PEB walk, FNV1a hashing) - BeaconGate API proxy + WFSO PoC sleepmask (extensible) - BOF execution with module stomping - Malleable C2 profiles with runtime switching - WinHTTP transport (proxy-aware) - Token manipulation (steal, impersonate, create) - TCP tunneling (SOCKS, lportfwd, rportfwd) - SMB pivoting - Stardust UDRL loader with module stomping
3.8 KiB
3.8 KiB
NaX UDRL Loader
Position-independent User Defined Reflective Loader for the NaX beacon, based on the Stardust template by Paul Ungur.
What It Does
The loader is the first code that runs when the shellcode is injected. It:
- Resolves its own base address and size (Stardust RIP-relative technique)
- Walks the PEB to find
ntdll.dllandkernel32.dllby FNV1a hash - Resolves
RtlAllocateHeapand TLS APIs via export table walk + compile-time hashes - Finds two consecutive TLS slots (egghunter) to store a global INSTANCE pointer
- Parses the NaxHeader v2 (160-byte structure between loader and beacon) to extract beacon size, .pdata/.xdata offsets, stomp flags, and sacrificial DLL name
- Places the beacon into executable memory (virtual allocation or module stomping)
- Transfers execution to the beacon entry point (thread pool or CreateThread)
Techniques
Technique selection is compile-time via preprocessor defines:
| Define | Value | Technique |
|---|---|---|
NAX_STOMP_MODE |
NAX_STOMP_VIRTUAL (0) |
NtAllocateVirtualMemory -- private RWX allocation |
NAX_STOMP_MODE |
NAX_STOMP_MODULE (1) |
Module stomp -- load sacrificial DLL, overwrite its .text section |
NAX_EXEC_MODE |
NAX_EXEC_THREAD (0) |
CreateThread -- start address = beacon entry |
NAX_EXEC_MODE |
NAX_EXEC_THREADPOOL (1) |
TpAllocWork + TpPostWork -- start address = TppWorkerThread |
Module Stomping
When NAX_STOMP_MODE == NAX_STOMP_MODULE:
- Loads a sacrificial DLL with
LoadLibraryExW(DONT_RESOLVE_DLL_REFERENCES)(no DllMain execution) - Writes the beacon into the DLL's
.textsection so it appears as image-backed memory (MEM_IMAGE) - Patches the LDR entry with flags:
ImageDll | LoadNotificationsSent | ProcessStaticImport | EntryProcessed - Stomps valid
.pdata(RUNTIME_FUNCTION) and.xdata(UNWIND_INFO) into the DLL for clean stack walks
Hashing
All API and module resolution uses FNV1a-32:
- Seed:
0x811c9dc5(H_MAGIC_KEY) - Prime:
0x01000193(H_MAGIC_PRIME) - Algorithm:
Hash ^= Char; Hash *= Prime;(XOR then multiply) - Case-insensitive: uppercased before hashing
Compile-time hashing via HASH_STR() (constexpr in C++ mode) ensures no API name strings appear in the shellcode.
Source Files
src/
Entry.asm # NASM entry point, calls PreMain
PreMain.c # Stardust bootstrap: RIP calc, PEB walk, TLS egghunter
Main.c # API resolution, NaxHeader parsing, stomp/exec dispatch
Ldr.c # LdrModulePeb (PEB walk), LdrFunction (export walk + forwarding)
Pe.c # PE header helpers: NaxPeHeaders, NaxFindSection, NaxFindSectionByDir
Stomp.c # Module stomping: NaxModuleStomp, NaxPatchLdr
Exec.c # Execution transfer: NaxExecThreadPool, NaxExecThread
Utils.c # HashString (FNV1a, case-insensitive)
include/
Common.h # Base types, PEB structures, compiler macros
Constexpr.h # HASH_STR / ExprHashStringA (compile-time FNV1a)
Defs.h # Pre-computed module/API hashes, NaxHeader layout
Loader.h # Function prototypes for Stomp/Exec/Pe
Macros.h # FUNC, STARDUST_INSTANCE, MmCopy, MmZero
Native.h # NT structures (PEB, LDR, TEB, IMAGE_*)
Utils.h # HashString prototype
Ldr.h # LdrModulePeb, LdrFunction prototypes
scripts/
Linker.ld # Linker script for section ordering
loader.c # Dev launcher: load shellcode into RWX, execute
stomper.c # Dev launcher: load nax.bin, RX, CreateThread
Build
The loader is built as part of the top-level make from the repository root. It is compiled as C++ (x86_64-w64-mingw32-g++) to enable constexpr hash evaluation, then linked with a custom linker script and extracted as raw .text via objcopy.