如何在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。步骤如下:
- 调用
CreateProcessWithTokenW启动挂起状态的进程(如cmd.exe或notepad.exe,传入CREATE_SUSPENDED标志) - 获取新进程的主线程句柄与进程句柄
- 用
VirtualAllocEx在目标进程内存中分配可执行的内存区域 - 通过
WriteProcessMemory将Shellcode写入该内存区域 - 调用
SetThreadContext修改主线程的RIP(x64)或EIP(x86)指向Shellcode地址 - 调用
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
相关产品推荐
相关产品推荐

