
简介面向网络安全初学者的夺旗CTF靶机实操教程以Vulnhub DC-1靶机为实验环境完整演示从环境搭建、局域网主机发现、端口扫描到漏洞利用与权限提升的攻防链路。压缩包内为PDF文档仅1个文件大小1.82MB内容编排清晰虽小巧但覆盖了多个核心知识点。已有1415人学习下载。教程从Kali Linux 2023与靶机镜像部署开始逐步讲解使用arp-scan扫描存活主机、用nmap识别开放端口再借助Metasploit框架搜索并利用Drupal漏洞获取初始shell随后通过Python反弹交互式shell并利用find命令查找SUID文件实现提权读取配置文件找到数据库密码通过MySQL查询用户信息、修改admin密码最终破解/etc/shadow中的flag4密码。每个步骤都有作者亲手验证的命令和界面提示适合初学者按步骤边学边练系统掌握网络扫描、漏洞利用、提权与数据库交互的完整夺旗思路。1. 为什么要拿 DC-1 做夺旗练习网络安全入门最怕的不是工具不会用而是不知道整个夺旗流程怎么串起来。DC-1 是 Vulnhub 上最适合新手反复练习的 CTF 靶机之一5 个 flag 从 Web 漏洞、数据库读写到 SUID 提权一路展开覆盖了真实渗透中“信息收集—漏洞利用—权限提升—深度提取”的完整闭环。和其他靶机不同DC-1 不需要猜隐藏路径或爆破后台每个 flag 都是下一步的指引做完之后你会更清楚 Metasploit 模块、MySQL 的 update 语句、John the Ripper 的字典攻击分别用在哪里。这套教程适合已经有 Kali 基础、想进入真实环境练习的人。2. 环境准备与信息收集从 arp-scan 到 nmap 的完整姿势2.1 为什么用桥接模式而不是 NAT在 VMware 里装 Kali 和靶机时网络模式一定要先想好。DC-1 的官方 vm 文件默认没有预设用户名和密码所有入口都暴露在网络上所以你需要让两台虚拟机在同一个广播域里桥接模式是最省事的选择。它会把虚拟网卡直接挂在物理机所在的局域网Kali 和 DC-1 都能从家用路由器或 DHCP 服务器拿到同网段 IP。NAT 模式虽然能上网但 Kali 和靶机之间常常因为虚拟网段划分的问题互相看不见会在信息收集阶段浪费时间。桥接模式下先用ip a确认 Kali 的 IP再扫描同一网段内的存活主机。实际演练中我习惯先看自己的地址避免把路由器、打印机等真实设备误当成靶机。2.2 arp-scan -l 找靶机 IPKali 自带 arp-scan它的原理是直接发送 ARP 请求询问局域网内所有主机然后收集回应。和 ping 扫描相比ARP 扫描不依赖 ICMP很多禁 ping 的设备也会回应所以在 VMware 这种二层可达的环境里尤其准确。sudo arp-scan -l执行后你会看到类似下面的输出192.168.1.155 08:00:27:... PCS Systemtechnik GmbHPCS Systemtechnik 是 VMware 虚拟网卡的常见 OUI看到这个厂商基本可以断定就是靶机。不同路由器网段不同你拿到可能是 192.168.31.155关键是看网卡厂商字段不要死记 IP。接下来把靶机 IP 记成变量后面每条命令都用它减少手误export TARGET192.168.1.155提示如果 arp-scan 输出很多先根据 IP 排除掉网关和本机。本机网卡 MAC 和 VMnet 网卡的厂商可能也是 PCS Systemtechnik不要把它当成靶机。更严谨的做法是第一次扫描记录一个基线第二次扫描做 diff新增的那台就是刚启动的靶机。2.3 nmap 端口扫描与版本识别知道靶机 IP 之后用 nmap 做端口扫描。很多人上来就扫 all ports其实对 CTF 靶机没必要DC-1 暴露面不大先扫常用端口再决定是否扩大范围。nmap -sV -sC $TARGET -p-参数说明-sV探测服务版本-sC跑默认脚本-p-扫 1-65535 全端口。DC-1 的结果通常是这样端口服务版本22/tcpsshOpenSSH 6.0p1 Debian80/tcphttpnginx 1.6.2 / Drupal111/tcprpcbind2-4/RPC #100000看到 80 和 22进攻面就很清晰了22 是后续拿账号密码后登录用的80 是当前突破口。111 的 rpcbind 在这种场景里一般没有直接利用价值但如果你发现 NFS 共享也会有用这里先记录在案。nmap -sV -sC $TARGET -p 80,22,111扫描结果里我一般会重点看 http 的脚本输出它会告诉你网站用的什么 CMS、有没有可能利用的目录。DC-1 的 80 端口直接暴露了 Drupal 登录页这说明靶机很可能用了较老版本的 Drupal接下来就该去 Metasploit 里搜对应漏洞了。这里也顺便说一句-sC跑的是默认脚本捕获的信息已经够用再往下做目录爆破反而容易被 404 干扰信息收集不是越多越好而是把端口、服务、CMS 三角拼齐就够了。2.4 先用人眼确认 HTTP 入口Nmap 扫描结果告诉我们 80 端口开着 nginx但服务是 nginx 还是 Drupal 的逻辑层需要再确认一次。打开浏览器访问http://$TARGET会看到一个 Drupal 站点首页有登录表单和默认主题。这一步看起来简单实际上信息量不小登录表单路径通常是/user/login管理系统是 Drupal这意味着后续搜索模块时可以直接用drupal做关键字。如果你在用命令行也可以快速看一眼响应头curl -I http://192.168.1.155返回里的X-Generator: Drupal 7如果有的话能进一步确认版本范围。为什么要确认版本因为 Drupal 7 的公开漏洞里既有需要认证的代码执行漏洞也有未认证就能打的漏洞Metasploit 里的模块会按版本做 release 判断你报给它的版本越准确它跑出来的成功率越高。看到这条以后我已经确定两个入口Web 服务和 SSH。下一步就是决定先打哪边。SSH 在没有弱口令和有效账号的情况下不好碰Web 服务反而是更大概率能找到现成攻击模块的点所以进入 Metasploit 是顺理成章的选择。3. 利用 Metasploit 拿下 Drupal 并获得第一个 flag3.1 search drupal 模块选择进入 Metasploit 后先做模块检索。这里的search会在已安装的模块库里匹配关键字比去浏览器搜“Drupal exploit”要快得多而且版本匹配更可靠。msfconsole search drupal输出里会出现多个模块。DC-1 官方文档没有写明具体 Drupal 版本所以选取优先级我一般按三条规则来优先选带unauthenticated描述的模块优先选exploit/multi/http/路径下的模块多个模块时启动后先check再exploit避免直接打挂服务。在本例中直接选择列表第一个可用模块用use 1把它切换进来。这里的1是 search 结果列表里的编号不是模块名每次扫描结果顺序可能不同务必先看清编号对应的模块名。3.2 show options 与 rhosts 配置选中模块后不要急着运行先执行show options。Metasploit 的模块就像参数化脚本URL、目标 IP、payload、verbose 这些都是可配置项漏设一项会导致 shell 回连失败或直接执行失败。use 1 show options输出里最重要的三个字段字段含义本靶机怎么填RHOSTS目标主机 IP192.168.1.155RPORT目标端口默认 80不用改TARGETURI目标路径默认/Drupal 装在根路径就保持默认配置命令如下set rhosts 192.168.1.155 set targeturi / runrun和exploit在 Metasploit 里等价都是启动漏洞利用流程。如果模块内部有检查和利用两段逻辑run会在利用前先做一次版本探测失败也不会立刻报错而是告诉你哪个环节不对。看到meterpreter 或shell会话提示符说明模块已经返回了一个会话。注意如果run之后很久没有回显检查两件事一是 RHOSTS 填的正确与否二是 payload 的 LHOST 是否填了 Kali 的 IP。虽然 Drupal 模块的默认 payload 会自动借用你本机地址但在多网卡情况下Metasploit 可能选错虚拟网卡导致靶机把反弹连接发到一个不可达的地址。稳妥的做法是先set LHOST为本机桥接网卡的 IP再run。3.3 从 meterpreter 到系统 shell拿到 meterpreter 会话之后第一件事不是翻目录而是先稳定会话。我一般先敲一个shell把 meterpreter 切换成系统命令交互再用ls确认当前目录和用户身份。很多新手在这个步骤里直接去找 flag忘了确认自己是谁、在哪一层目录导致后面找权限边界时一头雾水。shell ls whoami这里执行whoami返回的通常是www-data是 Web 服务的低权限用户。Drupal 站点根目录通常在/var/www/html但 DC-1 的 flag1 就被放在当前目录下ls后就能看到flag1.txt。直接读它cat flag1.txtflag1 的内容通常是一句提示指引你下一步去找站点配置文件。这句提示很有价值它没有直接给出路径但告诉你“配置文件中藏了东西”。Drupal 的配置文件路径是固定的sites/default/settings.php这也让我们后面去找 MySQL 账号密码有了明确方向。3.4 拿到 shell 后的边界意识这里需要强调一个很多人忽略的点Metasploit 模块返回的 shell 是目标机器上 Drupal 的www-data权限不是 root。你看到的$提示符是低权限 shell后续想读/etc/shadow、想访问数据库备份文件往往都会因为权限不够被拒绝。这也就解释了为什么 DC-1 设计者要把 5 个 flag 分开放第 1 个是 Web 拿下的第 2 个藏在配置文件里第 3 个需要进入后台第 4 个是破解出来的用户密码第 5 个才是 root 权限后的最终答案。4. SUID 提权、数据库回译与 flag2/flag34.1 用 Python 起一个交互式 shell通过 Metasploit 拿到的shell是非交互式的没有完整的终端环境运行su或sudo这类需要终端的命令时经常报错比如su: must be run from a terminal。常见做法是先用 Python 反转出一个交互式 pty shellpython -c import pty;pty.spawn(/bin/sh)这行命令会启动一个新的/bin/sh但它连接到当前伪终端上所以你能正常使用 Tab 补全、上下翻历史还能跑whoami、ls这类命令。参数说明pty.spawn会把当前进程替换成一个新的 pty 会话这是 Linux 环境下从 Web shell 升级成交互式 shell 的标准操作。执行后先跑whoami确认自己仍是www-data。接下来要思考的就是怎么从www-data变成root。这就是权限提升阶段也是 DC-1 设计的核心考点之一。4.2 查找所有 SUID 权限文件SUID 是 Linux 里一种特殊的文件权限位。当可执行文件带有 SUID 位时无论谁运行它进程的有效用户 ID 都会被强制设为文件所有者的 ID。如果文件所有者是 root那么运行它就能以 root 权限执行任务。这个机制本身是设计用来执行特权操作的但一旦某个 root 所有的 SUID 文件能被用来执行任意命令就变成了提权漏洞。find / -perm -us -type f 2/dev/null这行命令的作用是从根目录开始找所有设置了 SUID 位的普通文件。参数含义如下/从根目录遍历-perm -us匹配“用户执行位为 s”的文件-type f只保留普通文件2/dev/null把权限不足导致的错误输出丢弃避免刷屏。输出里会有/usr/bin/passwd、/usr/bin/su还有一个容易被忽略的/usr/bin/find。这里容易被误解的是真正触发 root 的不是 passwd 文件本身而是 find 自带 SUID 位。find 找到目标文件后会执行-exec后面的命令这个命令继承 find 进程的有效用户 ID于是等于间接以 root 身份执行了/bin/sh。4.3 利用 find -exec 拿到 root shell先进入/usr/bin目录确保 find 能搜索到目标文件cd /usr/bin find passwd -exec /bin/sh \;逻辑说明find 会在当前目录里查找名为passwd的文件每找到一个就执行一次/bin/sh。由于 find 本身是 SUID root所以启动的/bin/sh也是 root 权限。命令最后的\;是-exec的结束标志告诉 find 的命令到这里为止。执行后提示符会从$变成#这就是提权成功的标志。拿到 root 后先不要急着拿最终 flag回到之前的思路flag1 提示过配置文件里有东西。Drupal 的配置文件位于/var/www/html/sites/default/settings.php读它cat /var/www/html/sites/default/settings.php这个文件里能看到数据库名、用户名和密码都是明文配置项值databasedrupaldbusernamedrupaluserpassword明文密码hostlocalhost同时这个文件里也藏着 flag2。到这里要立刻切换思维既然拿到了数据库口令下一步就能直接操作数据改掉管理员密码进入 Drupal 后台第三个 flag 往往就在后台的文章或区块里。4.4 MySQL 登录与密码 Hash 重置用拿到的账号密码登录 MySQLmysql -u drupaluser -p drupaldb输入密码后进入 SQL 交互环境。先看表结构use drupaldb; select * from users;users表里会有一条 admin 记录密码字段是 Drupal 的 hash不是明文。直接反查原密码很费劲但我们可以换个思路既然能写库就自己生成一个新的 hash把 admin 密码覆盖掉。DC-1 的/var/www/scripts目录下通常会提供一个password-hash.sh脚本专门用来计算 Drupal 的密码 hashphp /var/www/scripts/password-hash.sh 123456这条命令会把123456变成一串 hash。然后在 MySQL 里执行update users set pass 生成的hash值 where uid 1;执行完select * from users;确认更新成功退出 MySQL。回到浏览器用admin / 123456登录 Drupal 后台首页随便点几个内容区块就能看到 flag3。这里有个值得记住的参数点uid 1通常对应 Drupal 的超级管理员。在真实环境中这种直接改库的做法并不是最优解因为它会破坏现有会话但在 CTF 靶机里是最快拿到后台权限的方式。如果你在真实项目里遇到这种场景更稳妥的路径是先把旧密码备份再尝试用离线 hash 破解。5. John the Ripper 破解 shadow、SSH 登录与 root 终局5.1 从 /etc/shadow 里发现 flag4拿到 root shell 后读取/etc/shadow是所有提权操作里的经典动作。/etc/shadow保存了所有用户的密码 hash只有 root 能读。cat /etc/shadowDC-1 里 shadow 文件会出现一个用户flag4后面跟着一串加密字符串这其实就是第四个 flag 的载体。CTF 场景里经常把关键信息藏在用户名里所以看到非标准用户不要跳过。把这段内容保存到本地文件shadow.txt中格式保持原样。这里有一个关键细节John the Ripper 默认不会自动识别所有加密格式最好把flag4:到下一个冒号之间的 hash 单独截取出来有时候还需要手动指定格式。不过 DC-1 的密码用的是常见的 sha512crypt大多数新版 John 都能直接识别所以先试默认模式。5.2 用 John 跑字典破解John the Ripper 的安装在 Kali 上有预装版本直接john命令就能用。如果要用源码编译版本参照常见流程下载、解压、进入src目录后执行make然后到run目录下运行john可执行文件。john shadow.txtJohn 默认会自动加载自带的 wordlist按频率从高到低尝试。如果默认字典没跑出来加--formatsha512crypt --wordlist/usr/share/wordlists/rockyou.txt再试john --formatsha512crypt --wordlist/usr/share/wordlists/rockyou.txt shadow.txt参数说明--format指定 hash 类型--wordlist指定字典文件路径。rockyou.txt 是 Kali 里常用的弱口令字典如果你的 Kali 没装先执行sudo gunzip /usr/share/wordlists/rockyou.txt.gz解压。跑完后 John 会显示破解结果按我实际验证这个密码是orange。拿到这个密码就意味着拿到了一个可以 SSH 登录的账号。5.3 SSH 登录读取 flag4再走一次 SUID 提权有了账号和密码用 SSH 登录靶机ssh flag4192.168.1.155密码输入orange登录成功后在当前目录看到flag4.txt。内容会提示你“你能用同样的方式在 root 目录中找到 flag 吗”这就是在引导你用之前的 SUID find 提权思路进入 root 目录。find /usr/bin/passwd -exec /bin/sh \; ls /root cat /root/thefinalflag.txt最终的thefinalflag.txt内容是制作者留下的收尾语大意是恭喜你完成了全部 5 个 flag 的挑战。这里我想额外给你一个验证习惯每完成一步都把当时的权限状态记录成一张清单。比如这一步你至少要确认三件事id显示当前 uid0说明确实在 root 上下文cat /root/thefinalflag.txt能读到文件说明权限正确在靶机上执行history或查看/var/log/auth.log观察你之前的攻击动作有没有留下痕迹。把这三条固化到自己的流程里再往后打 DC-2、DC-6 这类同系列靶机时你会发现 SUID 提权不是万能的但“先枚举、再找可执行文件、再看它是否继承特权”的思路是通用的。对还在刷靶机的人我建议先把这几条写进自己的 checklist拿到 shell 先确认身份、找 flag 前先找配置文件、提权前先看 SUID、拿到 hash 先试 John 默认字典再跑大字典。做到这四条DC-1 这个靶机才算真正消化完。本文还有配套的精品资源点击获取