You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中利用已有Token创建线程并执行Shellcode?

可行实现方法及简便方案

方法一:调整SetThreadToken的调用时机与参数

你之前用CreateThread+SetThreadToken失败,大概率是线程已启动后才设置Token,或是参数配置错误。正确流程如下:

  • 调用CreateThread时传入CREATE_SUSPENDED标志,创建挂起状态的线程
  • 立即调用SetThreadToken给这个挂起线程关联目标Token
  • 最后调用ResumeThread恢复线程执行,此时Shellcode会在Token对应的上下文里运行

注意:调用SetThreadToken需要当前进程持有SE_IMPERSONATE_NAME权限,需提前确保该权限已启用。

示例伪代码(C#):

const uint CREATE_SUSPENDED = 0x00000004;
IntPtr hThread = CreateThread(IntPtr.Zero, 0, shellcodePtr, IntPtr.Zero, CREATE_SUSPENDED, out uint threadId);
if (hThread != IntPtr.Zero)
{
    bool success = SetThreadToken(ref hThread, hSystemtoken);
    if (success)
    {
        ResumeThread(hThread);
    }
    // 后续资源清理逻辑
}

方法二:通过CreateProcessWithTokenW启动进程后注入Shellcode

这是更稳妥的方案,毕竟你已能成功调用CreateProcessWithTokenW。步骤如下:

  1. 调用CreateProcessWithTokenW启动挂起状态的进程(如cmd.exe或notepad.exe,传入CREATE_SUSPENDED标志)
  2. 获取新进程的主线程句柄与进程句柄
  3. 用VirtualAllocEx在目标进程内存中分配可执行的内存区域
  4. 通过WriteProcessMemory将Shellcode写入该内存区域
  5. 调用SetThreadContext修改主线程的RIP(x64)或EIP(x86)指向Shellcode地址
  6. 调用ResumeThread恢复进程执行,Shellcode会在目标Token的上下文里运行

该方案兼容性更强,新进程完全处于目标Token的安全上下文下,无需处理当前进程的权限限制。

方法三:用ImpersonateLoggedOnUser在当前线程模拟Token后执行Shellcode

若无需跨线程执行,可直接在当前线程模拟目标Token后运行Shellcode:

  • 调用ImpersonateLoggedOnUser(hSystemtoken)开启模拟
  • 用Marshal.GetDelegateForFunctionPointer将Shellcode转换为委托并调用
  • 执行完成后调用RevertToSelf取消模拟

示例伪代码(C#):

if (ImpersonateLoggedOnUser(hSystemtoken))
{
    Action shellcodeDelegate = Marshal.GetDelegateForFunctionPointer<Action>(shellcodePtr);
    shellcodeDelegate();
    RevertToSelf();
}

注意:此方法要求当前线程权限足够,且Shellcode执行不依赖进程级上下文差异(如进程权限、环境变量等)。

简便方案推荐

优先选择方法二,你已熟悉CreateProcessWithTokenW的调用逻辑,仅需扩展进程注入步骤,稳定性与兼容性更高,不易因权限或线程状态问题失败。若追求轻量化且当前进程权限满足要求,可尝试方法三,代码更简洁。

内容的提问来源于stack exchange,提问作者fanbyprinciple

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:50:48