BlackGate - Proving Grounds Practice
Enumeration
Nmap
Initial Nmap scan revealed Redis and SSH ports were open.
Exploitation
Redis RCE
Redis version was vulnerable to RCE and no authentication was required. So I found Redis RCE Github and cloned it.
To run commands with Redis, I had to clone RedisModules-ExecuteCommand repo and compile it.
But because of the GCC version (I think), I could not compile it. I applied the fixes compiler recommended.
- Add Missing Headers: The errors implicit declaration of function ‘strlen’, ‘strcat’, and ‘inet_addr’ mean the compiler doesn’t recognize these functions because the necessary headers haven’t been included.
Open module.c (src/module.c) and add the following lines to the top of the file (alongside the other #include statements):
#include <string.h> // Required for strlen, strcat
#include <arpa/inet.h> // Required for inet_addr
- Fix Pointer Discard Qualifiers (Warnings): The warning initialization discards ‘const’ qualifier happens because RedisModule_StringPtrLen returns a const char * (a read-only string), but the code assigns it to a char * (a modifiable string).
Update the variable declarations in DoCommand and RevShellCommand to use const:
In DoCommand: Change:
char *cmd = RedisModule_StringPtrLen(argv[1], &cmd_len);
To:
const char *cmd = RedisModule_StringPtrLen(argv[1], &cmd_len);
In RevShellCommand: Change:
char *ip = RedisModule_StringPtrLen(argv[1], &cmd_len);
char *port_s = RedisModule_StringPtrLen(argv[2], &cmd_len);
To:
const char *ip = RedisModule_StringPtrLen(argv[1], &cmd_len);
const char *port_s = RedisModule_StringPtrLen(argv[2], &cmd_len);
- Fix execve Argument (Warning): The warning argument 2 null where non-null expected for execve occurs because execve expects the second argument (argv) to be a pointer to an array of strings, not 0 (NULL). While passing NULL might work on some systems, it is technically incorrect.
In RevShellCommand: Change:
execve("/bin/sh", 0, 0);
To:
char *const args[] = {"/bin/sh", NULL};
execve("/bin/sh", args, NULL);
- Then compile in base directory (make all):
Then simply run Redis RCE and get a reverse shell.
Privilege Escalation
sudo -l
We could run redis-status binary without password as super user.
At first I thought this was a BoF challenge and tried to develop an exploit but could not make it work.
strings
Then I ran strings against the binary and found a password.
This was indeed the password for the binary (redis-status), and when we give that password it shows systemctl status page. Because we ran it as sudo we can simply do !sh to get a root shell.
Privilege Escalation (Kernel Exploit)
I also run linux-exploit-suggester and found some probable exploits.
PwnKit exploit worked and we got a root shell.