HackTheBox Busquedas Write Up

For me, this box was actually really interesting. There were a lot of possible rabbit holes that could have increased the time to root significantly. Luckily though, I managed to navigate through all the distractions and come up with a solution.

Website Overview

At first glance the website is a third-party search engine that allows you to enter a query and select a search engine of your choice with which to execute your query. It then either generates a link for you to copy and use, or re-directs you to the link automatically – depending on your choice.

Recon time

When I ran Nmap on this challenge, it revealed a lot of interesting information. This is where I could have got lost quite easily.

 

As you can see, there are some interesting version numbers here, and one piece of software I’d never encountered before. So I did some investigation:

  • Werkzeug is completely new to me. It is a collection of libraries for creating WSGI’s (Web Server Gateway Interfaces). Versions prior to 2.2.3 have a vulnerability with their cookies. It’s not a very critical vulnerability, so I was only going to look more into it if I came up with nothing else during my investigations.
  • This version of OpenSSH has a few DoS attack vulnerabilities, which I thought wouldn’t be relevant here because we don’t want to take the server offline.
  • This version of Apache has a request smuggling vulnerability. It is a critical vulnerability, so it is a possibility.

After my Nmap scan, I did the usual directory enumeration and found one directory that I already knew existed from just using the website: /search and another called /server-status. So nothing of real interest there.

Wappalyzer showed me that the website is using flask. I already knew from the Nmap scan that it was using Python.

Finally, I had another look at the website and saw something else that piqued my interest. The website is using something called Searchor:

A quick google revealed that Searchor is a Python library used for generating search query urls. Some further googling revealed a vulnerability in Searchor related to the unsafe implementation of the eval function in Python. There is no CVE for it, and only versions before 2.4.2 are vulnerable. So let me look a little deeper. I already know that the eval function, if improperly implemented, allows an attacker to execute code. What I don’t know, is exactly how this version of Searchor is implementing eval. So, to save myself a lot of time and trial and error, I can go to the Git repository and check out the code for version 2.4.0.

User Exploitation

Right, so I can see that the code does not sanitize the query that is being entered. This means that I can definitely exploit this and get it to execute code. So, to further clarify, if I enter the query ‘hello’ the code will look like this:

url = eval(f”Engine.{engine}.search(‘hello’, copy_url={copy}, open_web={open})”)

Thus, I need to inject something into my query that will be able to execute code for me. Let me try and close the query and comment out the rest and see if I still get a response. To do this, I will add ‘,)# to the end of my query and see what happens. By adding this, I’m making the code look like this:

url = eval(f”Engine.{engine}.search(‘hello’,’)#, copy_url={copy}, open_web={open})”) – remembering that the # is commenting out the rest of the code

 

As you can see, there is no change in the response. So we’ve confirmed that we can close off the code and comment out the rest. This leaves it open for us to add in more code for execution. The next step is to test a simple command like ‘ls’. To do this, I’m going to inject a second eval function to try and run a system command (ie. ‘ls’). In order for a system command to be executed, I’ll need to import the ‘os’ python library so that I can access the system command:

Success! I’ve managed to execute the ‘ls’ command. Now, I can change this payload to execute whatever I need to progress this challenge. First thing I want to do is read important files like /etc/passwd and /etc/hosts:

Next, I’m going to try and read the flag. I sent through a few commands to locate the flag and read it, but I’m not going to show you that part as you can do it yourself.

Root Exploitation

While I was looking for the flag, I also looked for some hidden folders using ‘ls -a’. I found a hidden git folder that contained a config file. Upon reading the config file I found some more interesting information:

I also noticed in the hosts file that there is also a subdomain named gitea.searcher.htb. I added that to my hosts file and this is what I found:

The server is running Gitea, which is a self-hosted Git service. Looking around on the site I noticed that there are 2 users, Cody and Administrator. Maybe I can try ssh into the server using the credentials I found in the config file (I could use those credentials to log into his Gitea account, but there is nothing worthwhile in there). I’m hoping that he is using the same password for both.

My attempt to ssh using those credentials was unsuccessful. However, when I was searching for the user flag I found it under a user named ‘svc’. So let me try using the password I found with this user. Great success! I am in:

So now I need to check my privileges and escalate them. First thing to do is ‘sudo -l’ to list what commands I can use with sudo:

It seems I have access to run a python3 script called system-checkup.py. I’m going to try and run this script and see what happens:

The script won’t run because I’m not using it correctly. Luckily, it gives us a list of arguments to try. So I’m going to try each argument and see what happens:

docker-ps
docker-inspect
full-checkup

What I’ve learned from this is that there are two docker containers running on this server, gitea and mysql. I’ve learned that the docker-inspect argument needs two arguments to run – format and container name. The full-checkup didn’t execute and doesn’t give me any further information to work with. Now, I don’t have a lot of experience with docker, but I do know that the docker-inspect command should give us more information about the container. So I went and had a look at the documentation to find out more about the docker-inspect command. I found this, which looks suspiciously similar to what I need:

docker inspect –format='{{json .Config}}’ $INSTANCE_ID

Armed with this information, I was able to dump the configs for both containers:

Gitea
MySQL

Awesome! We have some great information disclosure:

Gitea username and password

 

MySQL username and password

I know that the users Cody and Administrator don’t exist on the server because only the user ‘svc’ exists in the home folder. So I tried to log into the Gitea Administrator account using one of these passwords, and it worked! Look what I found:

I now have access to the system-checkup.py script and can investigate it to see why it was showing me ‘something went wrong’ when I tried to execute the full-checkup command:

When I call the full-checkup argument, it is looking for a full-checkup.sh bash script to execute. The great thing here is that it is using a relative path (“./”) and not an absolute path (“/”), so it is looking for this bash script in the folder that I am executing the command from. So now, all I need to do is find a folder that I can write files to, create a bash script called full-checkup.sh, and execute the system-checkup.py script again. Which folder is most commonly writable? /tmp.

In the tmp folder I created a bash script called full-checkup.sh. The script was super simple, I didn’t even need to escalate my privilege, I simply used the script to read the root flag:

#!/bin/bash
cat /root/root.txt

Finally, I executed the full-checkup.py script and got the flag!

What did I learn?

As I mentioned before, I really enjoyed this challenge. It was fairly straight-forward from the time I found the foothold, but I still learned a lot. The biggest thing I learned was exploiting the eval function, and actually learning more about how the eval function works. I didn’t get sucked down any rabbit holes because I know that ‘Busquedas’ means search, and so when I found the Searchor vulnerability I knew that’s where I needed to focus. I also learned more about docker and privesc.

Resources:

main.py code for Searchor V2.4.0
Searchor update notes that show change in using eval
Information on the eval function
Info on how to exploit the eval fucntion
Searchor vulnerability info
Docker documentation

 

About the Author

Kevin Cochrane

As a husband, father, and dedicated teacher, I've traversed various professional paths in search of my true passion. Now, I'm embarking on an exciting journey as an aspiring Ethical Hacker, driven by a deep commitment to cybersecurity. With each passing day, I immerse myself in learning, honing my skills, and embracing the challenges of this dynamic field.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may also like these