Mr Unlucky

Descrição do Desafio:

Categoria: pwn Descrição:

I have a love/hate relationship with dota2, I either always win or always lose. there is no inbetween :(

However, Oracle told me that If I win at his cursed game I'll win every match and gain the aegis of Immortality in real life as well!

CAN YOU HELP ME???

Note: The challenge autor is an immortal player already ;)

Arquivos

Arquivo
Descrição

mr_unlucky

Executável do desafio.

Dockerfile

Arquivo docker.

solve.py

Script em Python que resolve o desafio.

📥 Download: Arquivos

Passo a Passo da Solução

1. Análise do executável

Como este desafio não fornece o código-fonte, devemos analisá-lo diretamente.

Primeiramente, verificamos as proteções ativadas no binário para termos uma noção dos desafios que enfrentaremos:

Como podemos ver, o executável possui praticamente todas as proteções ativadas. Em seguida, vamos decompilá-lo para entender melhor seu funcionamento.

Analisando o código pelo Ghidra, podemos identificar duas funções essenciais: main() e print_flag().

Na função main(), observamos que:

  • Uma seed é definida para a função rand() usando o tempo atual (time(NULL)).

  • Um loop é executado 50 vezes (0x32 loops).

  • Em cada iteração, um nome aleatório é selecionado da variável heroes.

  • O usuário deve inserir o nome correspondente.

  • Caso a entrada esteja incorreta, o programa encerra.

  • Se o usuário acertar todas as tentativas, a função print_flag("flag.txt") é chamada.

Nota: As proteções neste caso não serão um problema, pois o objetivo é identificar uma maneira de responder todas as perguntas corretamente.

Código-fonte da main():

Saída de exemplo:

2. Solução

A solução é simples:

  1. Precisamos de uma cópia da lista de heróis armazenada na variável heroes.

  2. Precisamos garantir que a seed usada em nosso script seja a mesma do servidor.

Para obter os nomes, podemos inspecionar a região da memória onde heroes está armazenada no Ghidra:

Ao analisar essa região, podemos identificar que a cada 8 offsets, há um ponteiro para os nomes dos heróis.

Para definir a seed, usamos a biblioteca CDLL, que contém funções da libc.

No entanto, devemos considerar que o programa chama sleep(3) após definir a seed, o que significa que a seed real do servidor será time(NULL) - 3.

Nota: Localmente a seed não deve conter o '-3'.

Flag

ENO{0NLY_TH3_W0RTHY_0N35_C4N_CL41M_THE_AEGIS_OF_IMMORTALITY!!!}

Autor da WriteUp

Membro de Exploitation - HenriUz

Atualizado