The London Bridge | TryHackMe CTF | Walkthrough
Initial Scan
sudo nmap -sCV -vvv -A 10.10.162.10Nmap 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:
- Save the post request for which you are fuzzing parameters
- 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 -lpthreadNow run the build something like:
./exploit ubuntuAnd 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.charlesYou 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.