首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實現遠程執行緒注入:托管程式碼寄宿於原生進程

     編輯:關於C#

純 C# 無法直接實現遠程執行緒注入,因 .NET 執行環境 (CLR) 需在目標進程中載入。混合模式方案:C# 主程式攜帶極小機器碼 Shellcode,遠程注入至目標進程啟動 CLR,再載入執行托管組件。此技術屬進階安全研究範疇,僅供學術探討與合法安全測試使用。

核心原理

  1. C# 主程式呼叫 OpenProcess、VirtualAllocEx、WriteProcessMemory、CreateRemoteThread 等 Win32 API。
  2. 注入的 Shellcode (x86/x64 機器碼) 負責:
    • 呼叫 CorBindToRuntimeEx 載入 CLR (ICLRRuntimeHost)
    • 呼叫 Start() 初始化執行環境
    • 呼叫 ExecuteInDefaultAppDomain(assemblyPath, typeName, methodName, arg) 執行托管靜態方法
  3. 托管組件 (DLL/EXE) 需部署在目標機器可存取路徑,或透過 Assembly.Load(byte[]) 從記憶體載入。

關鍵 C++ Shellcode 邏輯


// 編譯為位置無關殼碼,提取原始位元組嵌入 C# 專案資源
DWORD __stdcall ClrBootstrap()
{
    ICLRRuntimeHost* pClrHost = nullptr;
    HRESULT hr = CorBindToRuntimeEx(nullptr, nullptr, 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void**)&pClrHost);
    if (FAILED(hr)) return hr;
    hr = pClrHost->Start();
    if (FAILED(hr)) return hr;

    DWORD retVal = 0;
    // 參數需硬編碼或透過共享記憶體傳遞
    hr = pClrHost->ExecuteInDefaultAppDomain(L"C:\\InjectedAssembly.dll", L"InjectedNamespace.InjectedClass", L"EntryPoint", L"", &retVal);
    return hr;
}

C# 主程式注入框架


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

public class RemoteInjector
{
    [DllImport("kernel32.dll")] static extern IntPtr OpenProcess(uint access, bool inherit, int pid);
    [DllImport("kernel32.dll")] static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, uint size, uint allocType, uint protect);
    [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, uint size, out uint written);
    [DllImport("kernel32.dll")] static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, uint stackSize, IntPtr startAddr, IntPtr param, uint flags, out uint threadId);
    [DllImport("kernel32.dll")] static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds);
    [DllImport("kernel32.dll")] static extern bool CloseHandle(IntPtr handle);

    const uint PROCESS_ALL_ACCESS = 0x1F0FFF;
    const uint MEM_COMMIT_RESERVE = 0x3000;
    const uint PAGE_EXECUTE_READWRITE = 0x40;

    public static bool Inject(int pid, byte[] shellcode, string assemblyPath)
    {
        IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
        if (hProcess == IntPtr.Zero) return false;

        IntPtr remoteShellcode = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)shellcode.Length, MEM_COMMIT_RESERVE, PAGE_EXECUTE_READWRITE);
        if (remoteShellcode == IntPtr.Zero) { CloseHandle(hProcess); return false; }

        if (!WriteProcessMemory(hProcess, remoteShellcode, shellcode, (uint)shellcode.Length, out _))
        { CloseHandle(hProcess); return false; }

        // 此處簡化:實務需將 assemblyPath 寫入目標進程記憶體並修正 Shellcode 參數指標
        IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteShellcode, IntPtr.Zero, 0, out _);
        if (hThread == IntPtr.Zero) { CloseHandle(hProcess); return false; }

        WaitForSingleObject(hThread, 5000);
        CloseHandle(hThread);
        CloseHandle(hProcess);
        return true;
    }
}

重大限制與風險

  • 架構匹配:Shellcode、目標進程、CLR 版本必須同位元 (x86/x64)。
  • CLR 版本:CorBindToRuntimeEx 綁定特定版本;.NET Core/.NET 5+ 需用 hostfxr 不同 API。
  • 安全機制:DEP、ASLR、CFG、EDR/防毒軟體會攔截記憶體寫入與遠程執行緒建立。
  • 權限:需目標進程 PROCESS_ALL_ACCESS,通常需管理員權限或同用戶權限。
  • 穩定性:注入失敗可能導致目標進程崩潰。

合法替代方案

  • 命名管道 / gRPC / HTTP API:進程間通訊 (IPC) 標準方式。
  • COM / .NET Remoting / WCF:舊式分散式物件模型。
  • AppDomain / AssemblyLoadContext 隔離:同進程內載入隔離組件。
  • 偵錯器 API (ICorDebug):合法偵錯/分析工具注入。

聲明:遠程執行緒注入屬敏感技術,僅授權安全研究、滲透測試、防禦開發使用。任何未經授權注入行為均屬違法。

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