Podemos ver que são reservados 32 bytes para o buffer
Source.c
Imagem 1 |
Vamos executar o binário com 31 A's e depois com 32 A's e ver o que acontece.
Imagem 2 |
Podemos ver que com 32 A's ocorre falha de segmentação.
Vamos analisar com o gdb+peda e visualizar o assembly digitando "disas main".
É interessante setar um breakpoint logo abaixo da função "gets" no endereço
0x08048495
Imagem 3 |
Vamos executar dentro deo gdb e inserir apenas 12 A's para analisar o comportamento da aplicação.
Imagem 4 |
Como podemos ver a execução parou na instrução conforme setado, podemos ver também que o endereço inicial do buffer é 0xfff32c70 e o ebp é 0xfff32c98, logo o endereço de retorno seria o 0xf7d539a1 valor armazenado no endereço
0xfff32c9c conforme imagem abaixo.
Imagem 5 |
Usamos o comando "ni" e continuamos com a execução até a instrução lea esp,[ebp-0x8] que efetuará uma subtração com o endereço de ebp (0xfff32c98) - 8 e salvará no esp, após isso esp será 0xfff32c90. Em seguida ocorre um pop ecx que removerá um endereço da stack e armazenará o valor em ecx, que no caso é o endereço 0xfff32cb0. Então sabemos que com 32 bytes iremos atingir esse endereço o qual é usado mais pra frente para calcular o retorno.
Imagem 6 |
Novamente digitando o comando "ni" seguiremos com a execução até a instrução lea esp, [ecx-0x4] que salvará o resultado da subtração em esp. Como sabemos, ecx tem o valor 0xfff32cb0, efetuando a subtração obteremos o valor 0xfff32cac, esse será o esp, que terá armazenado o valor (0xf7d539a1). Lembra acima que esse seria o possível endereço de retorno? (Imagem 5).
Imagem 7 |
A próxima instrução será um "ret" que remove o endereço de retorno da stack e passa o controle para essa localização.
Imagem 8 |
Ok, sabemos como a aplicação funciona! Vamos analisar como poderiamos tomar controle da aplicação. Sabemos que após os 32 bytes do buffer é armazenado um valor que será armazenado em ecx e algumas instruções depois é subtraído 4 desse valor que resultará no endereço de retorno. Com base nisso iremos agora procurar um call ecx usando o objdump.
objdump --disassemble-all Level01 | grep call
E vemos que existe um call ecx no endereço 0x080485e7 conforme imagem abaixo.
Imagem 9 |
Então, como poderiamos tomar controle da aplicação? Bem, vamos lá, sabemos que após 32 bytes existe um valor que será salvo em ecx ( então iremos inserir nosso endereço de retorno + 4, isso porque em uma outra instrução é subtraído 4 de ecx pra chegar no retorno). O endereço que iremos salvar será o endereço inicial do buffer + 4.
Vamos analisar o exploit do nosso amigo para que as coisas fiquem mais claras. Analisaremos apenas a partir da linha 15.
Imagem 10 |
Executei no gdb-peda e os endereços mudaram.
Na linha 15 existe a variável offset com valor 32 ( tamanho do buffer )
Na linha 16 o endereço 0x080485e7 ( referência para Call ecx) será salvo no inicio do buffer
Na linha 17 o endereço (buffer_addr + 40) dos NOPs. Endereço inicial 0xffffd2f0 + 40 decimal (28 hex) = 0xffffd318
Na linha 20 escreve 24 A's + 8 dos endereços anteriores = ( buffer =32)
Na linha 21 salva o endereço buffer + 4 ( 0x0xffffd2f4 ) após os A's (0x41) que mais tarde será armazenado em ecx e depois subtraído 4 de ecx que será o valor de retorno, 0x0xffffd2f4 (ecx) - 4 = 0xffffd2f0 que é o endereço inicial do buffer onde tem a referência para o call ecx, o qual chamando ecx ( 0x0xffffd2f4 ) que conterá o endereço dos NOPs (0xffffd318) e irá pulando até alcançar o shellcode.
Na linha 22 os NOPs
Na linha 23 o shellcode
Imagem 11 |
Imagem 12 |
Até a próxima.
foda
ResponderExcluirÉ nós man!!
Excluir