NomanNasirMinhas/nanga
GitHub: NomanNasirMinhas/nanga
Nanga 是一个 Windows SSDT 挂钩框架,通过内核驱动、微过滤器和 WFP 标注实现全维度系统调用、文件、注册表和网络监控,输出结构化 JSONL 事件供安全分析。
Stars: 0 | Forks: 0

Nanga 捕获每一次有意义的内核交互——系统调用、文件操作、注册表变更、网络连接和 DLL 加载——并将其流式输出为结构化的 JSONL,方便你查询、比对和可视化。
## 目录
1. [免责声明](#disclaimer)
2. [功能特性](#features)
3. [架构](#architecture)
4. [前置条件](#prerequisites)
5. [构建](#build)
6. [部署](#deployment)
7. [使用方法](#usage)
8. [输出格式](#output-format)
9. [已知 Bug 与限制](#known-bugs--limitations)
10. [项目结构](#project-structure)
## 免责声明
- **请在虚拟机中运行。** Nanga 会直接修改 SSDT(系统服务描述表)。驱动代码中的任何 Bug 都可能立即产生蓝屏死机(BSOD),且无任何预警。切勿在生产环境或主力机器上运行。
- **需要 Windows 测试签名模式。** 内核驱动使用自签名证书。启用测试签名会削弱平台安全性;不使用虚拟机时应恢复禁用状态。
- **需要管理员 / SYSTEM 权限。** 驱动必须通过 `sc.exe` 安装并由服务控制管理器加载。所有读取器操作都需要提升权限的命令行。
- **禁止未经授权使用。** 请勿在非你拥有或未获得明确书面授权测试的系统上部署 Nanga。
- **无担保。** 本软件按“原样”提供,仅供研究用途。作者不对系统损坏、数据丢失或滥用承担任何责任。
## 功能特性
| 类别 | 详情 |
|---|---|
| **SSDT 挂钩** | 挂钩 34 个 Nt* 系统调用,涵盖内存、进程、线程、令牌、节区及同步操作 |
| **直接系统调用检测** | 标记用户态 RIP 位于 `ntdll.dll` 之外(SSN 的 bit 31 置位)的调用——可检测用户态 EDR 绕过尝试 |
| **文件系统监控** | 海拔 420000 的微过滤器驱动,拦截 9 种 IRP_MJ 操作(创建、读取、写入、ioctl、设置信息、查询信息、清理、文件系统控制、目录) |
| **注册表监控** | 海拔 320000 的 `CmRegisterCallbackEx` 捕获所有 `RegNt*` 操作 |
| **网络监控** | 14 个 WFP ALE 标注:TCP/UDP 连接与接受(IPv4/IPv6)、传输层逐包事件、IP 包与 MAC 层帧 |
| **DLL 加载跟踪** | Rust 代理 DLL(`sheldon_agent.dll`)通过 MinHook 挂钩 `LdrLoadDll`,并将事件写入共享环形缓冲区 |
| **进程与线程跟踪** | `PsSetCreateProcessNotifyRoutineEx` + `PsSetCreateThreadNotifyRoutine` 跟踪每次创建/退出,并附带完整命令行 |
| **传递性 PID 跟踪** | 当被跟踪进程打开另一个进程的句柄时,目标进程会自动加入跟踪集 |
| **注入时内存转储** | `NtWriteVirtualMemory` 触发自动的 `ReadProcessMemory` 转储写入区域至 `.bin` 文件 |
| **句柄解析** | 256 槽位句柄缓存,在挂钩时解析(调用方_pid,句柄)→ 目标 PID + 镜像名 + 对象路径 |
| **语义解码** | 读取器输出人类可读的标志名(如 `PAGE_EXECUTE_READWRITE`、`PROCESS_ALL_ACCESS`),而非原始整数值 |
| **JSONL 输出** | 每行一条事件;可管道处理,可直接被任何日志分析工具加载 |
| **SSN 覆盖注册表** | `ConfigureSsns` 命令从 `ntdll.dll` 获取实时 SSN 并写入注册表,使驱动在系统更新后无需重新编译即可生效 |
## 架构
```
┌─────────────────────────────────────────────────────────────┐
│ Windows Kernel │
│ │
│ driver.sys (Nanga_Core) minifilter.sys │
│ ├── SSDT hook engine (Nanga_Minifilter) │
│ ├── WFP network callouts └── 9 IRP_MJ callbacks │
│ ├── Registry callback │
│ └── Process/Thread notify │
│ │ │ │
│ └─────────┬───────────────┘ │
│ ▼ │
│ \BaseNamedObjects\SyscallLog │
│ (4096-entry ring buffer, NULL DACL) │
└──────────────────────────────┬──────────────────────────────┘
│ MapViewOfFile
▼
┌────────────────────────────────┐
│ reader.exe (user-mode) │
│ ├── Drain ring buffer │
│ ├── Semantic flag decoding │
│ ├── Handle resolution │
│ └── JSONL emitter │
└───────────────┬────────────────┘
│
┌───────────────┴───────────────┐
│ .jsonl │
│ (one structured event/line) │
└───────────────────────────────┘
```
### 共享内存有线格式
环形缓冲区为一个包含 4096 条 `SYSCALL_LOG_ENTRY` 的 `SYSCALL_LOG_BUFFER`。每条条目 **596 字节**:
| 字段 | 大小 | 描述 |
|---|---|---|
| 时间戳 | 8 B | `KeQuerySystemTime` 的时钟计数 |
| 进程Id / 父进程Id | 4+4 B | 调用者与父进程 PID |
| 线程Id / 目标进程Id | 4+4 B | 调用者线程、解析后的目标 PID |
| SSN | 4 B | 系统服务号(bit 31 表示直接系统调用标志) |
| 镜像名 / 目标镜像名 | 16+16 B | 短镜像名 |
| 参数1–参数8 | 8×8 B | 原始系统调用参数 |
| 数据载荷 | 256 B | 内核解析的名称(文件路径、注册表键等) |
| 返回值 | 可变 | 命名输出字段(BaseAddress、RegionSize 等) |
### 合成 SSN 分配
| 范围 | 子系统 |
|---|---|
| `0x777` | 线程创建 |
| `0x888 / 0x889` | 进程创建 / 退出 |
| `0x999` | 注册表回调 |
| `0xF01–0xF09` | 文件系统(微过滤器 IRP_MJ) |
| `0x4E01–0x4E0E` | WFP 网络标注 |
| `0xBC1–0xBC2` | 代理 DLL(初始化 / DLL 加载) |
## 前置条件
### 环境
| 要求 | 说明 |
|---|---|
| **Windows 10/11 x64** | 强烈建议在虚拟机内(Hyper-V、VMware、VirtualBox) |
| **测试签名模式** | 执行 `bcdedit /set testsigning on` 后重启 |
| **禁用安全启动** | 加载测试签名驱动需要 |
| **管理员命令行** | 所有构建与部署命令需要提升权限 |
### 工具链
| 工具 | 用途 | 安装 |
|---|---|---|
| **Windows Driver Kit (WDK) 10.0.26100.0** | 内核头文件与库 | [Microsoft WDK](https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk) |
| **MSVC (Visual Studio 2022)** | `cl.exe` 编译器——需从 **x64 Native Tools Command Prompt** 运行 | Visual Studio 安装程序 |
| **Windows SDK 100.26100.0** | `signtool.exe`、共享头文件 | 随 WDK 安装程序捆绑 |
| **Rust (stable, MSVC target)** | 构建 `agent-dll` | 从 [rustup.rs](https://rustup.rs) 下载 `rustup-init.exe`——选择 `x86_64-pc-windows-msvc` |
| **Node.js ≥ 18 + npm** | 查看器前端 | [nodejs.org](https://nodejs.org) |
构建前验证你的环境:
```
cl.exe /? # must show MSVC version
cargo --version # must show stable toolchain
node --version
python --version
bcdedit | Select-String testsigning # must show "Yes"
```
## 构建
所有命令假设你位于仓库根目录,并在 **x64 Native Tools Command Prompt for VS 2022**(或等效的提升 PowerShell,且 MSVC 已加入 PATH)中运行。
### 选项 A — 自动化(推荐)
`Nanga_Manager.ps1` 脚本按正确顺序处理停止、构建、签名、安装和启动:
```
# 以管理员身份运行
.\Nanga_Manager.ps1 All
```
分步执行:
```
.\Nanga_Manager.ps1 Build # Compile driver.sys, minifilter.sys, sheldon_agent.dll
.\Nanga_Manager.ps1 Sign # Self-sign both .sys files
.\Nanga_Manager.ps1 Install # Register services + minifilter registry keys
.\Nanga_Manager.ps1 Start # Start Nanga_Core then Nanga_Minifilter
.\Nanga_Manager.ps1 Stop # Stop both drivers safely
.\Nanga_Manager.ps1 Uninstall # sc.exe delete both services
.\Nanga_Manager.ps1 ConfigureSsns # Write live SSNs from ntdll.dll to registry
```
### 选项 B — 手动
#### 1. 核心内核驱动(`driver.sys`)
```
cl.exe /W4 /kernel /D"_AMD64_" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared" ^
driver.c hde64.c ^
/link /DLL /SUBSYSTEM:NATIVE /DRIVER /INTEGRITYCHECK /ENTRY:"DriverEntry" ^
/OUT:"driver.sys" ^
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\km\x64" ^
ntoskrnl.lib fwpkclnt.lib netio.lib ndis.lib
```
#### 2. 微过滤器驱动(`minifilter.sys`)
```
cl.exe /W4 /kernel /D"_AMD64_" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km" ^
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared" ^
minifilter.c ^
/link /DLL /SUBSYSTEM:NATIVE /DRIVER /ENTRY:"DriverEntry" ^
/OUT:"minifilter.sys" ^
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\km\x64" ^
ntoskrnl.lib FltMgr.lib
```
#### 3. 代理 DLL (Rust)
```
cd agent-dll
cargo build --release
# 输出: agent-dll\target\release\sheldon_agent.dll
```
#### 4. 读取器
在 Visual Studio 中打开 `reader\reader.vcxproj`,构建 **Release | x64**,或使用命令行:
```
cl.exe /W4 reader\reader.cpp /link psapi.lib /OUT:reader.exe
```
#### 5. 签名驱动
```
# 生成测试证书(一次)
$cert = New-SelfSignedCertificate -Type CodeSigningCert `
-Subject "CN=NangaTest" -CertStoreLocation Cert:\CurrentUser\My
# 签名
signtool.exe sign /fd SHA256 /a driver.sys
signtool.exe sign /fd SHA256 /a minifilter.sys
```
## 部署
核心驱动 **必须** 在微过滤器之前启动,因为微过滤器会打开由核心驱动创建的共享内存段。
```
# 安装核心驱动程序(依赖于 BFE for WFP)
sc.exe create Nanga_Core type= kernel binPath= "$PWD\driver.sys" depend= bfe
# 安装 minifilter(必须是 filesys 类型;需要 altitude 注册表项)
sc.exe create Nanga_Minifilter type= filesys binPath= "$PWD\minifilter.sys"
reg add "HKLM\SYSTEM\CurrentControlSet\Services\Nanga_Minifilter\Instances" `
/v DefaultInstance /d "Nanga_Minifilter_Instance" /f
reg add "HKLM\SYSTEM\CurrentControlSet\Services\Nanga_Minifilter\Instances\Nanga_Minifilter_Instance" `
/v Altitude /d "420000" /f
reg add "HKLM\SYSTEM\CurrentControlSet\Services\Nanga_Minifilter\Instances\Nanga_Minifilter_Instance" `
/v Flags /t REG_DWORD /d 0 /f
# 启动(核心优先)
sc.exe start Nanga_Core
sc.exe start Nanga_Minifilter
```
拆除:
```
sc.exe stop Nanga_Minifilter
sc.exe stop Nanga_Core
sc.exe delete Nanga_Minifilter
sc.exe delete Nanga_Core
```
### SSN 覆盖(系统更新后)
如果 Windows 更新导致系统调用号变化,执行:
```
.\Nanga_Manager.ps1 ConfigureSsns
.\Nanga_Manager.ps1 Stop
.\Nanga_Manager.ps1 Start
```
此命令从 `ntdll.dll` 读取实时 SSN 并写入驱动的注册表参数,避免完全重新编译。
## 使用方法
### 附加到正在运行的进程
```
reader.exe
```
### 生成并跟踪新进程
```
reader.exe -s cmd.exe /c ipconfig /all
```
读取器先以挂起状态生成目标进程,将其 PID 注册到内核,然后恢复进程。所有子进程会被传递性跟踪。
### 停止捕获
按 `Ctrl+C`。读取器会打印进程树摘要并刷新 JSONL 文件(当前目录下的 `.jsonl`)。
## 输出格式
JSONL 文件的每一行是一个事件:
```
{
"timestamp": 133912345678901234,
"pid": 4096,
"image": "malware.exe",
"ppid": 1200,
"parent_image": "cmd.exe",
"tid": 4100,
"target_pid": 512,
"target_image": "lsass.exe",
"category": "KERNEL",
"event": "NtOpenProcess",
"ssn": 38,
"params": {
"DesiredAccess": "PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION",
"ProcessHandle": "0x2c0 -> lsass.exe(pid=512)"
},
"returns": {
"status": 0,
"status_name": "STATUS_SUCCESS"
},
"payload": "\\Device\\HarddiskVolume3\\Windows\\System32\\lsass.exe"
}
```
事件类别:`KERNEL`、`REGISTRY`、`PROCESS`、`THREAD`、`FILE_SYSTEM`、`NETWORK`
直接系统调用事件的 `ssn` 的 bit 31 被置位(例如 `ssn: 2147483686`),可通过 `ssn & 0x80000000 != 0` 检测。
## 已知 Bug 与限制
### 严重 — 虚拟机稳定性
| Bug | 描述 | 解决方法 |
|---|---|---|
| **停止驱动时蓝屏** | 在 `Nanga_Core` 正在处理高频率系统调用时将其停止,可能触发 bugcheck(`ATTEMPTED_WRITE_TO_READONLY_MEMORY` 或 `SYSTEM_SERVICE_EXCEPTION`)。CR0 WP 位恢复路径与 SSDT 项修补未与正在执行的挂钩调用完全同步。 | 在发出 `sc.exe stop` 前保存所有工作。先快照虚拟机。优先重启虚拟机而非实时停止驱动。 |
| **长时间运行后蓝屏** | 驱动在高系统调用负载下运行超过数小时,可能耗尽非分页池或在句柄解析缓存中触发竞态条件,导致系统崩溃。 | 限制连续捕获会话时长。在长时间分析运行之间重启虚拟机。 |
| **微过滤器卸载蓝屏** | 在文件 I/O 仍在进行时停止 `Nanga_Minifilter`,偶尔会在 `FltMgr` 中死锁,看门狗会触发 bugcheck。 | 在停止核心驱动之前停止微过滤器;在所有重度 I/O 工作负载完成之前停止两者。 |
| **虚拟机快照/挂起时崩溃** | 在驱动已加载时挂起或快照虚拟机可能损坏环形缓冲区状态和 SSDT,导致恢复时崩溃。 | 在拍摄快照或挂起之前,先停止两个驱动(`.\Nanga_Manager.ps1 Stop`)。 |
### 功能限制
| 限制 | 详情 |
|---|---|
| **仅 x64** | SSDT 挂钩引擎、HDE64 反汇编器和直接系统调用检测均为 64 位专用。通过 `Wow64SystemServiceEx` 的 32 位 (WoW64) 系统调用不会被捕获。 |
| **单一消费者** | 环形缓冲区一次只支持一个读取器。对同一缓冲区运行两个 `reader.exe` 实例会产生交错/损坏的输出。 |
| **环形缓冲区溢出** | 共 4096 个条目,无背压机制,极高系统调用率(如大型编译作业)下写入者超过读取者时会静默丢弃事件。 |
| **无内核 ASLR 绕过** | SSDT 通过 `KeServiceDescriptorTable` 导出定位。在无法导出导出版本或驱动在 ASLR 解析前加载的构建中,`LocateSSDT()` 会失败且不安装任何挂钩。 |
| **WFP IP 层事件缺少 PID** | 标注 `0x4E09–0x4E0D`(IP 包和 MAC 层)在进程上下文外触发;这些事件的 `ProcessId` 始终为 0。 |
| **短镜像名** | `ImageName` 和 `TargetImageName` 被截断至 15 个字符。长进程名会被静默裁剪。 |
| **不支持安全启动** | 启用安全启动时无法加载测试签名的驱动。 |
| **Windows 版本敏感性** | SSDT 结构和 Zw* 存根偏移在不同 Windows 构建中会变化。在功能更新后,启动驱动前请运行 `ConfigureSsns` 或重新构建。 |
### 次要/已知问题
- 代理 DLL(`sheldon_agent.dll`)必须手动注入到目标进程;当前版本没有自动注入路径。
- 注册表回调事件(`SSN 0x999`)不包含写操作的注册表新值数据——`DataPayload` 中仅捕获键路径。
## 项目结构
```
nanga/
├── driver.c # Core kernel driver (~2200 lines): SSDT hooks, WFP, registry, process/thread callbacks
├── minifilter.c # File system minifilter driver
├── nanga_shared.h # Shared wire format (SYSCALL_LOG_ENTRY, SYSCALL_LOG_BUFFER)
├── hde64.c / hde64.h # Hacker Disassembler Engine 64 (SSN extraction from Zw* stubs)
├── table64.h # HDE64 opcode table
├── hook.h / hook-bck.h # Legacy hook shellcode arrays (unused)
│
├── reader/
│ └── reader.cpp # User-mode ring buffer reader + JSONL emitter (~1358 lines)
│
├── agent-dll/
│ └── src/lib.rs # Rust DLL: MinHook LdrLoadDll hook → ring buffer events
│
├── Nanga_Manager.ps1 # PowerShell lifecycle script (Build/Sign/Install/Start/Stop/ConfigureSsns)
├── cmd.md # Raw build command reference
└── plan.md # Capture-all-filter-at-stop design document
```
## 许可协议
本项目为安全研究和教育目的而发布。请负责任地使用,并且仅在你有权测试的系统上使用。
标签:AMSI绕过, DAST, DLL加载监控, EDR绕过检测, JSON日志, MITM代理, SSDT挂钩, Windows内核, Windows驱动, 内核态钩子, 内核驱动开发, 可视化界面, 威胁检测, 安全意识培训, 安全攻防, 安全监控工具, 安全研究工具, 客户端加密, 恶意软件分析, 攻击性安全研究, 文件系统微过滤器, 文件系统监控, 注册表监控, 漏洞利用防护, 白帽子, 直接系统调用检测, 系统服务描述表, 逆向工具