一、实验环境与背景
在渗透测试或靶机演练中,常见的一步是检查系统中带有 SUID(Set User ID)权限的可执行文件。
- SUID 程序在执行时会临时以其文件拥有者(通常是 root)的身份运行,而非调用用户的身份。
- 这是系统提供的一种特权机制,用于执行需要临时提升权限的功能(例如 passwd 修改密码)。
- 一旦程序设计不当,就可能成为提权突破口。
在本次分析中,系统中存在一个非标准的 SUID 程序 /usr/bin/getinfo,它的功能是输出网络信息、/etc/hosts 文件内容以及操作系统信息。这类程序属于自定义工具,不在标准 Linux 安装中出现,因此格外值得怀疑。
二、信息收集与可疑点发现
在审计 /usr/bin/getinfo 时,注意到以下行为特征:
- 输出网络接口信息,结果与 ip address 命令相符。
- 显示 /etc/hosts 文件的内容,说明它在读取系统配置文件。
- 输出操作系统内核信息,格式与 uname -a 一致。
从这些特征可以推测:
- 程序内部极有可能直接调用外部命令 ip、cat、uname,而非使用系统 API。
- 如果调用时未指定绝对路径(如 /sbin/ip),而是依赖环境变量 PATH 查找,就会引发**命令搜索路径劫持(PATH Hijacking)**漏洞。
三、漏洞原理解析
1. PATH 环境变量的机制
在 Linux 中,当用户执行命令时,系统会根据当前的 PATH 环境变量定义的目录顺序去查找对应的可执行文件。
- 若程序中仅写了 system("ip"),那么实际执行过程会先在 PATH 的第一个目录中寻找 ip。
- 如果攻击者能在一个靠前的目录放置同名恶意脚本或二进制文件,就会优先执行攻击者提供的版本。
2. SUID 与 PATH 劫持结合的危险性
- 普通情况下,PATH 劫持只会在当前用户权限范围内执行伪造命令,影响有限。
- 但若目标程序是 SUID root,则执行伪造命令时将以 root 身份运行。
- 这意味着攻击者可以通过构造同名恶意程序,直接在 root 权限下获得任意 shell 或执行任意命令,从而实现本地提权。
3. getinfo 的漏洞本质
getinfo 之所以成为提权入口,根本原因是:
- 它在 SUID 环境下运行;
- 它调用了外部命令 ip;
- 没有使用绝对路径或安全函数;
- 因此受到 PATH 劫持攻击的影响。
四、漏洞利用过程(原理层面)
- 攻击者在可写目录(如 /tmp)中构造一个名为 ip 的伪造可执行脚本。
- 在该脚本中嵌入命令:直接调用 /bin/sh -p,确保在 SUID 环境下启动一个保持 root 权限的 shell。
- 修改 PATH 环境变量,将 /tmp 置于最前。
- 当执行 /usr/bin/getinfo 时,程序尝试调用 ip,但由于 PATH 被劫持,实际执行的是 /tmp/ip,进而触发 root shell。
通过这一链条,低权限用户 hubert 成功获得 root 权限。
五、成功提权后的验证
在提权完成后,通过 id 命令验证当前身份:
- UID 为 0,表明当前 shell 已经以 root 权限运行。
- GID 仍显示为原用户的组,但并不影响 root 身份的特权能力。
这一点说明攻击成功,且攻击链条逻辑闭环:SUID 程序 → 外部命令调用 → PATH 劫持 → root shell。
六、防护与修复建议
针对本次发现的漏洞点,修复和防护措施包括:
- 移除不必要的 SUID 程序
- 检查 /usr/bin/getinfo 的存在必要性,如果只是查询信息,完全不需要 root 权限。
- 可直接移除 SUID 位:chmod u-s /usr/bin/getinfo。
- 使用绝对路径调用命令
- 在程序中应调用 /sbin/ip、/bin/cat、/bin/uname,避免依赖 PATH。
- 避免使用 system()
- 尽可能通过库函数或系统 API 获取信息,例如使用 getifaddrs() 获取网络信息,而不是 system("ip")。
- 最小化特权
- 如果确实需要额外权限,可以通过 sudo 规则或 Linux capabilities,仅赋予必要的能力,而不是直接 SUID root。
- 安全开发规范
- 在编写可能被设为 SUID 的程序时,应清理或固定环境变量,避免 PATH、IFS、LD_PRELOAD 等带来的劫持风险。
七、总结
本次提权成功的核心原因在于:
- 系统存在一个非标准 SUID 程序;
- 程序中调用外部命令时未使用绝对路径;
- 低权限用户通过 PATH 劫持,将该命令替换为恶意脚本;
- 最终在 root 权限下执行恶意脚本,从而获取最高权限。
命令劫持提权
一、概述
在 Linux 提权场景中,命令劫持(Command Hijacking) 是一种经典方法,常与 SUID 程序 配合使用。其核心逻辑是:
- 程序在执行过程中依赖外部命令;
- 若调用未指定绝对路径,而是交由环境变量 PATH 搜索;
- 攻击者可通过伪造同名命令并控制 PATH 顺序,替换程序实际调用的目标;
- 当目标程序具备 SUID root 权限时,攻击者的伪造命令即会在 root 权限下执行,从而获得最高权限。
这一方法本质上是利用了 路径查找机制的不安全设计,使得低权限用户能够控制高权限程序的执行逻辑。
二、SUID 与命令调用的关系
- SUID 程序的特性
- 普通用户运行时,进程临时获得文件拥有者(root)的身份。
- 常用于密码修改、挂载文件系统等需要临时特权的操作。
- 外部命令调用的隐患
- 若程序调用外部命令时仅写命令名(如 ip),系统会依赖 PATH 搜索。
- 一旦用户可控 PATH 顺序,程序调用的实际结果就不再受开发者掌控。
- 风险放大
- 普通环境下,这只会导致程序功能异常。
- 但在 SUID 场景中,风险被放大为 权限绕过与 root 提权。
三、命令劫持的利用原理
- 条件
- 存在可执行的 SUID 程序;
- 程序内部使用外部命令,且未采用绝对路径;
- 用户具备写入某个目录的权限(如 /tmp);
- 用户能修改 PATH 环境变量。
- 攻击链条
- 攻击者构造同名的恶意“命令”;
- 将其置于 PATH 优先级更高的位置;
- 当 SUID 程序调用外部命令时,实际执行的是恶意版本;
- 从而实现以 root 权限运行任意代码。
- 结果
- 攻击者获得 root shell;
- 或执行特权命令,进而扩展控制范围。
四、典型案例解析
在靶机实验中发现的 /usr/bin/getinfo 程序,功能是展示网络信息与系统信息。
- 程序内部显然调用了 ip、cat、uname 等命令;
- 检测后发现它仅使用了命令名,而未指定完整路径;
- 攻击者通过在 PATH 中优先加载伪造命令,实现了 root shell 的获取。
这个案例充分说明了命令劫持在 定制化工具 与 教学靶场 中的普遍性。
五、防护与修复措施
- 开发层面
- 使用绝对路径调用外部命令;
- 避免使用 system(),尽量采用底层 API(如 getifaddrs() 获取网络信息);
- 在进入关键逻辑前清理环境变量,避免 PATH、IFS 等被篡改。
- 运维层面
- 定期审计系统中的 SUID 程序,移除不必要的 SUID 权限;
- 使用最小化特权原则,仅为确有必要的功能赋予 SUID;
- 使用 capabilities 或 sudo 精细化授权替代全局 root SUID。
- 监控层面
- 对系统中敏感二进制执行行为进行监控;
- 关注 PATH 异常变化与可疑目录下的可执行文件;
- 在防护体系中引入基于行为的检测与告警。
六、知识点深化总结
- 命令劫持提权 属于 环境变量劫持类漏洞 的典型代表,其本质是利用环境可控与程序信任不当的矛盾。
- 与其相似的利用方式还包括:
- LD_PRELOAD 劫持(通过预加载动态库注入代码);
- LD_LIBRARY_PATH 劫持(替换动态库搜索路径);
- IFS 环境变量劫持(修改 shell 对空格分隔的解释方式);
- PATH 劫持(本案例)。
- 在渗透测试实践中,命令劫持往往是初学者能较快掌握并利用的提权手段,但同时它也揭示了安全开发的严谨性要求。
- 通过对这类案例的深入理解,可以系统性地总结 “程序与环境交互的风险”,并在渗透或防御中更有针对性地排查与修复。
七、结语
“命令劫持提权”是一种典型的 因不安全命令调用方式 引发的本地提权漏洞。它提醒我们:在安全设计中,不仅要关注程序功能本身,还要考虑运行环境的安全性。
在实际渗透与防护场景中,这类漏洞虽然常见,但其本质反映了 环境变量可控性 与 特权程序信任缺陷 之间的矛盾。掌握这一知识点,不仅有助于提权实战,更能帮助开发者和运维人员建立更严谨的安全意识。