1. 靶机环境搭建与初步认识
1.1 DC-2到底是个什么靶机
如果你玩过vulnhub的DC系列,DC-1应该是不错的入门选择,而DC-2则是进阶路上绕不开的一台。它跟前作最大的区别在于:不再是那种"扫端口、找漏洞、一把梭"的线性流程,而是把WordPress站点渗透、密码爆破、受限Shell绕过、sudo权限滥用几个知识点串成了一条完整的攻击链。换句话说,DC-2更像是一个浓缩版的真实内网渗透场景,缺点是每个环节都藏了提示,优点是你顺着提示走,基本能把整套思路练扎实。
我在复现这台靶机时最大的感受是:它不靠0day也不靠复杂的缓冲区溢出,所有利用手段都是现成的工具和系统特性。你需要做的是把信息收集做得足够细致,把每条线索串起来。整个过程打下来约一个多小时,如果中间卡壳去查资料,可能耗上半天,但恰恰是这些卡壳点,才是最大的收获。
1.2 实验环境的搭建方式
准备环境时建议直接用VirtualBox,vulnhub官方的OVA文件导入之后基本不需要额外配置。导入完成后,把虚拟机网络模式设成NAT或者桥接都行,我习惯用NAT,因为靶机和攻击机处于同一个虚拟网段,方便后面的主机发现。如果你用的是VMware,直接导入OVA通常也能跑,偶尔会遇到网卡识别问题,那就手动把网卡类型调整为e1000。
自己的攻击机建议装Kali,或者任何带有nmap、wpscan、cewl工具的Linux发行版。这里提醒一句:wpscan需要Ruby环境,Kali自带,如果是自己搭的Ubuntu,记得先装好依赖,不然扫描中途报错会很扫兴。
靶机启动后,第一件事是确认两台机器能互相通信。在Kali上ping一下网关,再扫一下网段,确认靶机IP已经分配。DC-2默认开启了DHCP,所以IP不是固定的,每次重新启动可能变化。我在实验中获得的靶机IP是192.168.56.105,但不同电脑、不同网络环境下这个数字肯定不一样,后面所有操作都要把IP替换成你自己环境里的实际地址。
1.3 快速发现靶机IP的两个实用命令
靶机不告诉你IP,就得自己找。最常用的两种方式:
netdiscover -r 192.168.56.0/24arp-scan -l
两者原理类似,都是通过ARP广播探测网段内活跃主机。netdiscover会列出IP、MAC地址和厂商信息。vulnhub靶机的MAC地址通常带有明显的厂商标识,VMware和VirtualBox的网卡厂商名称就能帮你快速从一堆设备里认出靶机。我实际操作中扫出了三台设备,除了网关、攻击机之外,剩下那台就是靶机。
提示:如果靶机用了桥接模式,和攻击机不处于同一广播域,ARP扫描就会失效。这时候建议回到NAT模式,或者改用
nmap -sn做ICMP探测。
2. 信息收集:从开放端口到网站指纹
2.1 全端口扫描,别漏掉非常规SSH端口
拿到IP的第一件事不是打开浏览器,而是做端口扫描。我习惯先用nmap做一次全端口TCP扫描,命令是:
nmap -sS -sV -p- -T4 192.168.56.105这里简单解释几个参数:-sS是SYN半开扫描,速度快;-sV是服务版本探测,能识别端口背后的服务;-p-扫描全部65535个端口;-T4是加速扫描的时间模板。
扫描结果里有两点值得注意:一个是80端口跑着HTTP服务,另一个是7744端口,居然开着SSH。默认的22端口反而没开,这种把SSH挪到高位端口的做法在真实环境中也经常见到,为的是躲避批量扫描器对22端口的自动化爆破。DC-2在这点上很贴近真实场景——你要是不做全端口扫描,后面根本找不到SSH入口,整条攻击链就断在半路。
服务版本信息显示,80端口应该是HTTP服务,7744端口是OpenSSH。此时已经可以确认,这台靶机的主要攻击面就是Web和SSH,接下来就围绕这两个入口展开。
2.2 Web服务指纹识别与Hosts绑定
浏览器直接访问http://192.168.56.105,页面却跳转到了http://dc-2。这个细节很关键,说明Web服务配置了基于域名的虚拟主机,访问请求必须携带正确的Host头才会返回真实内容。
Linux下最简单的解决办法是修改/etc/hosts文件,把域名和IP绑定起来:
echo "192.168.56.105 dc-2" >> /etc/hosts修改完再访问http://dc-2,就能看到WordPress站点的首页了。
这个操作看着简单,背后的逻辑值得记住:很多Web应用会根据Host头决定返回哪个站点的内容,渗透测试时如果直接IP访问是默认页或404,不妨先绑定域名再试试。真实环境里,这类虚拟主机配置也常常隐藏了管理后台或测试站点,是信息收集阶段容易被忽视的点。
站点指纹方面,页面底部或源码中往往能看出用的是WordPress。如果想确认得更细,可以看HTTP响应头,里面会有服务中间件类型和版本信息。进一步的指纹识别,直接交给wpscan输出结果更直观。
2.3 首页藏着的flag1与第一个提示
WordPress首页的正文区域挂着一段看起来像是一篇文章的内容,里面明晃晃一个flag1。内容大意是提示你需要登录才能继续,同时暗示密码字典要用CEWL生成。这就是DC系列的特点——每个flag不仅代表阶段性成果,还会指引下一步方向。
拿到flag1先记录一下原文,后面很多环节都和这段提示呼应。此时自然而然的方向就是:既然这是WordPress站点,接下来就要做用户枚举和密码爆破。而CEWL这个东西的作用,是爬取网站页面内容并提取关键词生成字典。为什么用CEWL而不是直接用rockyou?因为flag提示你用CEWL,说明靶机作者希望字典基于站点自身内容生成,这也模拟了现实场景中利用站点公开信息定制字典的常见做法。
3. WordPress渗透:用户枚举与密码爆破
3.1 wpscan扫描用户列表
WordPress站点的用户枚举是经典突破口,因为WordPress的作者页面、REST API都可能泄露用户名。DC-2没有做额外的隐藏措施,用wpscan直接枚举就行:
wpscan --url http://dc-2 --enumerate u--enumerate u表示枚举用户。wpscan跑完会列出两个用户名:tom和jerry。这个结果在之后所有环节都起作用,多记住几个名字没坏处。
如果你在扫描过程中遇到wpscan提示API请求失败之类的问题,多半是API token限制的锅,不影响本地枚举功能。想省事可以在命令里加上--disable-tls-checks,把TLS相关的校验关掉。
3.2 用CEWL生成定制密码字典
按照flag1的提示,用CEWL爬取站点生成字典:
cewl http://dc-2 -w dict.txt命令会爬取首页的所有文本内容,把里面出现的单词提取出来,每个词一行,存到dict.txt。默认生成的字典可能比较大,里面有一些无意义的词组,但在这种刻意设计的靶机里,密码往往直接取自页面上的某个单词,所以CEWL效果出奇地好。如果想更精确一点,可以加上-m 6参数只保留长度不小于6的单词,密码太短的可能性不大。
CEWL的好处是生成的字典和站点强相关,适合这类小型站点。真实渗透中,如果目标是一个内容丰富的CMS站点,用CEWL生成的字典命中率通常比通用字典高,因为很多管理员习惯用和站点相关的词做密码。
3.3 wpscan密码爆破与两组有效凭据
拿到字典后,把枚举出的用户和字典组合起来做密码爆破:
wpscan --url http://dc-2 --usernames tom,jerry --passwords dict.txt这里要注意参数的写法。--usernames可以直接用逗号隔开的用户名列表,--passwords指定字典文件。wpscan会针对每个用户名尝试字典里的每个密码,过程中会有大量HTTP请求,需要几分钟时间慢慢跑。
爆破结果显示,tom和jerry两个账号都有对应的有效密码。这两个密码就是后续SSH登录和Web后台登录的关键凭据,先记录下来。
实操心得:wpscan的爆破本质就是调用WordPress的登录接口反复尝试,速度受限于网络状况和服务器响应。如果嫌慢,可以先用小字典快速验证思路,确认用户名有效再跑大字典。另外,爆破出来的密码建议立刻用
ssh试一下,因为很多情况下管理员在Web和系统上会共用密码。
3.4 登录后台拿到flag2与rbash提示
用tom账号和爆破出的密码登录http://dc-2/wp-admin,进入WordPress后台后,在仪表盘或某个页面里能看到flag2。提示内容大致是让你想想怎么借助SSH进入系统,同时明确提到了"rbash"这个词。rbash是受限bash,一种功能受限的Shell环境,通常限制用户切换到其他目录、执行带斜杠的命令等。这句话直接指明了接下来要打的点:尝试通过SSH登录系统,但会遇到受限Shell的阻碍。
如果你尝试登录后台时发现跳转异常,检查一下Hosts绑定是否生效。另外,WordPress后台登录路径有时会被隐藏或修改,但DC-2用的还是默认的/wp-admin,直接访问即可。
4. SSH登录与rbash绕过实战
4.1 非默认端口上的SSH登录尝试
用爆破出的tom账号密码尝试SSH登录,别忘了指定端口:
ssh tom@192.168.56.105 -p 7744这里有个容易踩的坑,SSH命令默认连22端口,如果不加-p 7744,大概率是连接超时或拒绝连接。另外,初次连接时SSH会询问是否确认主机指纹,输入yes即可。
登录成功后会显示一个受限的Shell环境,大概长这样:
tom@dc-2:~$但你会发现,很多常用命令都提示Command not found,比如ls、cat都用不了。这就是rbash的限制。它通过PATH环境变量和SHELL变量限制你能调用的命令集合,你的PATH被指向了一个只有少量命令的目录,连基本的文件查看命令都不在范围内。
4.2 受限Shell的原理与绕过思路
rbash的本质并不复杂,它只是在正常bash启动时做了几层限制:
- 限制
cd,不能切换到其他目录 - 不执行包含斜杠的命令,防止你调用绝对路径的程序
- 通过受限的PATH来限定可用的命令列表
但rbash有个经典弱点:只要你能让bash启动一个子进程,并且这个子进程不受限制,那么限制就形同虚设。常见的绕过思路包括:
- 用
vi打开文件后,在vi内部执行!/bin/bash弹出一个完全的shell - 利用
export PATH重新设置PATH,把正常命令目录加进去 - 利用
ssh直接执行远程命令的特性,绕过登录Shell的限制
在DC-2上,最简单的办法是重新设置PATH。很多WriteUp里用的是:
export PATH=/usr/local/bin:/usr/bin:/bin执行之后,你会发现ls、cat这些命令都能用了。这个操作在真实环境中对应了"受限Shell提权"场景,虽然看起来简单,但是非常经典。
4.3 获取flag3并切换到jerry用户
设置好PATH之后,查看当前目录:
ls -la会发现一个flag3文件,cat出来看内容,提示大概是关于jerry用户的。结合之前的用户枚举信息,正常思路就是切换到jerry用户。切换需要jerry的密码,正好之前用wpscan爆破出来了,直接su jerry即可。
这里有个细节:ssh登录的是tom用户,tom的rbash被绕过之后,在当前shell里执行su jerry,输入jerry的密码,就能切换到jerry。如果su命令提示权限错误,先确认PATH是否已经包含/usr/bin。
切换完成后,顺手再确认一下当前身份,用id看看是不是jerry,同时检查一下jerry有哪些sudo权限,这是下一步提权的敲门砖。
5. Git提权:从jerry到root
5.1 检查sudo权限,发现git的身影
用jerry的身份检查sudo配置:
sudo -l如果sudo命令受限,同样用刚设置的PATH路径。sudo -l 会列出当前用户能够以root身份执行的命令清单。结果显示jerry可以不用密码直接以root身份运行git命令。看到这个结果,基本上就锁定了提权方式:通过git的某种机制执行shell命令,获得root权限。
为什么git能提权?因为git提供了很多交互式的子命令,比如分页器、历史编辑器,这些组件会调用系统Shell来处理用户输入。如果你能通过sudo以root身份运行git,就能利用git的这些交互特性弹出一个root权限的shell。
5.2 利用git pager特性获取root Shell
利用git提权的最经典做法是:
sudo git -p help --help这条命令会打开git帮助页面,但背后的原理是git在显示帮助信息时调用了分页器。分页器通常是less,而less里可以执行shell命令。具体操作时,在git帮助页面出来之后,输入!/bin/bash,就会以root身份弹出一个shell。
如果你试了git -p help --help没反应,也可以试:
sudo git help config或者利用git的--exec-path配合GIT_PAGER环境变量:
sudo GIT_PAGER='bash -c "exec bash 0<&1"' git -p help这几种方式本质上是一样的:让git调用分页器,分页器再调用bash,并把输入输出正确连通。
注意:执行!命令时,如果当前环境是sudo产生的bash,身份就是root。确认一下
id,输出uid=0就说明提权成功。这个过程中如果出现分页器不等待输入的情况,多半是环境变量改错了,多试几种命令组合就能找到适合当前git版本的那一种。
5.3 读取final flag并复盘攻击链
提权成功之后,在root的家目录下就能看到最终的flag文件,直接cat读出内容。至此,DC-2的全部flag收集完毕,整个攻击链也完整走通。
整个流程回顾下来是:
- 信息收集发现Web站点和非常规SSH端口
- WordPress用户枚举得到tom、jerry
- CEWL生成字典并爆破出WordPress密码
- 登录后台获得flag2,获知rbash提示
- SSH登录tom,绕过rbash获得flag3
- 切换jerry,sudo -l发现git可用
- 利用git分页器执行命令,root提权成功
每个环节环环相扣,前一步的flag为下一步指明方向,这就是DC系列最吸引人的地方。
6. 几个踩坑经验与实用心得
6.1 我实际踩过的坑
第一次打DC-2的时候,我在SSH端口上卡了半小时。当时只做了常规端口扫描,没有做全端口,结果SSH服务完全没发现,整条攻击链推不动。后面学了乖,所有靶机一律-p-全端口扫描,没有任何例外。
第二次踩坑是wpscan爆破。爆破过程中我直接用了系统自带的rockyou字典,跑了一个多小时都没出结果。后来才意识到flag1已经提示了用CEWL,这个提示不是摆设,换成CEWL生成的字典之后,几分钟就爆出了密码。这也让我对"先看提示、再动手"这个原则有了更深的理解。
第三个坑是rbash环境里的PATH问题。登录tom后我直接尝试sudo -l、id这些命令,全部提示找不到命令。后来才反应过来,rbash的PATH是受限的,必须重新export PATH。这里也不要用/bin/bash去启动一个完整shell,因为rbash环境里可能不允许执行带斜杠的命令,老老实实重新设置PATH更靠谱。
6.2 为什么git能一路提权到root
git提权背后有两个关键机制。第一个是sudo配置允许jerry以root身份执行git,这一步是靶机作者刻意设计好的脆弱点。第二个是git在交互模式下会调用外部程序来处理输出,最常见的包括分页器(pager)和配置文件的编辑器。如果这些外部程序可以被替换成任意命令,就相当于获得了以git进程身份(root)执行命令的能力。
真实环境中,这类问题也经常出现在允许普通用户通过sudo运行某些管理工具的场景里。所以遇到sudo权限列表里有编辑器、分页器、文件查看器这类交互式工具时,基本都可以考虑类似的绕过思路。比如sudo less、sudo man、sudo vi这些组合,都是经典提权路径。
6.3 给新手的三个建议
如果是第一次接触DC-2,我给三个建议:
第一,每一步操作之后都要记录结果,尤其是flag的内容。DC-2的每个flag都在提示下一步,漏掉一条线索可能就会卡死。
第二,不要跳过信息收集阶段。全端口扫描、服务版本识别、用户枚举这些步骤看着基础,但它们是整条攻击链的起点。磨刀不误砍柴工。
第三,多试几种方法,但一定要搞清楚原理。rbash的绕过方式不止一种,git提权的方式也不止一种,逐个尝试的过程本身就是在理解系统行为。网上固然有WriteUp可以直接抄,但把命令背后的原理和为什么要用这个命令吃透,才算真正把这台靶机的价值发挥出来。
打完DC-2,你可以顺手再试试DC-3、DC-4,你会发现DC系列越往后越贴近真实环境的复杂度,但DC-2打下的基础——信息收集的细致程度、WordPress渗透的常规手法、受限Shell绕过和sudo滥用的思路——都是后续所有靶机通用的底层能力。