Mencionei o programa da
Check Point Security Academy várias vezes em Habré: sua essência é que a empresa
Check Point anunciou uma competição no formato Capture the Flag no verão, onde a experiência passada do participante não é importante, mas apenas sua capacidade de desvendar o cibercrime quebra-cabeças. Com base nos resultados desta competição, a empresa recrutou vinte participantes para um curso profissional de segurança cibernética de três meses, e todos os participantes desde o início do curso recebem o salário integral de um especialista em KB, sob a obrigação de trabalhar na empresa dois anos após o término do curso.
Em uma competição CTF, uma bandeira pode até ser uma imagem, como esta.A seleção dos participantes foi concluída em agosto, mas o site do concurso continuará em operação até o próximo verão, e convido aqueles que desejam se inscrever e tentar a sorte por interesse esportivo. A competição consiste em 12 quebra-cabeças de complexidade variável, classificados de 10 a 150 pontos.
Aqui, eu quero analisar o quebra-cabeça "Test My Pacience" da categoria "Surprise". Ela tem dificuldade média (50 pontos), e aqui está o texto completo:
Olá
Encontramos Este executável no computador do relojoeiro local.
Há rumores de que de alguma forma o relojoeiro foi a única pessoa que conseguiu quebrá-lo.
Pense que você é tão bom quanto o relojoeiro?
Nota: Este arquivo não é malicioso de forma alguma
Por referência - um binário de 32 bits para Windows, que
alguns antivírus juram , mas se você ainda o executa, fica assim:

Dentro do binário é criptografado; Ele se recusa a executar no depurador; se você tentar conectar um depurador a ele enquanto estiver em execução, ele será imediatamente encerrado. Provavelmente, especialistas da Check Point embrulharam seu quebra-cabeça em um crypto-packer, emprestado de algum tipo de malvari.
Como vamos adivinhar o número composto pelo relojoeiro?
Existem duas maneiras. O primeiro pode ser chamado condicionalmente de que "existe poder, não importa": se o programa não puder ser depurado ao vivo, então depuraremos o morto!
Iniciamos o "Gerenciador de tarefas" de 32 bits (\ Windows \ SysWOW64 \ taskmgr.exe), clique com o botão direito do mouse no processo misterioso e selecione Criar arquivo de despejo. (O Gerenciador de tarefas de 64 bits para processos de 32 bits cria um despejo do emulador wow64cpu, que é mais difícil de trabalhar.)
Examinamos o despejo e vemos que pelo menos as linhas já estão descriptografadas:

Mas as linhas com o número oculto ou a bandeira ainda não estão visíveis.
Passamos à principal arma de calibre: WinDbg (X86) -> Open Crash Dump ...

Onde está na memória a linha que queremos ver impressa - “Bom trabalho, meu amigo!”?
O comando
lm
permite determinar que o binário é carregado de
01140000
a
015b2000
; em seguida,
sa 01140000 015b2000 "Good job my friend!"
localiza a sequência de pesquisa em
0115a0d0
:

Vamos agora descobrir onde esta linha é impressa: talvez algum comando contenha os bytes
d0 a0 15 01
correspondentes ao endereço da linha que você está procurando? (
sb 01140000 015b2000 d0 a0 15 01
)
Boa sorte - essa equipe foi encontrada:

Qual é o código em torno deste comando? (
ub 011412f7; u 011412f7
)

Vimos que, dependendo do resultado da função
01141180
a mensagem desejada é impressa ou "Mensagem errada ..."
O código de função
01141180
ocupa três telas; é muito fácil perceber que essa é uma implementação do
strcmp()
, na qual uma chamada para
Sleep(700)
foi adicionada. Ainda não está claro por que há
Sleep()
; mas ainda não afeta o resultado da função, portanto, descobriremos melhor o que as seqüências de caracteres são comparadas:

Dois ponteiros iguais a
ebp-14h
e
ebp-24h
ebp-14h
; o segundo deles foi passado para a função
011410b0
como
011410b0
.
Não é essa a função que pede o número oculto? Vamos verificar a pilha de chamadas (
k
):

Sim é ela!
O esquema geral do quebra-cabeça agora está claro: o palpite do usuário é armazenado no
ebp-24h
, o número
ebp-14h
no
ebp-14h
, então eles são comparados e "Bom trabalho, meu amigo!" Ou "Errado ..." é impresso.
Tudo o que resta é extrair o número oculto do quadro da pilha. Já conhecemos o
ebp
da pilha de chamadas:

Vamos, vamos ...

Sucesso! Você pode abrir algo saboroso.
Mas três coisas misteriosas foram deixadas sem explicação:
- Por que há uma chamada para
Sleep(700)
dentro do strcmp()
Sleep(700)
? - Por que, quando inserimos o número oculto, o programa congelou por dez segundos antes de imprimir "Bom trabalho, meu amigo!"?
- O que o relojoeiro tem a ver com esse quebra-cabeça?
Então, acontece que existe uma segunda maneira - mais inteligente - de adivinhar o número estimado. Se você apenas tentar aleatoriamente os números de 0 a 9, é fácil perceber que nos nove o programa “trava” um pouco. Se você tentar os números 90-99, poderá ver que no número 98 o programa "congela" duas vezes mais. (Tendo descoberto sua coragem, já entendemos qual é o problema: uma comparação bem-sucedida de cada par de caracteres causa um atraso de 0,7 s.) Para resolver o quebra-cabeça sem sequer iniciar o depurador, bastava selecionar cada dígito seguinte para aumentar o atraso antes da resposta - manualmente com um cronômetro exato ou um script simples. Assim, os compiladores sugeriram um
método antigo de ataque aos algoritmos criptográficos , quando o tempo até uma mensagem de erro é medido e analisado.
Mas aprender a pegar programas envolvidos em cripto-packers desconhecidos é, na minha opinião, mais interessante e mais valioso :-)
Observe que não precisamos descobrir como o binário é criptografado ou como a string com o número que você vê aparece na pilha (vimos no dump que ela não está entre as constantes da string) - conseguimos ficar prontos e prontos, e por isso cerca de uma dúzia de comandos WinDbg foram suficientes.