Vulnhub virtual machine; Enter Version 3 - Experience of multiple engagements with WFUZZ to tunneling through socat and pivoting through ports. Take over a local global library file to encountering a buffer overflow print string bug. Finally, employing a custom kernel exploit. You will learn something new.
Legal Usage: The information provided by executeatwill is to be used for educational purposes only. The website creator and/or editor is in no way responsible for any misuse of the information provided. All the information on this website is meant to help the reader develop penetration testing and vulnerability aptitude to prevent attacks discussed. In no way should you use the information to cause any kind of damage directly or indirectly. Information provided by this website is to be regarded from an “ethical hacker” standpoint. Only preform testing on systems you OWN and/or have expressed written permission. Use information at your own risk.
By continued reading, you acknowledge the aforementioned user risk/responsibilities.
Vulnhub Link: https://www.vulnhub.com/entry/pinkys-palace-v3,237/ File: PinkysPalacev3.ova Size: 689 MB
Discover VM on network:
1 |
|
Target: 192.168.56.118
verified via VM as-well:
Enumeration
Nmap Scan:
1 |
|
nothing really enumerated
Unicornscan UDP scan:
1 |
|
again, nothing to note.
Nmap Syn-scan:
1 |
|
Well at this point we see we have an ftp, freeciv (no idea) and possible webserver http-alt.
Nmap Detailed Scan on open above ports:
1 |
|
Investigating /CHANGELOG.txt
we are able to enumerate the exact version of Drupal
to 7.57
Navigating to webserver on port 8000:
indeed we have a web server which looks to possibly be a drupal site.
create an account:
Searchsploit for Drupal:
1 |
|
few interesting finds pertaining our scope and version number
Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution | exploits/php/webapps/44449.rb
download locally and inspect
Enumerate web server with gobuster:
1 |
|
FTP server: Needed to enter with passive mode -p
1 |
|
Discovered WELCOME file along with firewall.sh
if we can get to the box and see if this firewall is on a crontab or SUID we might be able to modify this in a way to get access to high privilege in the future.
Returning back to searchploit 44449.rb
after investigating a bit into the code I realized the code was set for POST instead of GET. Sifting through the code modifications were made to:
added function:
1 |
|
changed:
1 |
|
Execute exploit
1 |
|
we have a low level shell at this point!
Some things we know:
- Box is behind a firewall
- We have a low level shell
- We want to upgrade
Upgrading low level shell:
First try, PentestMonkey Reverse Shells (http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet) - negative across the board
socat - reverse connection
We need a bind shell and we just so happen to have socat
.
For reference socat
allows for tunneling, pivoting and we’ll call network mischief.
setting up our connection on our victims box:
1 |
|
connecting to socat locally:
1 |
|
we have a successful connection.
check network connections:
1 |
|
few more ports open here that we didn’t find initially.
Lets use socat
to port forward the VM’s port 80 over port 4480
target:
1 |
|
Local Kali navigate to port 4480
socat
made the hole for use to pass through.
Make another socat port forward hole with port 65334
1 |
|
second port forward worked as well.
Enter the FUZZ
wfuzz directory enumeration:
1 |
|
“/server-status” looks well worth taking a stab at.
Navigating to /server-status
wfuzz: ‘files + extensions’
1 |
|
pwds.db
discovered
downloaded list locally now lets see if we can make this list work with our PinkSec login page.
What we have at this point:
Possible Username: pinkadmin
Password List: pwds.db
Pin: In my mind pin’s are normally numbers. or 100,000 combinations create pin list with crunch:
1 |
|
Brute Force Engage
with our combined information lets add it together and see if we can brute force this PinkySec Login page with wfuzz.
enumerating the correct username password:
1 |
|
in a sea of “45 Ch” we have a sole “41 Ch”
1 |
|
now, lets figure out this pin with wfuzz (while hiding all other responses & 50 threads)
1 |
|
we now own the pin “55849”
Login to web application with all credentials:
next we setup a socat listener to connect to port 1337
1 |
|
connect to newly open port 1337 via socat
1 |
|
we are now user: pinkysec
next, let’s move to install our ssh key to keep a backdoor.
Create SSH key for pinksec Local kali:
1 |
|
cat public key so we can install it on our target:
1 |
|
target pinksec install ssh key:
1 |
|
quick test connection with ssh key:
1 |
|
port 5555 which we enumerated as SSH in our begin recon.
Next, we begin our enumeration all over again
$HOME directory
pinksecd
has a SUID sticky bit for user “pinksecmanagement”. We now need to figure out exactly how this binary works and figure out an exploit to escalate privileges.
perform strings
on the binary and quicky see that the application is calling a global library file libpinksec.so
For reference .so
files refer to shared objects and/or libraries applications call locally.
Listing dependencies of a binary:
1 |
|
we can see from our dependencies that /lib/libpinksec.so
is writeable, which offers an entry way of taking over this shared object and take us further down the road
Navigate to location of libpinksec.so
1 |
|
Our current location (sanity check):
- We know that
pinksecd
has a SUID for user “pinksecmanagement” - We know that pinksecd calls on
libpinksec.so
- We know the shared object is rewrite-able
Re-writing libpinksec.so: First, we create a script to take over a function and return a “/bin/sh”
1 |
|
compile our new code over libpinksec.so
1 |
|
Execute pinksecd
we have escalated to “pinksecmanagement”
Lets, create another SSH doorway, that we’ll be able to quickly reconnect if anything were to happen.
local kali:
1 |
|
target create our .ssh/authorized_keys
1 |
|
Connect via ssh to “pinksecmanagement”
1 |
|
Enumeration re-begins, we found a SUID bit before lets see if another exists
1 |
|
PSMCCLI
definitely stands out
navigate to location:
and it just so happens to be owned by the one and only “pinky”
File PSMCCLI
at this point we know we are dealing this a 32bit binary.
Reverse Engineer PSMCCLI
Next, since gdb is not on our target box we need to get the file locally - first thought was nc
but we don’t have that luxury but we have base64
encode base64 PSMCCLI save to memory
1 |
|
decode base64 on local kali
1 |
|
great, file is now local!
Check binary protection
installed via apt-get install devscripts
1 |
|
Clear skies ahead~
Move files with socat
- Remote System: socat -u FILE:PSMCCLIb64 TCP-LISTEN:1338,reuseaddr
- Local System socat -u TCP:192.168.56.118:1338 OPEN:out.dat,creat
Reverse Engineer PSMCCLI
fire up gdb-peda
1 |
|
break main and run
disassemble main
1 |
|
we are calling argshow
function
disassemble argshow
1 |
|
which argshow
is calling on a functions printf
which is vulnerable to a format string %x
. When we give the arg of %x
we are telling printf to return the input in hexadecimal.
to which is exactly what is returned.
In this case we are going to use a 23byte shellcode to execve /bin/sh. To exploit the string bug the shell code is normally placed as an environment variable that is then called upon forcing the /bin/sh
.
23byte /bin/sh shellcode: http://shell-storm.org/shellcode/files/shellcode-827.php
we need to find the exact location in which we can place our shellcode to execute in which getenvaddr.c
comes into play:
link: https://raw.githubusercontent.com/Partyschaum/haxe/master/getenvaddr.c
1 |
|
compile on “pinksecmanagement”
gcc compile:
1 |
|
Current location (sanity check):
- We know we have direct memory access using the
%x
and we can print any memory location on the stack - We can write to any location on the stat using
%n
which will count the characters printed to location.
Using objdump
we can now combine these two vectors and overwrite the putchar
and put our shell code to be called instead.
1 |
|
the pointer for putchar is located at 0804a1c
.
add our shellcode as a variable and find our address to write with getenvaddr
- Memory address:
0x0804a1c
- Address to put shellcode:
0xbfffedd
Moved compile getenvaddr
to /tmp
and rand the rest of the commands from this directory.
Add 23byte shellcode for /bin/sh
to an environment variable:
shell storm link: http://shell-storm.org/shellcode/files/shellcode-827.php
1 |
|
Next, locate where the variable will be located in memory during the execution of the binary with getenvaddr
1 |
|
our goal now is to put the address from our SPAWN code 0xbffffe95
into the putchar 0x804a01c
Checking to see if memory aligns correctly:
1 |
|
the 4 bytes of “A”s and “B”s are within our memory address where we will overwrite.
Adding padding, with the stack not aligning quite right I had to add x2 “C”s for everything to sit correctly:
1 |
|
0xbffffe95
= shell code location
1 |
|
Boy’s become Men
And it was at this point things quickly came off the rails. Basically finding the correct padding required for the shell code became an ever increasing problem. 3 days later a solution is found.
Enumerating the stack, from the above python script I quickly ran into issues as I was adding an extra 2 bytes with %08x
along with some mind bending issues revolving using python to create the stack.
switching to perl and verifying with python things began to align.
On to the stack, and comparing them
perl:
1 |
|
python:
1 |
|
playing with both the padding of ‘C’s and narrowing down where they were located in this sequence began and repeated until I was able to align the A’s (41) and B’s (42). My combination that worked is as seen above.
next, we need to verify this location of our A’s and B’s due to the nature of this string exploit we can print off the stack with %x
and eventually write to the stack with %n
Here is where problem 1 of many began,
passing our location the beginning of the A’s first thought of at being at %134
yielded an output I was not expecting:
1 |
|
correct formatting is to add a 0 before the x
Enter script to find location of A’s 4141414
1 |
|
playing around with this script and the amount of C’s for padding would grep the location of what is to be the beginning of the A’s
which before hand had me grasping at straws trying to find this location manually - only leading to much much frustration .
Leading to the next major hurtle; Even after find the correct padding when I would give the arg with both address I wanted to print I would be taken somewhere completely different on the stack.
%136
seemed to be my beginning but when I would add %136
and %137
together on the same line… instant rekt.
and then the moment happened after much enumeration and adding a 0
to the $x
to return the command:
printing the entire correct string:
1 |
|
we now have the exact location of where we need to put the address to our shellcode.
Goal: Push our shell code at address 0xbffffe95
over putchar 0x804a01c
the exploit printf code that we will require will need to not only included our converted addresses to decimal but also include the offsets to be taken into consideration.
In this case 12 bytes were used AA AA BB BB CC CC %134…
before the beginning of our code. Keep this value in the back of the mind.
Enter the Seg Faults
To calculate the location of our shellcode in decimal two websites were used.
http://www.csgnetwork.com/hexaddsubcalc.html https://www.rapidtables.com/convert/number/hex-to-decimal.html
1 |
|
first half=49151 second half=65173-12bytes = 65161
second half first
1 |
|
first half second - extra 1 added to **0xbfff**
now **0x1bfff**
1 |
|
WORKING EXPLOIT
1 |
|
Priv-esc from Pinky
first and foremost move to create SSH key
Create ssh-keygen locally as done before:
1 |
|
echo key to .ssh/authorized_keys
1 |
|
Connect to SSH
1 |
|
note: IP changed as I restarted the box thinking I had messed up PSMCCLI
Privilege check with sudo
1 |
|
two binaries look to be able to run as root. Both are kernel modules and and which will require to be re-wrote or we can use a rootkit Diamorphine (github link: https://github.com/m0nad/Diamorphine)
Path to Root
Premade-Kernal Exploit Diamorphine Install: This exploit is unique in that it allow for it to be ran via an invisuble module sending a signal 64 to any pid.
Verify the kernal is at least 2.6x/3.x/4.x
1 |
|
Downloaded clone of repository && move diamorphine.c
, diamorphine.h
and Makefile
to target and make
:
1 |
|
Execute insmod with sudo:
1 |
|
Kill a pid with -64
invisibility:
Root&Loot
1 |
|
“Bring me the root!” -exec