The London Bridge
The London Bridge is falling down.
Last updated
The London Bridge is falling down.
Last updated
This work by Manav G Krishna is licensed under CC BY-NC 4.0
Machine IP
: 10.10.139.115
Hosts file entry
: echo '10.10.139.115 london.thm' | sudo tee -a /etc/hosts
Nmap Scan
:
The scan results show that we have two ports open, that is port 22
& 8080
.
Checking out port 8080
:
From the source code
of the page, we can see that the only functioning options containing links are Gallery
& Contact
:
We can now test for XSS
in the Contact Us
form:
Now let's set up a netcat
listener on port 80
. If the above payload works after clicking on Submit
we should be getting a connection back on our listener which shows that the server has reached out to our machine. The IP
specified in the payload is the tun0
interface IP
.
But unfortunately, we don't get any connection on the listener.
We can now check out the Upload
option that we have on the Gallery
page by uploading an image:
As we can see the image gets uploaded successfully within the /uploads
path. The source code of the /gallery
page shows the same and we also have this note:
Let us try to put some other file format for example a PHP
file to see how the feature reacts:
Based on the response, we cannot upload any file that isn't an image
. I will be directly jumping to the point that none of the file upload bypasses had worked here and there was no good information from any of the already present images metadata. This wasn't the correct path to go further into solving the room.
We can now do some directory busting
.
Directory Busting
:
Command
:
There is a path named /dejaview
. We can check this out:
We have a box where we could enter an image URL
and then it would show us the image. Trying out the same with our previously uploaded car.jpeg
image (http://london.thm:8080/uploads/car.jpeg
):
And it gives us the image. But the note in the Gallery
page's source code said we could add images using links which is not the case here. So that likely means that the devs might not have implemented this feature yet.
But we have a box wherein we can enter a URL
. The first thing that comes to mind is SSRF
(Server-Side Request Forgery
).
Intercepting the View Image
request in Burp
:
There is a parameter
named image_url
. We can test for SSRF
here by seeing if the server is reaching out to our attacker machine
(The same setup that we had done before while testing for XSS
applies here too).
The value is URL encoded
. But we don't get any hit on the listener on port 80
. This is where the Hint
given to us for the room comes in handy.
It tells us to check for other parameters
apart from the one that we already know, that being - image_url
.
To find parameters
we can make use of a tool called Arjun
and the same can be done using tools like wfuzz
, ffuf
etc.
Using wfuzz
:
Firstly we have to fetch a wordlist
:
Save this to a file called params.txt
or just clone the repo.
Command
:
Using Arjun
:
Command
:
We have found another parameter
named - www
.
Let us now try SSRF
by using this newly found parameter
in the request:
And the server reached out to us. We now have a successful SSRF
.
Let us try connecting to the localhost
of the target machine now:
But it gives us a 403 Forbidden
error. Upon replacing 127.0.0.1
with localhost
too we end up getting the same response. This likely means that there is something on the target machine preventing us from using the traditional methods
to connect to the localhost via ways like using: 127.0.0.1
, localhost
etc.
Let us now try 127.0.1
. This is one of the many block list bypass
techniques that can be used to connect to localhost
.
And it worked. This means port 80
is open
. This: http://127.0.1
, is the same as doing a http://127.0.1:80
.
For the sake of the writeup let us go ahead and ignore the information that we now know about port 80
being open
. Assume it wasn't 80
and if we had to find out other internally open ports
. The below section explains how this can be achieved through a Python script
and also via wfuzz
.
SSRF Port Scanning Python script
:
The ports can also be specified in this manner: 80 85 8080-8085
.
But anyways we now know that ports such as 80
, 8080
, etc. are open. The 8080 is nothing but the web server
itself that we are able to access externally
.
Using wfuzz
:
We need to first create a wordlist
containing a few of the most common ports
:
Command
:
Now that we've confirmed port 80
is open
and serving content, we can proceed to explore potential directories
that may be accessible within it.
Using wfuzz
:
Firstly we have to fetch a wordlist
that contains directory paths
:
A few entries:
Command
:
We get a good amount of valid hits
, .ssh
being the most interesting. Let us check it out:
The private (id_rsa
) and the public key (authorized_keys
) is present within the .ssh
directory.
We can now read the contents of it:
The public key shows that the private key possibly belongs to a user named beth
.
Now we can possibly SSH
in as beth, post putting the private key to a file on our attacker machine
.
Command
:
We indeed get in.
In the home directory, we don't see the user flag
.
Finding the flag
:
There is also an app.py
and here we can see the lines of code that were blocklisting
common ways localhost
could be accessed via:
So using: localhost
, 127.0.0.1
& 0.0.0.0
were blocked
.
No significant findings were discovered during the manual traversal of various directories and files. So we can now run linpeas
.
It can be placed in the /tmp
directory as it is universally writeable:
Important information from the output
:
Kernel version
being 4.15.0-112-generic
.
Linux exploit suggester
suggested exploits can also be checked out, this can come in handy as we couldn't find anything else on the machine that would potentially help us privilege escalate
. So kernel exploits
might be the way to root
.
At this point, we can start by looking for exploits
based on the exact kernel version
.
We have two
results from Exploit-DB
. The first result is for CVE-2018-18955
. Linpeas
too had suggested the same exploit and also the affected kernel version
starting range is a close match to what we are having on our target machine
. So this is something worth trying out. The result below is for CVE-2019-13272
and it says affected versions start from 4.10
and our version fits well within the range. This can be tried out too.
The final result shows a GitHub
exploit, CVE-2023-6546
, which too is an LPE
exploit.
Following are the two
main reasons this exploit might end up working:
First reason
:
This is a close match with our OS
:
The same can also be seen in the linpeas
output.
Second reason
:
It is the same Kernel
for us too.
Trying out CVE-2023-6546
:
Command
:
Editing the Makefile
from this:
To this (adding the -static switch
):
Using the -static
switch when compiling with gcc
creates a statically linked executable. This means that all necessary libraries
(like glibc) are included directly within
the executable itself, rather than relying on these shared libraries
at runtime
on the target machine
that it would be run on. This is done to avoid any runtime errors that might occur due to the needed glibc version
not being found on the target, etc.
If it is possible to compile
the exploit code
on the target machine
, then that would work too.
Compiling the exploit code via make, serving it and running it on the target machine
:
We run the exploit using the ubuntu
argument and we are root
.
I had further checked out CVE-2019-13272
but found that the kernel
we have was not tested
for this vulnerability
. Nevertheless, I attempted to exploit it, but unfortunately, it did not
work.
Now finally moving on to CVE-2018-18955
:
After cloning the repo:
We can send the entire directory to the target machine
like so:
Out of the above-marked exploit scripts only the exploit.dbus.sh
worked. Showing the same:
The reason why the dbus
script worked is due to the SUID
bit set on dbus-daemon-launch-helper
. By default, this binary will have the bit set as part of the dbus
package.
Command
:
The root flag
can be fetched from the /root
directory:
Now for this question
:
There is no direct way we could laterally move from beth
to charles
on this machine, so we had to get to root
first.
We see a .mozilla
directory.
And there is a Firefox profile
named 8k3bf3zp.charles
. Such profiles will usually have stored encrypted credentials
.
We can see that the most important file, that is logins.json
is present. The presence of this file indicates that we can go ahead with decrypting
the encrypted password
.
Both logins.json
and key4.db
are needed to decrypt
the saved passwords
in Firefox
:
logins.json
: Contains the encrypted passwords and associated usernames.
key4.db
: Contains the encryption keys used to encrypt and decrypt the passwords in logins.json
.
For decrypting
, we can make use of this tool:
Downloading the profile
to our attacker machine
:
Cloning the repo and running
the tool:
And we get the decrypted password
for charles
.
Room solved!!