论坛首页 安全编程开发区 阅读主题

[原创]无声的提权:Windows攻击链中的进程伪装与UAC绕过

439 浏览 6 回复
#1 楼主 2026-06-01 21:08:57
在 Windows 攻击链中,许多看似基础的提权手段依然频繁奏效。在缺乏可用漏洞或需避免高风险内核操作时,攻击者会试图让提权看起来像系统应有的行为,以避免打断用户或触发告警。因此,“进程伪装”常被用于提权之前。攻击者通过塑造“合理的进程身份”而非单纯隐藏,来让 EDR 、AV 等防护产品和分析人员误以为其后续操作是合规的。提权不只是技术问题,而是关于身份与信任的问题:理解这一视角的转换,是识别“进程伪装 + 提权”攻击链的关键,也是本文讨论的重点。Windows 的进程拥有多层复杂的“身份信息”。攻击者在进行"进程伪装"时,本质上就是在针对这些不同的"证件"和"特征"进行造假。我们可以将进程的身份划分为以下 4 个层级:系统程序、安全软件乃至安全分析师,大多是在各自的视角下检测和验证其中的部分信息。攻击者倾向于寻找成本最低、收益最高的进程伪装方式,以躲过安全防护软件的检测和分析师的注意,然后悄无声息地实现提权。伪造进程的内核信息,成本和风险都很高;而篡改磁盘上的映像信息又容易被静态扫描识破。因此,攻击者的目光很自然地落在了进程的用户态运行时信息上。这是一个介于内核与用户观测之间的“灰色地带”,其中比较方便操作的就是进程环境块PEB,它既不属于内核,却又深刻影响着用户态工具和分析人员的判断。Windows 为了管理进程维护了很多数据结构。其中,EPROCESS 是位于内核空间的进程描述符。由于用户模式的程序无法直接访问内核空间,Windows 将一部分不那么敏感、但程序运行又频繁需要的信息放在了用户空间的进程环境块(PEB,Process Environment Block)中。每个进程都有自己独立的 PEB 结构。它位于用户态内存,用于存放特定进程状态信息的关键数据结构,包含映像基地址、加载的模块列表(PEB_LDR_DATA)、命令行参数和环境变量等,普通进程可以直接读取甚至修改它。x86 (32位):TEB 位于 FS 段寄存器指向的地址,PEB 地址存储在 FS:[0x30]。x64 (64位):TEB 位于 GS 段寄存器指向的地址,PEB 地址存储在 GS:[0x60]。TEB (Thread Environment Block - 线程环境块),存储特定线程运行时的各种信息。每个线程都有自己独立的 TEB,用于管理线程本地存储 (TLS),包含异常处理链表(如 SEH 指针),存储线程的堆栈限制、线程 ID 等信息。TEB 访问方式:在 32 位系统下通过 FS:[0] 寻址,64 位系统下通过 GS:[0] 寻址。可以看到进程的部分信息已经被修改了这种修改主要欺骗的是读取 PEB 来获取进程信息的工具(某些日志审计工具、早期的反病毒软件)。后面要实现的 UAC 绕过需要欺骗 AppInfo 服务(承载了大部分 UAC 的验证逻辑),仅仅修改 ProcessParameters 是骗不过 AppInfo 服务的。 AppInfo 还会遍历 PEB->Ldr (加载器数据),检查当前进程加载的第一个模块(即 EXE 自身)的路径。修改 LDR 链表的代码实现后面还会提到。从上面的结果也可以看到,只要对比一下 Command Line 的程序名称和 Image file name,就可以看出这两者不一致,肯定有问题。查看一下进程的内核结构体 EPROCESS 也能发现进程的“真实身份”,为什么这也能轻易实现提权?关键在于 Windows 为了性能和架构的简便,AppInfo 服务(运行在 svchost.exe 中)通过 ReadProcessMemory 跨进程读取请求者的 PEB 内存块。它读取的是用户态的内存,而不是请求内核去查询 EPROCESS(内核对象)。如果系统进程频繁访问内核的结构体,会产生很大的开销。为了让 Explorer.exe 能够静默完成许多管理任务,系统必须给它开绿灯。就好比,一个小偷用伪造的工卡想进入办公大楼,保安看过一眼就放行了,因为去调人事档案来核实身份太麻烦了。而且这个伪造的工卡本来属于每天都来单位的财务,保安无条件信任这个工卡。当然要查一下证件照、看一下监控录像就很容易发现这个人不对劲。当等到发现的时候,小偷已经得逞了。恶意程序篡改 PEB 后立刻提权,就能顺利完成恶意操作。这个比喻可能不太严谨,但大概是这个意思吧。在 UAC 机制下,即便是管理员账户登录,默认启动的进程也只是中等完整性(Medium Integrity),只有通过提权操作,才能获得高完整性(High Integrity),从而真正拥有写系统目录、改注册表核心键值的权限。提权的大致原理是系统内置的CMSTPLUA组件(实现了该接口)允许静默提权,但前提是调用者必须为受信任的系统进程。攻击者首先修改当前进程的PEB,将自身路径伪装成合法可信的进程,例如 explorer.exe。接着,代码使用CoGetObject配合Elevation提权字符串去实例化该组件。系统的AppInfo服务在校验时被PEB伪装欺骗,从而在独立的dllhost.exe中免弹窗创建了一个高权限的COM对象。最后,攻击者调用该接口的ShellExec方法启动目标程序(如cmd.exe),通过父子进程的权限继承,成功实现无弹窗获取管理员权限。读取 PEB 之后然后修改,这个前面介绍了,这里就不多说了。CoInitialize 是 Windows API 函数,用于在当前线程上初始化组件对象模型(COM)库,并将线程设置为单线程单元(STA)模式。使用任何 COM 功能前必须调用它(内存分配函数除外),且必须与 CoUninitialize 成对使用以释放资源。组件对象模型 (COM) 是微软开发的一种二进制接口标准,旨在实现跨编程语言(如 C++、C#、Python)和跨进程的软件组件复用。它允许以 DLL 或 EXE 形式存在的可重用二进制组件在运行时动态交互,是 ActiveX、OLE 和 DirectX 的技术基础。Elevation Moniker(COM提升名字对象)是Windows的一项安全特性,允许在UAC(用户帐户控制)限制下运行的应用程序以管理员权限激活特定的COM类。Elevation Moniker: Elevation:Administrator!new: 是一种特殊的 COM 语法。它告诉 COM 运行时环境(COM Runtime):实例化后面这个 CLSID 对应的对象,并且要以管理员权限(High Integrity Level)来创建它。如果一个普通的、未提权的程序调用这行代码,UAC(User Account Control)会拦截请求,弹出一个确认窗口,询问用户是否允许。CLSID (Class Identifier,类标识符) 是一个 128 位 (16 字节) 的数字,属于 GUID(全局唯一标识符)的一种,通常以带有大括号和连字符的十六进制字符串形式呈现。它用于在 Windows 系统中唯一地标识一个具体的 COM 类 (COM Class)。无论是一段处理图像的代码、一个 Excel 应用程序实例,还是一个执行系统权限提升的组件,只要它是一个 COM 对象,

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290107.htm
#2 2026-06-01 21:08:57
太有用了。
#3 2026-06-01 21:08:57
感谢分享。
#4 2026-06-01 21:08:57
github上早就有了,47cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5H3P5r3I4S2L8X3g2Q4x3V1k6n7P5i4m8S2M7%4y4g2b7f1x3`.
#5 2026-06-01 21:08:57
不执行MasqueradePEB貌似也可以BypassUAC
#6 2026-06-01 21:08:57
感谢分享.
#7 2026-06-01 21:08:57
测试了,360直接拦截。。。。有点用,但是不大

请登录后参与讨论

立即登录 注册账号