[ Inicio ] [ Hacking ] [ CTFs ] [ Rant ]
.:: Brenn0 Weblog ::.

Título : Level 4 - Outro simples stack overflow [OverTheWire CTF – Narnia]
Autor : brennords
Data : 15/01/2017
            

Esse level 4 foi rápido de se resolver e, se você leu o write-up do level 2, também resolve fácil.

De qualquer forma, farei um write up simples indicando a pequena diferença entre os challs.

narnia4@melinda:/narnia$ ./narnia4
narnia4@melinda:/narnia$ ./narnia4 asdfa
narnia4@melinda:/narnia$

Executa-lo não ajudou muito. Hora de cat narnia4.c.

Praticamente a única diferenca entre o level 2 e este é que ele enche de 0’s as variáveis de ambiente. Mas com qual objetivo? Você pode perguntar. Com o objetivo de impossibilitar que guardemos um shellcode em alguma variável de ambiente e faça o programa executa-lo assim que estourarmos o buffer de chars e sobreescrevermos o endereço de retorno.

Se você não entendeu bem como o programa faz isso, deixo esta página com o manual sobre a environ.

Nesta altura do campeonado todos já devem saber o que acontece quando se usa strcpy (linha 17 do código acima) para se copiar um conjunto de dados de tamanho desconhecido para uma variável de tamanho fixo (não sabe? Leia os write-ups desde o level 0).

Diferente do level 3, desta vez não haverá problema algum em usar a stack para guardar um shellcode e executa-lo. Pude confirmar isso usando comando checksec no gdb+peda.

narnia4@melinda:/narnia$ gdb -q narnia4
Reading symbols from narnia4...(no debugging symbols found)...done.
(gdb) source /usr/local/peda/peda.py
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : disabled

A partir desse momento segui os mesmos passos do level 2: descobri o tamanho do buffer que era preciso para sobreescrever exatamente o endereço de retorno e também o endereço que o shellcode estaria. Então enchi o buffer de nops + shellcode + endereço do shellcode.

Acabei ficando com o exploit assim:

Que quando executado:

Mas antes de finalizar, queria salientar que uma coisa nova que aprendi resolvendo esse desafio foi de que algumas vezes o exploit pode rodar dentro do gdb e resultar em um erro fora dele (illegal instruction ou coisa assim). Isso acontece porque o gdb joga umas variaveis de ambiente extras no stack, o que pode bagunçar com os endereços. Ou seja, no gdb vai ser um endereço e fora dele será outro. No passado fiquei confuso quando me deparei com esse tipo de comportamento mas nunca pesquisei a fundo, mas, ao resolver esse chall e ao mesmo tempo tentar entender o máximo possível do que acontecia, encontrei esta bela postagem chamada “Common Pitfalls When Writing Exploits”. Recomendo a leitura.