Today I’ll be detailing how to compromise Pink_Panther’s most excellent Pinky’s Palace V1 VM from start to finish. This VM was really interesting, including a few fun things that I’d not previously messed with (Squid proxy for example!)
Right. This is very interesting. Web server on port 8080 which is returning a 403 Forbidden error, Squid HTTP Proxy on port elite 31337 (hopefully you already see what needs to happen, but no problem if not!) and SSH running on port 64666 instead of the usual 22 (presumably to trip up people who are only scanning the standard top 1000 ports which nmap is configured to hit by default.
First of all we’ll be dilligent pentesters and scan the webserver with Dirb and Nikto (although I predict that both will fail.)
And Nikto says…. Absolutely nothing. It wasn’t very happy at all and sat doing nothing for 10 minutes before I hit CTRL+C!
So the next logical thing is the webserver is configured to only accept traffic from localhost, so if we were to set our box up to use Squid Proxy for HTTP comms then things might start working..!
Proxied Dirb says…..
EXACTLY THE SAME AS ABOVE!
Ditto Proxied Nikto. Navigating to the browser for inspiration yielded the 403 error as expected when a proxy wasn’t specified, but when going back to the site with a proxy then the following output is observed:
The standard Squid error page. Notice the very bottom line though: Generated Thu. 29 Mar…….. by pinkys-palace
It was at this point that I wondered if maybe adding a record to /etc/hosts to resolve pinkys-palace to 192.168.56.103 would work.
Bingo! Nothing interesting in the page’s source code but at least now we can try Dirbuster / Nikto against the box again and see what we can see.
Dirbuster and Nikto #2
In reverse order, Nikto reported nothing of interest but Dirbuster came through for us –
Out of 283393 requests, only one item of interest was discovered! Absolutely nothing was discovered with any of the Dirb wordlists, which is what prompted me to change tact and try Dirbuster’s wordlists instead.
SIDE NOTE: Dirbuster is an excellent tool but it seems quite easy to get into a rabbit hole of trying to “bust” for example “/////////” if the webserver returns a 200 code for that kind of URL, which of course is just wasted processing, Dirb doesn’t have that issue.
Little Secrets (-main)
the little secrets login page looks like the above ^ with a HTML comment saying –
” <!– Luckily I only allow localhost access to my webserver! Now I won’t get hacked. –>”
– Haha nah, thanks to your dodgy Squid Proxy we’re attacking via Localhost 😉
So we start by running the usual barrage of SQL injection etc. to see what we can see.
Linux pinkys-palace4.9.0-4-amd64#1 SMP Debian 4.9.65-3+deb9u1 (2017-12-23) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms foreachprogram are described inthe
individual files in/usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY,tothe extent
permitted by applicable law.
Last login:Fri Feb204:00:512018from127.0.0.1
Poking around, we can see that there are two users on the box “pinkymanage” and “pinky”, pinky’s home directory is locked down completely so we go and poke around the web app directory instead for inspiration.
Under /var/www/html/littlesecrets-main/ultrasecretadminf1l35 there’s a “note.txt” talking about an RSA key, and a file named .ultrasecret containing said RSA key (albeit base64 encoded).
So straight away in Pinky’s home directory we see a note which says –
Been working on this program to help me when I need to do administrator tasks sudo is just too hard to configure and I can never remember my root password! Sadly I’m fairly new to C so I was working on my printing skills because Im not sure how to implement shell spawning yet 🙁
And a binary named ‘adminhelper’ with the sticky bit set (??) which appears to echo whatever it’s given back to the terminal. Disassembling the app with the (conveniently installed!) GDB shows us –
So fairly boilerplate stuff EXCEPT for the “spawn” function and what appears to be references to setegid, seteuid and execve… Three functions that execute something as whatever the effective UID and effective GID are set to (hopefully root, thanks to the sticky bit!)
The spawn function looks as follows –
As expected, 0 is put into rbp-0x4 and rbp-0x8 and then passed as arguments to seteuid and setegid which means that we’re setting our effective user / group IDs to 0 which is root!, then we load the address of a string out of memory and pass it as an argument to “execve”.
Running the app (to get the correct address offsets and looking at $rip+0xd9 shows us this –
So what this means is that if the app ever makes it into the spawn function, when the instruction pointer hits the execve line, the $RDI register will contain “/bin/sh”.. So putting all of this information together means that if we can get this spawn method to fire then we’ll spawn a root shell 🙂
So how to we get spawn to fire? Well luckily the main method has a buffer overflow!
Notice main+42, strcpy and not the modern replacement of “strncpy” 😀 The author has also been kind enough to disable ASLR so we can simply exploit that bufferoverflow to make EIP point at the first line of the spawn function. Huzzah!
The next step is trial and error with chucking more and more data into the program argument until we completely overwrite either EIP or the return address of main. Let’s do that now! After 5 minutes of jamming more and more 0x41s into the argument, eventually I found that the magic number 72 A’s to get to the point where we can overwrite EIP and then the next 6 bytes are the address which we want to jump to (AKA the start of the spawn method)
Program received signal SIGSEGV,Segmentation fault.
Notice that we’ve tried to “execute” an instruction at offset 0x0000424242424242! (The hex char for ‘B’) So now we just need to swap out the B’s for a real address at the start of the spawn method and we’re off!