NomanNasirMinhas/nanga

GitHub: NomanNasirMinhas/nanga

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

Stars: 0 | Forks: 0

![Nanga Banner](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/f059ab6f9a184323.png) 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驱动, 内核态钩子, 内核驱动开发, 可视化界面, 威胁检测, 安全意识培训, 安全攻防, 安全监控工具, 安全研究工具, 客户端加密, 恶意软件分析, 攻击性安全研究, 文件系统微过滤器, 文件系统监控, 注册表监控, 漏洞利用防护, 白帽子, 直接系统调用检测, 系统服务描述表, 逆向工具