最近用Vulnhub上的DC系列靶场练手,DC-3算是我印象最深的一台。它是基于Joomla CMS构造的靶机,整体难度定位中等偏上,不像DC-1那样扫到洞就能一路打通,也不像DC-2那么依赖密码收集。如果你正在学Web渗透和Linux提权,DC-3是非常典型的一条完整攻击链:信息收集、版本识别、SQL注入、哈希破解、后台getshell、内核提权,几乎每个环节都会戳到新手痛点。这篇文章不聊那些已经写烂的攻击过程,只把我实际打的两次过程中踩到的5个坑整理出来,每个坑都附上排查思路和最终解决办法。适合刚入坑Vulnhub、或者正在卡DC-3的朋友,当作一份避坑手册对照着看。
1. 先把DC-3的考点和踩坑路线理清楚
1.1 这个靶场到底练什么
DC-3和DC-1、DC-2的解题思路差别很大。DC-1是Drupal框架,核心是找漏洞点;DC-2是WordPress加密码收集和简单提权;DC-3则是Joomla CMS,需要靠SQL注入把后台数据摸出来,再通过后台功能拿到WebShell,最后在内核上找提权路径。
说白了,它模拟的是一个比较常规的“被入侵路径”:攻击者先发现目标网站用Joomla搭建,再通过已知的SQL注入漏洞读取数据库中的管理员账号和密码哈希,破解后登录后台,利用后台写文件能力执行PHP代码,拿下低权限Shell,然后在内核漏洞上动手脚获得root权限。
对新手来说,这条链路每一步都不算特别难,但每一步都容易翻车。因为网上的WriteUp经常直接告诉你“跑一条命令就出结果”,省略了大量中间判断过程。等你实际敲命令时,就会发现扫描结果对不上、注入请求报错、哈希破不出来、提权exp编译失败,各种问题一个接一个冒出来。
1.2 五个坑的整体分布
我把自己踩过的坑按阶段划分,大概是这样分布的:
- 环境与信息收集阶段:靶机IP找不到、Joomla版本识别错。
- 漏洞利用阶段:SQL注入参数识别错、密码哈希破解失败。
- 提权阶段:内核版本没确认就盲目跑exp。
这五个坑单独看都不算致命,但它们会连环影响下一步操作。比如版本识别错,会导致你去找错误的漏洞代码;注入参数错,会导致sqlmap反复跑却拿不到数据;哈希破解失败,会卡在后台登录这一步,后面全部进行不下去。下面我把每个坑展开讲,也包括我最终是怎么绕过去的。
2. 环境与信息收集:前两个坑,戒掉“一把梭”
2.1 坑一:虚拟机网络配置导致靶机IP找不到
DC-3下载下来是一个OVA镜像,导入VMware或VirtualBox之后,默认会分配一个动态获取IP的网卡。我第一次导入时图省事,直接选了NAT模式,启动靶机后从Kali里用nmap对自己的网段扫了一圈,结果怎么都看不到新主机。
当时我以为是靶机没启动成功,反复重启了几次,又回到VMware里看控制台。结果发现系统在里面正常启动,登录界面都出来了,就是没有显示IP地址。后来才反应过来,是主机的DHCP分配时间太长,或者虚拟网卡没正常被系统识别。在控制台里折腾了一会儿,看到网卡已经起来了,但还是没拿到地址。
解决办法分两步:
- 先把虚拟机的网络模式从“NAT”改成“桥接模式”,或者直接在控制台里执行
dhclient重新获取IP,这是最稳妥的。我第二次就是进到靶机控制台手动执行了dhclient,很快就拿到了一个和Kali同网段的地址。 - 如果靶机控制台不方便操作,也可以用
arp-scan去扫描整个局域网,配合虚拟机网络模式把主机IP找出来。arp-scan -l能主动发ARP请求,比nmap的IP段扫描更容易发现新上线的虚拟机。
这里给新手一个建议:打Vulnhub靶机之前,先确认攻击机和靶机在同一个虚拟网络里。最简单的方法是两台机器都ping一下网关,如果网关通了,再互相ping,通了就说明网络层面没问题。不要一上来就用nmap -sP,有时候NAT模式下的nmap不一定会把靶机扫出来。
2.2 坑二:版本识别不精确,排查方向直接跑偏
我的第二个坑是在识别Joomla版本时偷懒,浪费了将近半天时间。
第一次扫描端口,确认80端口开着,访问首页发现是一个Joomla站点。当时我急着找漏洞,直接用了一款常见的CMS识别工具,结果工具识别出的版本号是”Joomla! 2.5.x“,于是我就照着Joomla 2.5的老漏洞去找exp,结果全部无效。
后来才发现,那个工具是基于指纹库的,版本识别规则比较旧,把DC-3使用的Joomla 3.8系列误判成了2.5。这个误判非常坑,因为2.5和3.8的漏洞利用方式完全不同,SQL注入点也不一样。
正确的版本识别方式应该是:
- 查看页面HTML源码,在
<meta name="generator" content="Joomla! ...">里通常能看到标题里的版本号。 - 直接访问
/administrator/manifests/files/joomla.xml,这个文件里有完整的版本信息,比如<version>3.8.3</version>。 - 也可以打开
/README.txt或/htaccess.txt,虽然不一定会直接暴露版本,但可以辅助确认CMS类型。
我最后就是靠joomla.xml确认了确切版本号,然后才开始针对3.8系列的漏洞做检索。如果你也遇到“工具扫出版本但怎么都利用不上”,先别急着放弃,回到站点源码里手动确认一次版本,这个习惯能替我省下大量无用功。
注意:识别CMS版本时,永远不要百分百信任扫描器的结果。扫描器的作用是缩小范围,最终判断要靠手工确认。特别是在这种训练靶场里,目标就是考验你的判断能力,不是让你无脑套工具。
3. SQL注入到管理后台:中间两个坑最折磨人
3.1 坑三:SQL注入参数不对,payload全部打空
确定Joomla版本是3.8.3之后,我去搜到了对应的SQL注入漏洞。这个漏洞大概在Joomla的fields组件里,利用入口是某个list[fullordering]参数。思路很清晰,就是先用sqlmap跑一遍,把数据库信息dump出来。
但问题来了:我直接在浏览器地址栏里复制了一个URL,把sqlmap命令拼上去,结果sqlmap报了各种“unable to connect”和“missing parameter”的错误。一开始我以为是目标反爬,又加了--random-agent、--delay,还是不行。
后来我仔细对比网上成功案例里的请求包,发现自己漏了一个关键信息:这个注入点的完整URL不是首页,而是需要带上option=com_fields和view=fields这些参数,同时还要保持一个合法的会话Cookie。有些人用的是GET请求,有些人需要用POST,我在没有完全理解HTTP请求结构的情况下,光靠工具瞎试,当然跑不通。
这个坑的解决方法其实很朴素:
- 先用Burp Suite抓一个正常访问页面的请求,看完整请求行、请求头和Cookie。
- 把完整URL放到sqlmap里,格式类似:
sqlmap -u "http://目标/index.php?option=com_fields&view=fields&list[fullordering]=1" --cookie="xxx"。 - 如果工具识别不到注入点,手动在Cookie或POST参数里加一个“标记参数”,让sqlmap知道该往哪里测。
我最后是参考了漏洞公告里的POC,把URL框里面的list[fullordering]参数改成一个单引号,再抓包确认返回数据库报错,才确定注入点位置。之后再让sqlmap跑,很快就把数据库表列出来了。
这里还有个更基础的教训:使用sqlmap时,如果注入点本身是带参数的点,一定要保证URL里的参数名是完整的,不能省略。比如list[fullordering]这种中括号参数名,在某些环境下需要URL编码,否则会被Web服务器截断,导致请求和预期不一致。
3.2 坑四:拿到密码哈希,字典不对照样白干
sqlmap顺利dump出数据后,我找到了Joomla的用户表。里面除了几个演示用户,还有一个管理员账号,密码字段是一长串哈希。我以为这下稳了,直接丢给John the Ripper,用默认的rockyou字典跑,结果跑了很久都没跑出来。
之后我才发现,Joomla 3.8的密码哈希用的是bcrypt加密,和旧版本的MD5或phpass格式不一样。John默认的识别格式可能识别成别的类型,导致暴力破解方向错误。而且rockyou字典虽然大,但我自己没控制好规则,很多变体没跑出来。
这个坑的解法有三个:
- 先用
john --list=formats检查Joomla相关的哈希格式,看到有bcrypt或joomla格式后,再指定格式跑。 - 不要把hash直接放在命令行里,先写成一个hash文件,用
john --format=bcrypt hash.txt运行。 - 如果rockyou跑不出,可以考虑加规则,比如
--rules=best64,把常用密码的变体也覆盖起来。
最终我是用john --format=bcrypt --wordlist=/usr/share/wordlists/rockyou.txt hash.txt,跑了大概几分钟后成功解出明文密码。这个密码其实就是一个比较常见的词,但如果不指定格式,John可能连试都不试。
提示:破解哈希前第一件事是先识别哈希类型。用
hashid或者nth工具把哈希类型判断准了,再选择破解工具和参数。跳过这一步,相当于不看锁的型号就直接拿铁棍撬。
拿到管理员密码后,登录Joomla后台就顺畅了。后台在/administrator目录,输入账号密码进入管理面板。此时我们已经获得了管理员权限,但还需要把这个权限转化成WebShell,才能进入下一步提权。这里也有一个隐藏小坑,我放在后面一起说。
4. 权限提升与最终Flag:最后一个坑
4.1 坑五:提权前没看内核版本就盲目跑exp
拿到低权限WebShell之后,我急着提权,直接把这个版本的常见本地提权exp上传上去,编译一把就执行,结果提示Kernel panic或者直接断连。我以为是exp没传好,又换了一个变体,反复试了半个多小时,机器越来越卡。
后来静下来看系统信息,才发现当前的Linux内核版本是4.4.0系列,而我一直用的那个exp主要适配的是另一个版本。目标机的内核源码和编译环境也不齐全,用gcc编译时报了一堆头文件缺失。这是提权阶段最典型的“不看环境、只找exp”综合征。
正确操作顺序应该是:
- 先执行
uname -a,确认内核版本。 - 再用
cat /etc/os-release或lsb_release -a确认操作系统发行版和版本号。 - 最后根据内核版本去检索对应的写exp。DC-3靶机的Ubuntu内核正好有一个经典的漏洞利用思路,但前提是必须匹配版本。
如果你是第一次尝试提权,别直接找源码编译,可以先考虑Metasploit里的本地提权模块,它会自动检测当前系统的漏洞匹配情况。或者使用目标机器上容易获取的exploit,但要确保编译选项和系统架构匹配,比如32位和64位不能混用。
编译问题上还有一个很实际的坑:目标机不一定有gcc,就算有,也可能缺少头文件。此时可以用攻击机的交叉编译,编译出静态二进制再传上去。不过要注意,静态二进制体积大,传输时可能会被WebShell的执行环境超时卡住。我是先把exp用base64编码传输,解码成功后再执行,这样比直接传二进制更稳。
4.2 从后台getshell到提权之间的几个细节
趁这个节点我也想补充两个很容易被WriteUp忽略的细节。
第一个是后台怎么真正拿到Shell。Joomla后台的“模板管理”里,通常可以编辑当前模板的PHP文件。我在/templates/protostar/index.php末尾追加了一段PHP代码,保存后直接访问首页,就会执行。这本身不算坑,但很多新手会把代码加错位置,比如加到了templateDetails.xml这种不会被PHP解析的文件里,结果访问首页没有任何变化。正确的判定标准很简单:保存后访问首页,如果页面出现你设置的输出,就说明代码成功执行了。
第二个是WebShell执行命令时,很多命令会被禁用或报错。比如用纯PHP代码调用system(),有些环境下需要使用proc_open或者passthru。如果不想绕来绕去,可以直接在PHP代码里通过$_GET接收命令参数,比如system($_GET['cmd']);,访问/index.php?cmd=id就能执行任意命令。我一开始直接把命令写死在PHP里,每次想换命令都得改模板,来回刷新后台很麻烦。
到了这一步,后面的流程就是标准的内核提权了。确认好内核漏洞后,提权exp执行完,直接id看到uid=0,然后去/root下读取flag文件。
4.3 常见问题速查表
前面五个坑是实操中最大的拦路虎,再帮大家做一个简短的速查表,方便卡住时快速对照:
| 常见问题 | 可能原因 | 解决方向 |
|---|---|---|
| 靶机IP扫不到 | 虚拟机网络模式不对,DHCP没生效 | 手动执行dhclient,或用arp-scan扫描 |
| CMS版本识别错误 | 扫描工具指纹库过旧 | 查meta generator、joomla.xml文件 |
| sqlmap注入不成功 | 请求参数或Cookie不完整 | 抓包确认完整URL,带上Cookie参数 |
| 密码哈希破解不出 | 哈希类型判断错,字典不匹配 | 用hashid识别类型,指定john格式 |
| 提权exp失败 | 内核版本不匹配,编译环境缺失 | 先uname -a,匹配对应的exp,考虑交叉编译 |
这五个坑基本就是DC-3这条攻击链的浓缩版。每个坑的根源都是同一个问题:在动手之前没有把环境信息和上下文搞清楚。信息收集不够细,后面就会不断试错;版本识别不精确,后面所有漏洞利用都是空中楼阁。
我个人在实际操作中的体会是:打这类靶场,别把目标放在“快点拿到flag”上,而是把每一台靶机都当成一个完整的项目来推进。每到一个阶段先停下来问自己三个问题:我现在掌握的信息是否充分?我选的工具是否匹配这个场景?如果这条路径跑不通,有没有可能是我漏掉了前置条件?
最后再分享一个小技巧:如果你在DC-3的某个阶段卡住了,比如SQL注入跑不动、提权exp编译失败,可以先把自己使用的工具的完整命令、报错信息和当时的HTTP请求包都记录下来。因为很多问题不是思路不对,而是Payload在传输过程中被环境改变了。把这些原始数据重新对照一遍,往往能发现参数少了一个、Cookie没加、字典格式不对这类细节。第一次打DC-3我花了两个晚上,第二次再打一遍,整个过程控制在四十分钟以内。这中间差的不是技术,是对这些细节的熟悉程度。希望这篇避坑指南能帮你少走一些弯路。