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

Título : Assemble your way to the flag [Pragyan CTF 2018]
Autor : brennords
Data : 06/03/2018
            

A solução desse chall é bem simples e praticamente só exige que você saiba o que a instrução PUSH faz, e ler o que há na stack usando um debugger qualquer.

O binário do desafio pode ser encontrado neste link.

Assim que se roda o programa, o resultado é:

brenno@budweiser ~/D/c/p/reverse1_question./question
Look for something else....

Depois de usar o comando strings (porque sempre há esperança) e o ltrace para tentar encontrar alguma coisa mais óbvia e falhar, comecei a usar o gdb:

brenno@budweiser ~/D/c/p/reverse1_questiongdb -q question
Reading symbols from question...(no debugging symbols found)...done.

E fui procurar por main:

gdb-peda$ info functions main
All functions matching regular expression "main":

Non-debugging symbols:
0x00000000000006a0 main

main encontrada, hora de ver o que a função principal do programa fazia:

São muitos mov e push. O que tanto essa porra joga na stack?

Para descobrir, setei um breakpoint em main:

gdb-peda$ b *main
Breakpoint 1 at 0x6a0

Rodei o programa com o comando run e, usando o atalho para o comando next, que é a letra n, fui instrução por instrução até chegar no primeiro push rax, após os mov e xor suspeitos, em main+33.

Pelo amor do espaço desperdiçado no post com um monte de lixo, cortei boa parte da saída do gdb e quero que se destaquem a linha 6, que é a instrução que acabou de ser executada, e a linha 13, que representa o valor que está no topo da stack. Parece bastante com um caracter que pode compor a flag: “}”. Para confirmar essa tese, posso muito bem setar um breakpoint em main+52 e usar o comando c (que representa o continue, se não estou viajando) para fazer o programa continuar rodando até lá. E assim o fiz.

Você pode observar que no topo da stack agora há o caracter “y”. Já era óbvio. A flag estava sendo mandada para a stack.

Então, procurei a última instrução push rax, que está em main+555, coloquei um breakpoint na instrução seguinte e fiz o programa continuar a rodar. Assim que ele bateu no meu breakpoint, a flag inteira estava na stack.

Nesse momento, ainda no gdb, foi só usar o seguinte comando: x/30ws $sp que é responsável por examinar a memória no gdb. E os parâmetros que passei significam que quero ler 30w para 30 WORDS (4 bytes) e com o s digo para printa-los como string. E o $sp representa o local inicial da memória de onde quero ler esses bytes. $sp nada mais é do que o stack pointer, o registrador que estará sempre apontando para o topo da stack.

pctf{l3geNds_c0d3_1n_4Ss3mb1y}.