0xsp-SRD/aether

GitHub: 0xsp-SRD/aether

Aether是一款用于Windows内存取证和威胁狩猎的工具,可检测恶意行为和注入技术。

Stars: 28 | Forks: 1

Aether logo


# 以太 版本:0.8(公开测试版) **Aether** 是一款Windows内存取证和威胁狩猎工具,它扫描实时进程内存以查找恶意模式、检测注入技术、植入签名、反射加载.NET程序集。它使用多层置信度模型,显著降低误报率并寻找恶意行为。Aether在检测Hollowing、APC、线程劫持技术方面具有良好能力。安全分析师可以使用它扫描、狩猎并快照可疑区域以进行离线分析。 ## 核心功能 以下是Aether核心功能的简要说明,您可以阅读完整的技术博客文章以获取更多信息: ### 签名扫描 - 在进程内存中进行**字节模式匹配**,使用**首字节索引**,比简单的扫描快50-100倍 - **ASCII + UTF-16LE双编码** — 捕获.NET CLR存储的字符串(例如,“msxsl:script”变为`6D 00 73 00 78 00 ...`) - 从JSON文件中**动态加载规则** — 将新签名放入`rules/`而无需重新编译 - 在`MEM_PRIVATE`区域中进行`PE头检测` — 标记反射加载.NET程序集(`MZ` + `PE` + `BSJB`元数据) ### 结构化内存IOCs Aether在原始工作集信号上**叠加五层过滤器**,因此一个发现需要多个一致指标才能报告,并带有FP过滤: | 层 | 过滤器 | 目的 | |-------|--------|---------| | **L1** | 结构化 | 仅考虑**可执行**IMAGE子区域(消除`.data` / `.rdata` COW噪声) | | **L2** | 定量 | 通过`private_pages`计数和`private_ratio`(低/中/高)进行评分 | | **L3** | 协同 | 只有当**独立**信号在相同的分配基上达成一致时才提升 — 签名命中、`missing_peb_entry`、`private_rwx`、钩子前缀、或磁盘差异 | | **L4** | CLR感知 | 对ngen / R2R / tiered-JIT目标(`*.ni.dll`、`mscor*`、`clr*`、`coreclr`、`system.private.corelib*`)进行模块级抑制,而不是在CLR加载时跳过所有内容 | | **L5** | 磁盘差异 | 使用`CreateFileMappingW(SEC_IMAGE_NO_EXECUTE)`映射模块文件;将每个私有可执行页的前16字节与磁盘上的相同RVA进行比较。任何差异都是真实的修改IOCs | 其他结构化检查: - **PEB模块交叉引用**:不在PEB模块列表中的`MEM_IMAGE`分配(DLL空心化/模块踩踏) - **工作集扫描**:通过`K32QueryWorkingSetEx`检测修改后的代码页,**批量**处理每个区域的单个系统调用,而不是每个4 KB页(比简单的循环快50-100倍) - **私有RWX检测**:标记`MEM_PRIVATE + PAGE_EXECUTE_*`(它会产生误报)分配(shellcode、JIT喷洒、动态代码占位符分配) - **钩子前缀探测** — 读取每个私有代码页的前16字节并匹配经典的x86/x64跳板: - `E9 ?? ?? ?? ??` — `JMP rel32` - `FF 25 ?? ?? ?? ??` — `JMP [rip+disp32]` - `68 ?? ?? ?? ?? C3` — `PUSH imm32 ; RET` - `48 B8 ?? ?? ?? ?? ?? ?? ?? ?? FF E0` — `MOV RAX, imm64 ; JMP RAX` - `49 BB ?? ?? ?? ?? ?? ?? ?? ?? 41 FF E3` — Detours风格的`MOV R11, imm64 ; JMP R11` - **CLR检测** — 对`Cor_Private_IPCBlock_v4_`部分进行节对象探测*和* v2 `Cor_Private_IPCBlock_`(旧.NET 2/3 / mscorwks),因此运行旧运行时的嘈杂应用程序池不会被错误分类 ### 线程启动地址验证(TSAV / L8) Aether对线程进行更严格的分类,并与L1–L5发现进行交叉相关。对于目标进程创建的每个线程,Aether通过`NtQueryInformationThread`读取其`Win32StartAddress`,当访问允许时,也通过`GetThreadContext` / `Wow64GetThreadContext`读取其实时`Rip` / `Eip`。 每个地址都按以下表格进行评分,更多详情请阅读博客文章: | 判决 | 严重性 | 条件 | |---------|----------|-----------| | `TSAV_SHELLCODE_PRIVATE` | CRITICAL | 地址位于`MEM_PRIVATE + PAGE_EXECUTE_*`区域 — 经典的`CreateRemoteThread`shellcode | | `TSAV_SUSPENDED_RIP` | CRITICAL | 暂停线程的`Rip` / `Eip`与`Win32StartAddress`不一致,并解析为可疑区域 — 捕获`Win32StartAddress`欺骗(EarlyBird / APC技巧)和`SetThreadContext`劫持 | | `TSAV_HOLLOWED_HOST` | HIGH | 地址位于不在PEB模块列表中的`MEM_IMAGE`分配(DLL空心化/模块踩踏) | | `TSAV_MODIFIED_HOST` | HIGH | 地址位于L1–L5管道已标记为`MODIFIED_CODE_*`、`MISSING_PEB`、`PRIVATE_RWX`、`DISK_MEM_DIFF`或`HOOK_PROLOGUE`的分配 | | `TSAV_STAGED_PRIVATE_RW` | HIGH | `MEM_PRIVATE + PAGE_READWRITE` — `VirtualProtect`之前的shellcode阶段 | | `TSAV_MAPPED_NONPE` | MEDIUM | `MEM_MAPPED`(页面文件支持的节)没有PE头 — sRDI / 页面文件反射加载器 | | `TSAV_SPOOF_TRAMPOLINE` | MEDIUM | 线程`Win32StartAddress`等于拒绝列表中的跳板(`LoadLibraryA/W/ExA/W`、`WinExec`、`CreateProcessA/W`、`VirtualAlloc[Ex]`、`RtlExitUserThread`、`RtlExitUserProcess`、`NtTerminateProcess`、`ShellExecuteA/W`) | 与基本检查“启动地址是否在任何模块中”相比,使其更强大的原因: - **`VirtualQueryEx`交叉检查** — 每个地址都通过单个O(1)调用查询`Type` / `Protect` / `AllocationBase`,而不是在模块列表中进行线性扫描 - **与L1–L5的交叉相关** — 启动地址落在已标记分配中的线程从“OK”升级到`TSAV_MODIFIED_HOST` - **PEB一致性** — 即使启动地址在技术上落在“真实”范围内,也能检测到空心化模块 - **暂停-Rip探测** — `Win32StartAddress`可以通过`NtSetInformationThread`写入进程,并且是可欺骗的字段;暂停线程的实时`Rip`是加载器难以重写的。我们比较这两个,并标记任何解析为可疑区域的任何不一致 - **WoW64感知** — 自动切换到`Wow64GetThreadContext`并读取64位进程中的32位线程的`Eip` - **访问权限级** — 每个线程回退到`QUERY_INFORMATION | GET_CONTEXT` → `QUERY_INFORMATION` → `QUERY_LIMITED_INFORMATION`,因此部分访问场景仍然产生有用的分类 ### 混沌分析与Shellcode启发式方法 Aether目前支持在占位符级别进行XOR检测模式,并采用Shannon熵算法检查内存区域中字节的随机性,它标记所有高于阈值的项。为了解决高误报率,Aether使用多个指标。 ### C2信标检测 - **TCP连接监控** — 轮询`GetExtendedTcpTable`以获取目标PID - **信标模式检测** — 识别周期性短暂连接(经典的C2回调行为) - **连接表输出** — 格式化的控制台表,包含状态、端点、命中和协议 ### 输出模式 - **基于严重性的彩色控制台报告**,使用ANSI高亮显示 - **可由机器解析的JSON**,用于SIEM / d-tect.py管道集成 - **分级怀疑输出** — 每个`MODIFIED_CODE_*`发现都携带`private_pages`和`region_pages`,以便分类具有实际数字 - **使用Unicode框绘制字符的表格格式输出**,用于连接监控 ## 怀疑类型 ### 修改代码管道(L1–L5) | 标签 | 严重性 | 含义 | |-------|----------|---------| | `MODIFIED_CODE_HIGH` | HIGH | 具有钩子前缀、磁盘差异或≥ 25 %私有页比的可执行IMAGE页面 | | `MODIFIED_CODE_MED` | MEDIUM | 由另一个信号证实,或≥ 5 %比率,或≥ 8个私有页 | | `HOOK_PROLOGUE` | MEDIUM | 在私有代码页的起始位置找到跳板字节模式 | | `DISK_MEM_DIFF` | HIGH | 可执行私有页的前16字节与磁盘上的映像不同 | | `MISSING_PEB` | HIGH | `MEM_IMAGE`分配不在PEB模块列表中(DLL空心化) | | `PRIVATE_RWX` | HIGH | 具有可执行保护的私有内存 | | `CLR_INIT` | INFO | 目标进程托管.NET CLR(过滤提示,不是发现) | ### 线程启动地址验证(L8) | 标签 | 严重性 | 含义 | |-------|----------|---------| | `TSAV_SHELLCODE_PRIVATE` | CRITICAL | 线程在`MEM_PRIVATE + PAGE_EXECUTE_*`(经典shellcode线程)启动 | | `TSAV_SUSPENDED_RIP` | CRITICAL | 暂停线程的`Rip` / `Eip`解析为与`Win32StartAddress`不一致的可疑区域 | | `TSAV_HOLLOWED_HOST` | HIGH | 线程在PEB中缺失的`MEM_IMAGE`分配中启动 | | `TSAV_MODIFIED_HOST` | HIGH | 线程在L1–L5已标记的分配中启动 | | `TSAV_STAGED_PRIVATE_RW` | HIGH | 线程在`MEM_PRIVATE + PAGE_READWRITE`(`VirtualProtect`之前的阶段)启动 | | `TSAV_MAPPED_NONPE` | MEDIUM | 线程在`MEM_MAPPED`非PE节中启动 | | `TSAV_SPOOF_TRAMPOLINE` | MEDIUM | 线程`Win32StartAddress`等于拒绝列表中的跳板(`LoadLibraryW`、`RtlExitUserThread`等) | | `THREAD_START_ANOMALY` | HIGH | 每个扫描的每个可疑线程的聚合计数 | ### 加密有效负载检测 | 标签 | 严重性 | 含义 | |-------|----------|---------| | `XOR_PE_HEADER` | CRITICAL | 在单字节或多字节XOR下找到PE头;DOS占位符锚点+ `MZ` / `e_lfanew` / `PE\0\0`一致性检查全部通过(Donut、CS `sleep_mask`、Sliver、sRDI) | ## 规则包 签名组织到JSON规则包中。将这些中的任何一个放入`rules/`目录: | 文件 | 覆盖范围 | |------|----------| | `cobalt_strike.json` | Cobalt Strike信标工件 | | `meterpreter.json` | Metasploit Meterpreter植入 | | `sliver.json` | Sliver C2植入(BishopFox) | | `brute_ratel.json` | Brute Ratel C4獾 | | `havoc.json` | Havoc C2恶魔 | | `sharp_tools.json` | .NET攻击工具(Rubeus、Seatbelt、SharpHound) | | `mimikatz.json` | Mimikatz凭证盗窃 | | `powershell_cradles.json` | PowerShell攻击支架 & AMSI绕过 | | `dotnet_loaders.json` | 通用.NET加载器和注入器 | | `mythic_poshc2.json` | Mythic / PoshC2 / Nighthawk植入 | | `phantom_str.json` | Phantom ASP .NET加载器 | 每个规则文件都是一个签名对象的JSON数组: ``` [ { "pattern": "msxsl:script", "weight": 5, "category": "engine_xslt", "description": "XSLT script block declaration" } ] ``` `category`映射到以下之一:`engine_xslt`、`engine_codedom`、`engine_managed`、`c2_tcp`、`c2_http`、`c2_sql`、`c2_smtp`、`c2_file`、`c2_dns`、`evasion`、`reflective_load`、`webshell_generic`。 ## 使用方法 ``` Aether.exe --scan --pid [OPTIONS] Aether.exe --scan --lookup "ProcessName.exe" Aether.exe --hunt SLEEP_MS PERIOD Aether.exe --scan-all [OPTIONS] ``` ### 选项 | 标志 | 描述 | |------|-------------| | `--pid`,`-p ` | 要扫描的目标进程ID | | `--lookup`,`-l ` | 查找匹配进程名的所有PID | | `--json`,`-j` | 将结果输出为JSON(用于SIEM集成) | | `--verbose`,`-v` | 显示每个区域的扫描细节 | | `--scan-all`,`-a` | 扫描所有进程 | | `--hunt`,`-b [ms] [hits]` | 监控连接 — 每ms`轮询一次(默认2000),标记出现≥ `hits`次出现的端点 | | `--networking` | 网络监控模式 | | `--rules`,`-r ` | 规则目录(默认:`rules/`) | | `--config`,`-c ` | 单个规则文件(旧格式) | | `--help`,`-h` | 显示帮助 | ## 示例输出 ### 控制台报告 ``` Scan Results for PID 4820 ================================================== Regions: 847 total, 312 scanned, 287 system-skipped Bytes scanned: 214.35 MB Read errors: 3 Scan time: 1247 ms [HIGH] ENGINE_XSLT | score=18 hits=4 [T1220] +5 "msxsl:script" @ 0x7FFE2A3B1000 (ascii) +6 "urn:payload" @ 0x7FFE2A3B1200 (ascii) +4 "enableScript" @ 0x7FFE2A3B1400 (utf16le) +3 "XsltSettings" @ 0x7FFE2A3B1600 (ascii) [CRITICAL] REFLECTIVE_LOAD | 2 PE headers in MEM_PRIVATE (1 with .NET BSJB metadata) [T1620] ---- Structural IOCs (8) ---- [HIGH] MISSING_PEB @ 0x000001D6E0000000 (1048576 bytes) [HIGH] DISK_MEM_DIFF @ 0x000001D6E0001000 (4 private / 240 pages) [HIGH] MODIFIED_CODE_HIGH @ 0x000001D6E0001000 (4 private / 240 pages) [HIGH] PRIVATE_RWX @ 0x000001D6EDDD0000 (12288 bytes) [CRITICAL] XOR_PE_HEADER @ 0x000001D6EDDD0000 (4 bytes) [CRITICAL] TSAV_SHELLCODE_PRIVATE @ 0x000001D6EDDD0000 (8472 bytes) [HIGH] TSAV_MODIFIED_HOST @ 0x000001D6E0001000 (8476 bytes) [HIGH] THREAD_START_ANOMALY @ 0x0 (2 bytes) ``` 使用`--verbose`还可以看到每个线程的详细信息和恢复的XOR密钥: ``` [!] XOR_PE_HEADER @ 0x1D6EDDD0000 key_len=4 key=AABBCCDD [!] TID:8472 SHELLCODE_PRIVATE start=0x1D6EDDD0150 [!] TID:8476 MODIFIED_HOST start=0x1D6E0001A80 host=msi.dll ``` 恢复的密钥字节可以传递给一个单行命令(`python -c 'import sys; k=bytes.fromhex("AABBCCDD"); d=sys.stdin.buffer.read(); sys.stdout.buffer.write(bytes(b^k[i%len(k)] for i,b in enumerate(d)))'`)以转储解密后的PE进行分析。 ## 如何编译 ### 预先条件 - **Zig 0.16** — [在此下载](https://ziglang.org/download/) - 从任何宿主操作系统(Linux、macOS、Windows)进行交叉编译 ### 构建 ``` git clone https://github.com/0xsp-SRD/aether cd aether # 调试构建(启用安全检查) zig build # 发布构建(更小,更快二进制) zig build -Doptimize=ReleaseSafe # 或者 zig build -Doptimize=ReleaseFast ``` 构建的可执行文件位于`zig-out/bin/Aether.exe`。 ### 部署 如果您想执行额外的签名扫描,请将`zig-out/bin/Aether.exe`和`rules/`目录复制到目标Windows机器。如果目标进程需要管理员权限,则需要以管理员权限运行Aether.exe。 ## 局限性 - **仅用户模式** — 没有内核驱动程序;无法检测rootkits或内核级操作 - **仅IPv4** — TCP连接监控目前不支持IPv6端点。 - **L5磁盘差异需要文件访问** — 如果原始模块文件已被删除或被锁定,则磁盘差异将静默跳过该模块(其他层仍然运行) - **TSAV欺骗跳板列表在扫描器自己的进程中解析** — 捕获系统DLL共享ASLR基会话范围的常见情况,但可能错过具有独特进程基的靶标(Win10+上很少见) - **TSAV Rip探测仅捕获暂停线程** — 在探测时已运行的线程上的`Win32StartAddress`重写只能检测到线程恰好在一个等待时被挂起(与Moneta相同的约束) - **XOR-PE检测在此版本中是基本的** ## 许可证
标签:APC 技术, Hollowing 技术, JARM, .NET 集成, PE 头检测, RFI远程文件包含, SecList, Windows 安全, 低误报率, 内存分析, 内存取证, 动态规则加载, 多人体追踪, 多层级置信模型, 安全分析工具, 安全响应, 注入技术, 端点可见性, 签名扫描, 线程劫持, 结构化内存 IOCs