Ret2lib
Informações Básicas
A essência do Ret2Libc é redirecionar o fluxo de execução de um programa vulnerável para uma função dentro de uma biblioteca compartilhada (por exemplo, system, execve, strcpy) em vez de executar shellcode fornecido pelo atacante na pilha. O atacante cria um payload que modifica o endereço de retorno na pilha para apontar para a função da biblioteca desejada, ao mesmo tempo que organiza para que quaisquer argumentos necessários sejam configurados corretamente de acordo com a convenção de chamada.
Passos de Exemplo (simplificados)
Obter o endereço da função a ser chamada (por exemplo, system) e o comando a ser chamado (por exemplo, /bin/sh)
Gerar uma cadeia ROP para passar o primeiro argumento apontando para a string de comando e o fluxo de execução para a função
Encontrando os endereços
Supondo que a
libc
usada seja a do computador atual, você pode encontrar onde ela será carregada na memória com:
Sabendo qual libc está sendo usada, também é possível encontrar o deslocamento para a função
system
com:
Sabendo qual libc está sendo usada, também é possível encontrar o deslocamento para a função da string
/bin/sh
com:
Usando gdb-peda / GEF
Ao saber qual libc está sendo usada, também é possível usar Peda ou GEF para obter o endereço da função system, da função exit e da string /bin/sh
:
Usando /proc/<PID>/maps
Se o processo estiver criando filhos toda vez que você interage com ele (servidor de rede), tente ler esse arquivo (provavelmente você precisará ser root).
Aqui você pode encontrar exatamente onde a libc está carregada dentro do processo e onde será carregada para cada filho do processo.
Neste caso, ela está carregada em 0xb75dc000 (Este será o endereço base da libc)
Libc desconhecida
Pode ser possível que você não saiba qual libc a binário está carregando (porque pode estar localizada em um servidor onde você não tem acesso). Nesse caso, você poderia abusar da vulnerabilidade para vazar alguns endereços e descobrir qual biblioteca libc está sendo usada:
Leaking libc address with ROPE você pode encontrar um modelo do pwntools para isso em:
Leaking libc - templateConheça a libc com 2 offsets
Verifique a página https://libc.blukat.me/ e use um par de endereços de funções dentro da libc para descobrir a versão utilizada.
Bypassing ASLR em 32 bits
Esses ataques de força bruta são úteis apenas para sistemas de 32 bits.
Se o exploit for local, você pode tentar forçar a base de endereço da libc (útil para sistemas de 32 bits):
Ao atacar um servidor remoto, você pode tentar forçar o endereço da função
libc
usleep
, passando como argumento 10 (por exemplo). Se em algum momento o servidor demorar 10s extras para responder, você encontrou o endereço dessa função.
One Gadget
Execute um shell apenas pulando para um endereço específico no libc
:
Exemplo de Código x86 Ret2lib
Neste exemplo, o brute-force do ASLR está integrado no código e o binário vulnerável está localizado em um servidor remoto:
Exemplo de Código x64 Ret2lib
Verifique o exemplo em:
ROP - Return Oriented ProgramingExemplo ARM64 Ret2lib
No caso do ARM64, a instrução ret salta para onde o registro x30 está apontando e não para onde o registro de pilha está apontando. Portanto, é um pouco mais complicado.
Também no ARM64, uma instrução faz o que a instrução faz (não é possível pular no meio das instruções e transformá-las em novas).
Verifique o exemplo em:
Ret2lib + Printf leak - arm64Ret-into-printf (ou puts)
Isso permite vazar informações do processo chamando printf
/puts
com alguns dados específicos colocados como argumento. Por exemplo, colocar o endereço de puts
na GOT em uma execução de puts
irá vazar o endereço de puts
na memória.
Ret2printf
Isso basicamente significa abusar de um Ret2lib para transformá-lo em uma vulnerabilidade de strings de formato printf
usando o ret2lib
para chamar printf com os valores para explorá-lo (parece inútil, mas é possível):
Outros Exemplos e Referências
Ret2lib, dado um vazamento para o endereço de uma função na libc, usando um gadget
64 bits, ASLR ativado mas sem PIE, o primeiro passo é preencher um estouro até o byte 0x00 do canário para então chamar puts e vazá-lo. Com o canário, um gadget ROP é criado para chamar puts e vazar o endereço de puts da GOT e um gadget ROP para chamar
system('/bin/sh')
64 bits, ASLR ativado, sem canário, estouro de pilha em main a partir de uma função filha. Gadget ROP para chamar puts e vazar o endereço de puts da GOT e então chamar um gadget.
64 bits, sem pie, sem canário, sem relro, nx. Usa a função write para vazar o endereço de write (libc) e chama um gadget.
Usa uma string de formato para vazar o canário da pilha e um estouro de buffer para chamar o sistema (está na GOT) com o endereço de
/bin/sh
.32 bits, sem relro, sem canário, nx, pie. Abusa de um mau indexador para vazar endereços de libc e heap da pilha. Abusa do estouro de buffer para fazer um ret2lib chamando
system('/bin/sh')
(o endereço do heap é necessário para contornar uma verificação).
Last updated