The London Bridge | TryHackMe CTF | Walkthrough

The London Bridge | TryHackMe CTF | Walkthrough

Initial Scan

sudo nmap -sCV -vvv -A 10.10.162.10
Nmap scan report for 10.10.162.10
Host is up, received timestamp-reply ttl 60 (0.14s latency).
Scanned at xx IST for 165s
Not shown: 998 closed tcp ports (reset)
PORT     STATE SERVICE    REASON         VERSION
22/tcp   open  ssh        syn-ack ttl 60 OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 58:c1:e4:79:ca:70:bc:3b:8d:b8:22:17:2f:62:1a:34 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDziNs6aSHIQOJFilv8PhCPd676iD1TrhMYe4p4Mj2E3yaAl4xb8DNT2dhpcv6H8EvtCJnAbXmnFTTOZy14fd7FKc2/Mr4MNLsINFpMU8hc85g6S9ZEnWKlU8dw5jUUeZnAbHSTnq6ARvEbT/Y5seiWEJ7IBiUqptlUA2eiOU7g0DFwrYH7n40aDe0m6PKPIfI9G0XO0cJHISeJ0bsSES1uun2WHLM0sRx+17hrBgM2YfD9OevcltVMlQqWasP9lqf2ooOdBvQTq4eH5UyyuEzaRtQwBYP/wWQEVFacejJE1iT2VD6ZAilhlzo9mww9vqTEwGTvatH65wiyCZHMvrSb
|   256 2a:b4:1f:2c:72:35:7a:c3:7a:5c:7d:47:d6:d0:73:c8 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJuZrGZxDIlI4pU1KNZ8A87cWFcgHxRSt7yFgBtJoUQMhNmcw8FSVC54b7sBYXCgBsgISZfWYPjBM9kikh8Jnkw=
|   256 1c:7e:d2:c9:dd:c2:e4:ac:11:7e:45:6a:2f:44:af:0f (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICkCeqFADY/YvhJyJabcs5DVTYbl/DEKEpBoluTuDdB1
8080/tcp open  http-proxy syn-ack ttl 60 gunicorn
|_http-server-header: gunicorn
|_http-title: Explore London
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Server: gunicorn
|     Date: Fri, 14 Nov xxxx GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 2682
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="UTF-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
|     <title>Explore London</title>
|     <style>
|     body {
|     font-family: Arial, sans-serif;
|     margin: 0;
|     padding: 0;
|     background-color: #f2f2f2;
|     header {
|     background-color: #333;
|     color: #fff;
|     padding: 10px 20px;
|     text-align: center;
|     background-color: #444;
|     color: #fff;
|     padding: 10px 20px;
|     text-align: center;
|     color: #fff;
|     text-decoration: none;
|     margin: 0 10p
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Server: gunicorn
|     Date: Fri, 14 Nov xxx GMT
|     Connection: close
|     Content-Type: text/html; charset=utf-8
|     Allow: GET, HEAD, OPTIONS
|_    Content-Length: 0
| http-methods: 
|_  Supported Methods: GET HEAD OPTIONS
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.94SVN%I=7%D=11/14%Time=69170C1C%P=x86_64-pc-linux-gnu%
SF:r(GetRequest,B15,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20gunicorn\r\nDate
SF::\x20Fri,\x2014\x20Nov\x202025\x2005:31:48\x20GMT\r\nConnection:\x20clo
SF:se\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x
SF:202682\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n\x20\x
SF:20\x20\x20<meta\x20charset=\"UTF-8\">\n\x20\x20\x20\x20<meta\x20name=\"
SF:viewport\"\x20content=\"width=device-width,\x20initial-scale=1\.0\">\n\
SF:x20\x20\x20\x20<title>Explore\x20London</title>\n\x20\x20\x20\x20<style
SF:>\n\x20\x20\x20\x20\x20\x20\x20\x20body\x20{\n\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20font-family:\x20Arial,\x20sans-serif;\n\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20margin:\x200;\n\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20padding:\x200;\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20background-color:\x20#f2f2f2;\n\x20\x20\x20\x20
SF:\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20\x20\x20\x20header\x20{\n\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background-color:\x20#333;\n\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#fff;\n\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2010px\x2020px;\n\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text-align:\x20center;\n\x2
SF:0\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20\x20\x20\x20nav\x20
SF:{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background-color:\x2
SF:0#444;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#fff;
SF:\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2010px\x202
SF:0px;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text-align:\x20ce
SF:nter;\n\x20\x20\x20\x20\x20\x20\x20\x20}\n\x20\x20\x20\x20\x20\x20\x20\
SF:x20nav\x20a\x20{\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color
SF::\x20#fff;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20text-decora
SF:tion:\x20none;\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20margin:
SF:\x200\x2010p")%r(HTTPOptions,B3,"HTTP/1\.0\x20200\x20OK\r\nServer:\x20g
SF:unicorn\r\nDate:\x20Fri,\x2014\x20Nov\x202025\x2005:31:48\x20GMT\r\nCon
SF:nection:\x20close\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nAl
SF:low:\x20GET,\x20HEAD,\x20OPTIONS\r\nContent-Length:\x200\r\n\r\n");
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=11/14%OT=22%CT=1%CU=36605%PV=Y%DS=5%DC=T%G=Y%TM=691
OS:70CB8%P=x86_64-pc-linux-gnu)SEQ(SP=FC%GCD=1%ISR=101%TI=Z%CI=Z%II=I%TS=A)
OS:SEQ(SP=FC%GCD=1%ISR=101%TI=Z%CI=Z%II=I%TS=B)OPS(O1=M508ST11NW7%O2=M508ST
OS:11NW7%O3=M508NNT11NW7%O4=M508ST11NW7%O5=M508ST11NW7%O6=M508ST11)WIN(W1=F
OS:4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M
OS:508NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T
OS:4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+
OS:%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y
OS:%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%
OS:RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
]]]

Web Enumeration

We found a website running on port 8080. When I enumerated the website, I found a path /gallery there, you have an option to upload an image to the website.

I tried to upload multiple files to check which kind of files are allowed to upload on it, and from my enumeration, I found that the extension of the file doesn't matter, because when I changed the .jpg file extension to the .php I was able to upload it, but the actual .php file with the .jpg was not getting uploaded.  

This means that the website is checking for magic number of file. So I went ahead and edited the magic number of our reverse shell. But unfortunately, it didn't work either.

So now it's time to enumerate further because I was sure there's nothing to exploit further from here. Now let's run a fuzzer to see if there are any hidden routes on the website.

feroxbuster -u http://10.10.162.10:8080/
 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher                    ver: 2.11.0
───────────────────────────┬──────────────────────
     Target Url            │ http://10.10.162.10:8080/
     Threads               │ 50
     Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
     Status Codes          │ All Status Codes!
     Timeout (secs)        │ 7
     User-Agent            │ feroxbuster/2.11.0
     Config File           │ /etc/feroxbuster/ferox-config.toml
     Extract Links         │ true
     HTTP methods          │ [GET]
     Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404      GET        4l       34w      232c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET       60l      137w     1952c http://10.10.162.10:8080/gallery
200      GET       59l      127w     1703c http://10.10.162.10:8080/contact
200      GET       82l      256w     2682c http://10.10.162.10:8080/
405      GET        4l       23w      178c http://10.10.162.10:8080/feedback
405      GET        4l       23w      178c http://10.10.162.10:8080/upload
200      GET       57l      319w    27009c http://10.10.162.10:8080/uploads/images.jpeg
200      GET      363l     1894w   151239c http://10.10.162.10:8080/uploads/e3.jpg
200      GET      286l     1579w   125448c http://10.10.162.10:8080/uploads/04.jpg
200      GET      286l     1579w   125448c http://10.10.162.10:8080/uploads/07.php1
200      GET      286l     1579w   125448c http://10.10.162.10:8080/uploads/04.php
200      GET      230l     1199w    97517c http://10.10.162.10:8080/uploads/caption.jpg
200      GET      344l     1947w   168990c http://10.10.162.10:8080/uploads/www.usnews.jpeg
200      GET      286l     1579w   125448c http://10.10.162.10:8080/uploads/07.jpg
200      GET     2242l     8558w   712812c http://10.10.162.10:8080/uploads/Thames.jpg
200      GET     6116l    36096w  2841008c http://10.10.162.10:8080/uploads/Untitled.png
405      GET        4l       23w      178c http://10.10.162.10:8080/view_image

Here we can see the last URL we have found here. This URL has not been introduced to us earlier when accessing the website directly. When accessing the URL, it says Method not allowed. So let's change the method, and it worked. 

We now have a website that is asking for the URL to show an image. I guess this is classic SSRF attack.

I tried with multiple payloads, and nothing seems to work.

Unfortunately, after trying a lot, nothing worked. Then I got the hint from the THM Check for other parameters that may been left over during the development phase. If one list doesn't work, try another common one

To perform the parameter fuzzing, we:

  1. Save the post request for which you are fuzzing parameters
  2. Now configure and use this command.
sudo ffuf -u http://10.10.162.10:8080/view_image -w /usr/share/seclists/Discovery/Web-Content/big.txt -X POST -request ssrf.ffuf -ac
        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : POST
 :: URL              : http://10.10.162.10:8080/view_image
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/big.txt
 :: Header           : Accept-Language: en-US,en;q=0.5
 :: Header           : Referer: http://10.10.162.10:8080/view_image
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Header           : Origin: http://10.10.162.10:8080
 :: Header           : Priority: u=0, i
 :: Header           : Host: 10.10.143.144:8080
 :: Header           : User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
 :: Header           : Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 :: Header           : Accept-Encoding: gzip, deflate, br
 :: Header           : DNT: 1
 :: Header           : Connection: keep-alive
 :: Header           : Upgrade-Insecure-Requests: 1
 :: Data             : FUZZ=http://localhost/gallery/04.jpg
 :: Follow redirects : false
 :: Calibration      : true
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

www                     [Status: 403, Size: 239, Words: 27, Lines: 5, Duration: 169ms]
:: Progress: [20476/20476] :: Job [1/1] :: 255 req/sec :: Duration: [0:01:26] :: Errors: 0 ::

So now that we have a new parameter, let's try again.

So whatever we are passing as the www parameter, it's returning 403 FORBIDDEN.

So we ran a fuzzing attack to check whether the other works, and http://127.1:80 returned me a 200 status code.

And when loading the page, we get a "The London Bridge is falling" poem and no other option to proceed, which triggered the thought that there might be some kind of LFI with the SSRF. So let's test that too.

When fuzzing for the LFI .profile gave us some results which tell us that there is LFI here to be exploited, and in the next fuzzing, we found the .ssh folder containing id_rsa and authorized_keys.

Read the content of both from the authorized_keys you will get the username of the user whose keys are found and the private key in id_rsa file.

Use this detail to gain an initial foothold.

Initial foothold and User flag

Now that we have an initial foothold on the system, we will get the user flag. There is no flag in the Beth directory. That means that the flag might be under the Charles directory, which we don't have access to.

I tried many things and nothing worked. At the end, I searched online and got a bunch of walkthroughs and saw that the Linux version is vulnerable. So let's follow that and try to exploit it and our flag. 

Also, earlier I mentioned that there was no flag in the Beth directory, which is wrong; there is a user flag in the __pycache__ directory.

bash-4.4# cat user.txt 
THM{l0n6_l1v3_7h3_qu33n}

Privilege escalation and root flag

When searching for the exploit, I found this https://github.com/ly4k/PwnKit. We clone this repo on our system and create a Python HTTP server, and copy the exploit.c file to the target system and build it using gcc.

gcc exploit.c -o exploit -lpthread

Now run the build something like:

./exploit ubuntu

And bang, you are root.

To get the root flag, simply read the root flag file:

bash-4.4# cat .root.txt 
THM{l0nd0n_br1d63_p47ch3d}

Now, let's get the password of Charles.

It can be found in the charles home directory itself under:

/home/charles/.mozilla/firefox/8k3bf3zp.charles

You can see that the file password and username are encrypted, so we need to decrypt them. Here I will be using this decrypter https://raw.githubusercontent.com/unode/firefox_decrypt/refs/heads/main/firefox_decrypt.py

And we got the username and password:

Username: Charles
Password: thekingofengland

 

Happy Hacking.