WhyHackMe
Dive into the depths of security and analysis with WhyHackMe. - by suds4131
Last updated
Dive into the depths of security and analysis with WhyHackMe. - by suds4131
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
We start with a nmap scan and discover three open ports. 21, 22 and 80. The corresponding services also run on these standard ports. We can log on to port 21 of the FTP with the user anonymous
.
On the FTP, we find the file update.txt
. This reports that the user mike
had to be deleted due to a compromise. The credentials for the new user can be retrieved under /dir/pass.txt
for all authorized users accessing via localhost. Interesting. That will be useful for later.
While we have Gobuster running, we enumerate the endpoint 80 manually. We are greeted with a link to a blog page, /blog.php
. All clear. We are dealing with PHP here. Let's update the Gobuster scan with -x php
.
On the blog page, we find a comment section, which is only available for logged-in users. There is a link to the login page /login.php
. Furthermore, there is a comment from the user admin
, who points out that he checks every single post. I see.
The login page itself does not seem to be vulnerable, no users are leaked, and a brute force for the admin
seems hopeless.
In the finished Gobuster scan, we see that the registration.php
page is also available. Great, so we don't need to compromise an account, we simply create one. Also, there is an interesting directory, /dir,
which we already have information on from the update.txt
file.
Let's start with an example user first.
Now let's anticipate something. We see a comment field in which we can submit comments. The first thought was stored XSS. A lot has been tried here, including the Unicode Normalization Bypass, but nothing has worked.
All <
,>
were encoded as HTML entities.
Until, after far too long, I noticed that the username also appeared in the comments and that it might also be vulnerable. Said and done, we create the user <script>alert(1);</script>
.
After registration, we log in with the user, visit /blog.php
, and write any comment. Immediately after submitting, we see that we had been successful here.
But what can we do with it? The idea came immediately, I had to think directly of the Challenge Bandit https://0xb0b.gitbook.io/writeups/tryhackme/2023/bandit. In order not to spoil anything, I won't tell you what had to be done in Bandit. It's definitely different from this challenge.
We remember the update.txt
from the FTP, the call to /dir/pass.txt
must be made from localhost
. Mmh, why not let the user call /dir/pass.txt
via XSS and then exfiltrate the information? But first we have to check our assumption to see whether the user is actually calling the page.
Before we log out, we delete our comments so that there is no confusion with the XSS.
We set up a Python web server on port 9000 via python -m http.server 9000
and create a user with the following username:
After we have created our user, logged in and called /blog.php
, we start Burp Suite to intercept our comment so that the XSS is not rendered in our browser.
We send our comment via Burpsuite as the "fetch"
user and see a short time later that the target machine is accessing our web server. Nice. We cannot identify a cookie as the server does not support POST
, but even after checking via nc
, none can be found. But we know our target is on the page. So we can get to /dir/pass.txt
.
Again, we delete our comments before logging out. We make it easy for ourselves and use an existing JavaScript to exfiltrate data:
The following link explains in detail what happens here:
In the script itself, we only need to add our endpoint to lines 68 and 80 and the resource to be exfiltrated to line 33. A request is sent via xhr
to the resource set, and the content is chunked via Image()
requested to our web server in the base64.
By including the script, the function stealData();
is called at the end, which then executes the whole thing.
This payload is a bit simpler due to the script, we only integrate our exfiltration script via our web server.
We create said user, log in, go to /blog.php
, and post a comment, which we intercept in BurpSuite.
We send the request via BurpSuite and a short time later we see the content of /dir/pass.txt
on our web server base64 encoded.
We only have to decode the base64 content and get the credentials from jack
using CyberChef.
Next, we try to log on to the machine with jack
via SSH, and it works. Nice. In the home directory of jack
we find the first flag.
During the initial enumeration, we notice that we can use iptables
as user jack with sudo authorizations. Interesting, as there is nothing about this in GTFOBins to escalate privileges. We may have to open a port for a service we don't know about yet in order to move forward.
In the /opt
directory, we find a pcap
file and an urgent note. This mentions the security incident, which has not yet been fully resolved and has only been mitigated for the time being with a workaround of blocking a specific port. The network traffic was recorded, with the help of which the problem should be solved.
It is also noted that since the hack, there are files in /usr/lib/cgi-bin
that cannot be deleted via root. Probably the persistence of the attacker.
Looking at /usr/lib
we see that we cannot access cgi-bin
and the group is assigned to h4ck3d
. This is probably why root cannot delete it.
So let's take a look at what has been blocked by the admin using iptables
. It is port 41312
. Ok.
sudo /usr/sbin/iptables -L --line-numbers
To get the note and the pcap file, we use a Python web server, but we could also use SCP.
We look at the network recording and cannot recognize anything, we have TLS traffic here, and everything is encrypted. Too bad. We only see port 41312
again, which confirms that this is the malicious port.
Ok, let's open port 41312
, delete the administrator's rule as a precaution, and see what happens on the port.
sudo /usr/sbin/iptables -L --line-numbers
sudo /usr/sbin/iptables -D INPUT
sudo /usr/sbin/iptables -I INPUT -p tcp --dport 41312 -j ACCEPT
First of all, we can use Nmap to confirm that the port is open and see that an Apache web server is behind running.
We are told to use HTTPS
when accessing the page.
OK, but little success here either. We have no access to the page. Gobuster doesn't give us any useful results either, nor does Nikto. We have to take a closer look at the Wireshark recording.
Here is a hint for decrypting the Wireshark traffic. Either a series of session keys or the private key from the certificate is required.
And a lot of time passed before I realized that the attacker was using Apache, which is also used by the blog. So all we had to do was to check where the key was located. To confirm this, the 000-default.conf
can be examined. The search for the key is not really necessary from here on, as this can be taken directly from the config, but was the first attempt.
And fortunately, we also have access to this. So start the web server in /etc/apache2
again or use SCP and download the key.
The key must now be integrated into Wireshark as follows:
Edit->Preferences->TLS-> RSA keys list Edit...
Then we can filter by http
and see the URI for a webshell, finally.
We can access it and execute the command id
.
The next step is to check whether busybox
is available, which was previously forgotten.
We set up a listener and start a reverse shell via busybox
. The reverse shell connects, we are user www-data
, and we upgrade the shell. But that wasn't an upgrade to root, was it? Don't be fooled, enumerate first.
We see via sudo -l
that we can execute everything as sudo. No sooner said than done, we switch to root
using su
, go to root's home directory, and find the final flag there.
Don't miss out on the unintended path to access the root flag through the Chrome Remote Debugging Port
discovered by 0day and jaxafed.
Check out jaxafed's writeup: