HackTheBox — OpenSource Writeup

Ardian Danny
5 min readAug 31, 2023

So this is my write-up on one of the HackTheBox machines called OpenSource. Let’s go!

Initial

As usual first of we start with an NMAP scan.

Okay, so there are three ports provided, ports 22, 80, and 3000. Let’s ignore port 3000 for now.

Visiting the website, it seems we can download the website source code.

And it seems we can try the feature as well.

Reading at the source code for a while, it seems there’s a vulnerability in the upload feature.

views.py

...
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
file_name = get_file_name(f.filename)
file_path = os.path.join(os.getcwd(), "public", "uploads", file_name)
f.save(file_path)
return render_template('success.html', file_url=request.host_url + "uploads/" + file_name)
return render_template('upload.html')
...

utils.py

...
def get_file_name(unsafe_filename):
return recursive_replace(unsafe_filename, "../", "")
def get_unique_upload_name(unsafe_filename):
spl = unsafe_filename.rsplit("\\.", 1)
file_name = spl[0]
file_extension = spl[1]
return recursive_replace(file_name, "../", "") + "_" + str(current_milli_time()) + "." + file_extension
def recursive_replace(search, replace_me, with_me):
if replace_me not in search:
return search
return recursive_replace(search.replace(replace_me, with_me), replace_me, with_me)

We can control where our file will be stored by manipulating the name of the file we upload. The application also only filters on ‘../’. Also, from the Docker component given in the source code, we know the app will be run on /app the directory. With all of this information, we can try to overwrite the views.py file with our maliciously edited views.py file.

I added a malicious route called /testing on the views.py, which will execute a python3 reverse shell.

Foothold

Upload the file and manipulate the file name to the right path.

The upload was successful.

Now, I should be able to visit /testing and get a shell back.

We are in. But we are inside of a docker container.

Docker Escape

I spent quite some time trying to figure out how to escape this docker container. Remember the port 3000 we found earlier? We can access that service via the container we are in. This was tricky because we can’t see the service running inside the docker container. When we run netstat, we can’t see anything.

But we can see that the service is running if we try to nc to the gateway on the port 3000.

And it’s a web server.

So, we can try to port-forward this service so we can access the service from our machine. We can use chisel for this. You can download chisel from here https://github.com/jpillora/chisel/releases.

First, transfer the chisel binary to the docker container. Then, we create a chisel server to listen for the port forwarding connection.

Then, using chisel client we can forward the service we discovered earlier.

Now, we can access the service on the port we specify. In my case, http://localhost:7777.

It’s a Gitea service.

There’s a user called dev01.

After quite some time looking around the Gitea website, I found nothing interesting. But looking back on the source code we downloaded earlier, there’s a .git folder.

We can look around the branch and commit history to this .git folder.

There’s a branch called dev .

There are four commits on the dev branch. Looking at each one, I discover that the commit with id be4da71987bbbc8fae7c961fb2de01ebd0be1997 is interesting because it contains user dev01 credentials.

We now got his password, and we can try to log in to the Gitea server.

We are in, and there’s a repository called home-backup.

And inside it, there’s an SSH private key we can use.

We are in.

Getting Root

After doing some enumeration for a while, I found a cronjob running when running pspy64.

It executes some git commands and commits a backup. We know the git location is on our home directory.

There’s also a hooks folder that contains a pre-commit script. According to atlassian.com,

https://www.atlassian.com/git/tutorials/git-hooks#:~:text=Git%20hooks%20are%20scripts%20that,in%20the%20development%20life%20cycle.

the pre-commit script is executed every time you run git commit before Git asks the developer for a commit message or generates a commit object. Since we know that there’s a cronjob running git commitas root, we can create our own pre-commit script that contains a malicious script to escalate our privilege.

After waiting for a bit, our malicious pre-commit script got executed and we can now gain the root shell.

ROOTED!

Final Thoughts

Overall, it’s a fun and creative box. I really like it, especially the foothold part.

Thank you for reading this write-up. Stay safe, everybody!

--

--

Ardian Danny

Penetration Tester, Ethical Hacker, CTF Player, and a Cat Lover. My first account got disabled by Medium, but it won’t stop me from sharing the things I love.