To solve this machine, we begin by enumerating open ports using
nmap – finding ports
development, and read
development, we are able to run a python script as
root. Exploiting a code injection vulnerability in the script, we are able to get a shell as
root, and read
Like all machines, we begin by enumerating open ports using
nmap. From our scans, we find ports
$ sudo nmap -v -p- --min-rate 3000 $RHOST [...] $ sudo nmap -sV -A -p 22,80 -oA enum/nmap/tcp-scripts $RHOST # Nmap 7.91 scan initiated Sun Jul 25 10:31:00 2021 as: nmap -sV -A -p 22,80 -oA enum/nmap/tcp-scripts 10.129.188.70 Nmap scan report for 10.129.188.70 Host is up (0.047s 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 Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%) No exact OS matches for host (test conditions non-ideal). Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 80/tcp) HOP RTT ADDRESS 1 47.54 ms 10.10.14.1 2 47.66 ms 10.129.188.70 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Sun Jul 25 10:31:24 2021 -- 1 IP address (1 host up) scanned in 24.34 seconds
Next, we run
gobuster to enumerate files and directories on the webserver. Doing so, the only interesting results we have are
/db.php. Going to the webserver in the browser, we see a basic page that tells it’s a site for bug bounty hunters.
Clicking the “Portal” link, we are taken to a page that says the portal is under development. It also includes a link to test the bounty tracker.
/resources/bountylog.js, when it is submitted.
/tracker_diRbPr00f314.php. Looking at
/tracker_diRbPr00f314.php, we see that it returns text, that likely uses the values supplied via the XML.
As the XML is formed based on user input, it’s likely vulnerable to XML External Entity (XXE) injection. To test that the XML is formed as we suspect, we use the Bug Bounty System form as intended, and submit some test data. After getting the response in the browser, and comparing it to the POST request in
BurpSuite, we have confirmed our suspicion.
Now that we have confirmed user-controlled XML is being processed, we can create a proof-of-concept (POC) using CyberChef. For our POC, we will try to read the
/etc/passwd file, which we are certain the machine has. For reference, we will use this cheatsheet to create the base64 string needed for the POC. We also need to URL-encode the base64, so it does not get incorrectly sent to the server.
Once we’ve created the POC base64 string, we can use BurpSuite’s
Repeater to send it in the “data” field. Doing so, we get a listing of the user accounts and their relevant information. Notably, we see
development are the only accounts with a shell.
As our POC worked, we can now use it for more data exfiltration. Remembering that previously we found
/db.php, this is the file we will want to read, as it likely contains credentials. Since it probably contains php code, we have to change how we use XML to read the file, as we do not want it to be processed by the server. Looking at the cheatsheet, we can use php wrappers to base64-encode a file, and exfiltrate with no problem. Doing so, we are able to read the contents of the file, and find a password for the database.
Using the password, we test it against the
development user via SSH, and are given a shell. This allows us access to now read
Having gained a shell as
development, we begin our initial enumeration. The first thing we always run is
sudo -l to check for commands/scripts we may run as another user. Doing so, we see we are able to run a python script as
Reading through the script, we see it reads a “.md” file, and checks the first 2 lines for set values. If they are not there, it returns false. Interestingly, further in the script, we see there is an “eval()”, which processes raw python code. Since the argument to the eval() is user supplied, we may be able to exploit it, and get a shell as
root (since the script is ran as root).
Since the code that processes the eval() statement has certain conditions that have to be met in order to execute, we can bypass this limitation by including a nested eval() that contains our code to get a shell. After creating the malicious “.md” file, we run the python script as
root, supply our filename, and get a shell as
root. With this, we are now able to read
Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!