Grep
A challenge that tests your reconnaissance and OSINT skills. - by l000g1c
Last updated
A challenge that tests your reconnaissance and OSINT skills. - by l000g1c
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
Scanning our target with Nmap we can discover four open ports, of which three of them running a web server and the other one is an ssh server.
Knowing the four ports, we refine our scan with the tags -sV
and -sC
to enable version detection and scan with default script to gain more information.
By visiting the first page at port 80 we just get the Apache2 default page.
We aren't able to access the HTTPS page on port 443. We are greeted with a default 403 forbidden page.
Getting back to our Nmap scan, we see that the common Name
is set to grep.thm
for the page on port 443. So we edit our /etc/hosts
file and add grep.thm
to it.
By visiting https://grep.thm/
now we are redirected to https://grep.thm/public/html
. It is a web page under development with the name SearchMe.
Lastly, we try to access the page on port 51337, but are denied with a 403 forbidden page.
Next, we run Gobuster on the web server at port 80, but do not find anything interesting.
Then, we try a directory scan on the HTTPS website using Gobuster. With the -k
flag, we skip the verification of the SSL certificates. We are able to discover some directories, an interesting one is /api
, which will be relevant for the next part.
We get back to the SearchMe website, while browsing it we see, that we are able to visit a register site to create a new account. To see what is happening, we intercept the request using Burp Suite.
We see, that the /api/register.php
is used to create a new account using the X-Thm-Api-Key: e8d25b4208b80008a9e15c8698640e85
. It looks like a MD5 hash.
Upon forwading the request, we get the message, that the key is invalid.
We use crackstation, to quickly crack the hash and get the result johncena
.
From here on, we remember that this is mostly an OSINT challenge. We used the information already made and try by means of google-dorking and the search on GitHub to get further useful hints. Maybe the current API key has been deposited somewhere by mistake. We have the possible user johncena, the website is called SearchME, we know from the intercepted request that it is a PHP application and from the room description that the company behind this application is SuperSecure Corp.
After a few tries, we got a hit via GitHub. With the search for SearchME with the restriction to the programming language PHP, we are able to restrict the repositories far enough. We find the repo supersecuredeveloper/searchmecms
.
Here we are able to look at the commit history and see that a key was removed in a commit: fix: remove key.
Opening the commit, we are able to retrieve another API key, with this, we try to register our new user again. Fun fact, it's also an MD5 hash referring to John Cena.
Again, we intercept the register request and replace the contents of X-Thm-Api-Key
with the one key we found on GitHub.
After forwarding the request we successfully created our new user test
.
Next, we use the credentials of our user to log in and are greeted with the first flag at the dashboard.php
page.
Looking further into the GitHub repository under the /api
directory, we see the source code for an upload functionality. This PHP script handles file uploads in a session-enabled environment. It checks uploaded file types using magic bytes, allowing only JPG, JPEG, PNG, and BMP formats. If the user is logged in and a valid file is uploaded, the script moves the file to an 'uploads/' directory and responds with success, otherwise it provides appropriate error messages.
This script only filter file uploads with a magic byte check, those can easily be manipulated to upload files that appear valid but contain malicious content like a reverse shell.
To check the upload functionality, we fire up cURL and make a quick post request without any data reusing our PHPSESSID cookie and use the option -k to ignore certificate validation. We get the response No file uploaded
.
Next, we add a cute picture of a cat and see, that our upload was successful, but where is it?
We run a Gobuster scan again on the /api
directory and see, that there are more functionalities provided through the api but also the directory uploads.
Visiting the /api/uploads
directory we see the picture of our uploaded cat listed.
And we are able to access our cute cat picture.
We use https://www.revshells.com/ to generate our php reverse shell by providing our IP address and port using the PHP PentestMonkey reverse shell.
We save the raw content into a file on our machine and edit the file applying custom magic bytes by using the hexeditor tool.
In the editor, we add 4 bytes by hitting CTRL+A four times and add FF D8 FF E0 to let the file appear as a JPEG. We save it as evilcat.php, file endings are not checked. First, we saved it as evilcat.jpg, but the reverse shell did not work. For reference see
Next, we upload our evilcat.php
reverse shell using the same cURL command as before. Set up a listener and open the evilcat.php
file at https://grep.thm/api/uploads/evilcat.php
in the browser. The reverse shell connects and we are the user www-data
.
We use the time to quickly upgrade our shell.
On the machine, we find a backup folder in /var/www
. There is a users.sql
file. We use grep to quickly retrieve the admin credentials, a bcrypt hash and his email address.
While running Hashcat on the bcrypt hash, we see that it takes more than 40 minutes to crack. Time to check if the credentials are hidden elsewhere. On further investigation of the machine being www-data
we find the directory leakchecker
, maybe something related to the other web servers.
As www-data
we are not able to check the contents of the files of leakchecker
.
Revisting the page at https://grep.thm:51337/
we check out the certificate and get the common Name leakchecker.grep.thm
.
We add this common name to our /etc/hosts
file and are able to access the Email Leak Checker page on port 51337.
Here, we enter the found email from users.sql
, and are able to retrieve the password of the user admin.