As always we start with nmap to discover open ports.
Nmap Scan
nmap -sC -sV -oA bountyhunter 10.10.11.100
Starting Nmap 7.80 ( https://nmap.org ) at 2021-07-29 07:28 EET
Nmap scan report for 10.10.11.100
Host is up (0.16s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
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
There are 2 ports open:
22 => SSH
80 => HTTP
Nothing to do with ssh for now so lets enumerate port 80
HTTP Enumeration
Launching firefox and visiting http://10.10.11.100.
There is portal.php so lets check it. But first lets run gobuster to find any hidden directories while we are enumerating the web application. gobuster dir -u http://10.10.11.100/ -w /opt/SecLists/Discovery/Web-Content/raft-medium-words.txt -t 80 -x php -b 404,403
There is db.php which contains database credentials that may help us if we get LFI.
The portal is under development so lets click on "here".
It takes us to Bounty report system page and it is still in beta.
Looking at the source code i noticed there is no form to be submitted but there is onlick="bountySubmit()" and i think this function is inside bountylog.js.
Looking at bountylog.js, bountySubmit() function is sending the user input data to tracker_diRbPr00f314.php in base64 encoded XML form and getting the response on the page. So i think it may be XXE injection.
Lets put some data and intercept the request with burpsuite and send to Repeater to play with it. The data being sent is base64 encoded then URL encoded and the user input is reflecting on the page.
So to be able to inject XML data we need to decode this string and inject our data then encoding it again. First we URL decode it (CTRL+SHIFT+U) and then base64 decode it (CTRL+SHIFT+B).
Lets see if we can declare a new XML entity as following.
https://book.hacktricks.xyz/pentesting-web/xxe-xee-xml-external-entity
By base64 encoding (CTRL+B) then URL encoding (CTRL+U) it we get the number 3 in the response. Now we know we have XXE injection.
Initial Foothold
Now lets try Reading/etc/passwd. There is a user on the box called “development”
Remember db.php file we got from gobuster earlier? lets read it and get the creds. Reading db.php using PHP filter wrapper which converts a text to base64 string to avoid executing PHP scripts.
Then lets decode the string to get the credentials of the database.
We didn’t see any login page on the web app but we have SSH port open and development user on the box, lets try SSHing to development user using this password. And successfully logged in!
Getting root
There is contract.txt that says I set up the permissions for you to test this. Good luck.
Lets check what we can do with sudo -l
, we can run Skytrain internal tool as root.
Lets take a look at this script
The tool uses eval on one line of the opened file which we can abuse this to get a shell on the box, but there are some conditions we must satisfy.
- The file name must end with .md.
- The first line in the file starts with # Skytrain Inc.
- The second line starts with ** ## Ticket to **.
- The third line starts with Ticket Code:.
- The last line starts with ** followed by a number % 7 = 4 followed by a + ( The number can be 7+4 or 14+4 or 21+4 or ….) so 11 will be fine. After satisfying all the condition we reach the eval function where it will evaluate this line.
Our file will look like this one but on the fourth line we will add our command to be executed.
Now lets create the file, as you can see the first three lines satisfy the conditions and the first number is 11, means 11%7=4 is true so it executes the eval command.
Run the tool with sudo. sudo python3.8 /opt/skytrain_inc/ticketValidator.py and enter the path to the .md file. As you can see it executes whoami as root.
Now for the root shell we only need to change whoami to bash.
And we have rooted the box :D