
Scanner de vulnerabilidades para apps iOS/Android sem descompilação (DC25 demo lab, CB17)
# README




trueseeing é um scanner de vulnerabilidades rápido, preciso e resiliente para aplicativos iOS/Android. Operamos no nível da Dalvik VM para Android — ou seja, não importa se o aplicativo alvo está ofuscado ou não.
## Capacidade
Atualmente podemos:
* Escanear automaticamente o aplicativo em busca de vulnerabilidades, gerando relatórios em formato HTML/JSON/texto (veja abaixo)
* Manipular o aplicativo para facilitar a análise: por exemplo, ativar o bit de depuração, habilitar backup completo, desabilitar TLS pinning, manipular o nível da API alvo, injetar frida-gadget, etc.
* Examinar o aplicativo em busca de informações gerais
* Copiar dados para dentro/fora do aplicativo através da interface de depuração
* Procurar por determinadas chamadas/consts/sput/iput
* Deduzir constantes/conjuntos de tipos para argumentos de operações
* Escanear chamadas de API/privadas para códigos nativos (NB: você precisa do [ts2-disasm-ghidra](https://github.com/alterakey/ts2-disasm-ghidra))
* Escanear aplicativos iOS para vulnerabilidades básicas (NB: você precisa do [ts2-disasm-ghidra](https://github.com/alterakey/ts2-disasm-ghidra))
* Anexar scripts frida
* Fornecer sessão interativa frida
* Rastrear chamadas
* etc.
## Instalação
### Contêineres
NOTA:
* A partir da versão 2.1.9, estamos no ghcr.io. (Docker Hub está um tanto obsoleto)
* Requer adbd no host para controlar dispositivos.
Fornecemos contêineres para que você possa usar imediatamente da seguinte forma; agora esta também é a maneira recomendada, e a única maneira se você estiver no Windows, de executar:
$ docker run --rm -v $(pwd):/out -v ts2:/cache ghcr.io/alterakey/trueseeing
Se você quiser executar sem estado, omita a montagem do volume em /cache (não recomendado para uso diário; veja também [#254](https://github.com/alterakey/trueseeing/issues/254)):
$ docker run --rm -v $(pwd):/out ghcr.io/alterakey/trueseeing
### Instalar com [uv](https://github.com/astral-sh/uv)
Alternativamente, você pode instalar nosso pacote com [uv](https://github.com/astral-sh/uv) da seguinte forma. Especialmente a forma de instalação `uv tool install` pode ser útil para extensões (veja abaixo), pois concede a elas a maior liberdade. Apenas lembre-se de que você precisa de um JRE e Android SDK (opcionalmente; para mexer com dispositivos):
$ uvx trueseeing
$ uv tool install trueseeing
$ trueseeing
### Instalar com pip (obsoleto)
Claro, você sempre pode usar o bom e velho pip se necessário:
$ pip install trueseeing
## Uso
### Modo interativo
Você pode escanear/analisar/patch/etc. aplicativos interativamente — tornando-o a escolha ideal para análise manual:
$ trueseeing target.apk
[+] trueseeing x.y.z
ts[target.apk]> ?
...
ts[target.apk]> i # mostrar informações gerais
...
ts[target.apk]> pf AndroidManifest.xml # mostrar arquivo de manifesto
...
ts[target.apk]> a # analisar também recursos
...
ts[target.apk]> /s algo # pesquisar texto
...
ts[target.apk]> as # escanear
...
[+] concluído, encontrados 6403 problemas (174.94 seg.)
ts[target.apk]> gh report.html
### Modo em lote
Aceitamos um comando inline (`-c`) ou arquivo de script (`-i`) para executar antes de exibir o prompt, bem como sair imediatamente em vez de exibir o prompt (`-q`; não exigimos um tty neste modo!).
Você pode usar esses recursos para realizar uma varredura em lote, como a seguir, por exemplo, para despejar resultados diretamente no stderr:
$ trueseeing -eqc 'as' target.apk
Para gerar um relatório em formato HTML:
$ trueseeing -eqc 'as;gh report.html' target.apk
Para gerar um relatório em formato JSON:
$ trueseeing -eqc 'as;gj report.json' target.apk
Para obter o relatório gerado na stdout, omita o nome do arquivo do comando `g*` final:
$ trueseeing -eqc 'as;gh' target.apk > report.html
$ trueseeing -eqc 'as;gj' target.apk > report.json
### Modo de varredura não interativo (obsoleto)
Tradicionalmente, você pode escanear aplicativos com a seguinte linha de comando para listar os resultados no stderr:
$ trueseeing --scan target.apk
Para gerar um relatório em formato HTML:
$ trueseeing --scan --scan-output report.html target.apk
$ trueseeing --scan --scan-report=html --scan-output report.html target.apk
Para gerar um relatório em formato JSON:
$ trueseeing --scan --scan-report=json --scan-output report.json target.apk
Para obter o relatório gerado na stdout, especifique '-' como nome do arquivo:
$ trueseeing --scan --scan-output - target.apk > report.html
$ trueseeing --scan --scan-report=html --scan-output - target.apk > report.html
$ trueseeing --scan --scan-report=json --scan-output - target.apk > report.json
## Usos Avançados
### Extensões
Você pode escrever seus próprios comandos e assinaturas como extensões. As extensões são colocadas em `/ext` (contêineres) ou `~/.trueseeing2/extensions/` (uv/pip). Alternativamente, você pode distribuir suas extensões como wheels. Fornecemos informações de tipo para que você não apenas possa verificar tipos de suas extensões com [zuban](https://github.com/zubanls/zuban), mas também obter assistência adequada das IDEs. Veja a seção de detalhes para mais informações.
## Compilação
Você pode compilar da seguinte forma:
$ docker build -t trueseeing https://github.com/alterakey/trueseeing.git#main
Para compilar wheels, você pode fazer com [flit](https://flit.pypa.io/en/stable/), da seguinte forma:
$ flit build
Para hackear, você precisa criar um ambiente de compilação adequado. Com [uv](https://github.com/astral-sh/uv) você pode simplesmente fazer:
$ git clone https://github.com/alterakey/trueseeing.git wc
$ uv sync --locked --dev
$ (... hackear ...)
$ uv run trueseeing ... # para executar
$ uv run zuban check trueseeing && uv run ruff trueseeing # para validar
Success: no issues found in XX source files
$ uv run flit build # para compilar (wheel)
$ docker build -t trueseeing . # para compilar (contêiner)
Com pip, para criar um, primeiramente configure um venv, instale [flit](https://flit.pypa.io/en/stable/) e as ferramentas de validação ([zuban](https://github.com/zubanls/zuban) e [ruff](https://github.com/astral-sh/ruff)) nele, e faça com que o flit instale as dependências. Resumindo, faça algo assim:
$ git clone https://github.com/alterakey/trueseeing.git wc
$ python3 -m venv wc/.venv
$ source wc/.venv/bin/activate
(.venv) $ pip install flit zuban ruff
(.venv) $ flit install --deps=develop -s
(.venv) $ (... hackear ...)
(.venv) $ trueseeing ... # para executar
(.venv) $ zuban check trueseeing && ruff check trueseeing # para validar
Success: no issues found in XX source files
(.venv) $ flit build # para compilar (wheel)
(.venv) $ docker build -t trueseeing . # para compilar (contêiner)
## Detalhes
### Classes de Vulnerabilidade
Atualmente podemos detectar as seguintes classes de vulnerabilidades, em grande parte cobertas pelo OWASP Mobile Top 10 - 2016:
* Uso Impróprio da Plataforma (M1)
* Depurável
* Publicação inadvertida de Activities, Services, ContentProviders, BroadcastReceivers
* Dados Inseguros (M2)
* Com backup (ou seja, suscetível ao ataque de backup)
* Permissões de arquivo inseguras
* Logging
* Comunicações Inseguras (M3)
* Falta de pinning (ou seja, suscetível ao ataque de interceptação TLS)
* Uso de HTTP em texto claro
* WebViews adulteráveis
* Criptografia Insuficiente (M5)
* Frase secreta/chaves secretas codificadas
* Cifras Vernum com chaves estáticas
* Uso do modo ECB
* Problemas de Qualidade do Código do Cliente (M7)
* WebViews refléteis (ou seja, XSSs em tais visualizações devem ser escaláveis para execução remota de código através de reflexão JS)
* Uso de política insegura em conteúdos mistos
* Adulteração de Código (M8)
* Certificados codificados
* Engenharia Reversa (M9)
* Falta de ofuscação
### API de Extensão
Nossa API de extensão está localizada sob o pacote `trueseeing.api`. Como fornecemos informações de tipo com ela, sua IDE irá auxiliá-lo ao escrever suas extensões. Apenas certifique-se de que o PYTHONPATH da sua IDE (ou do seu servidor de linguagem) cubra o venv onde nosso pacote está; veja `uv tool list --show-paths` se você instalou com `uv tool install`. Se você instalou com `uvx`, considere reinstalá-lo com `uvx install`. Se você instalou com pip, você já sabe onde está.
#### Comandos
Para definir novos comandos, implemente `trueseeing.api.Command` e anuncie-os.
A seguinte classe fornecerá um comando de exemplo como `t`, por exemplo:
```python
from typing import TYPE_CHECKING
from trueseeing.api import Command
from trueseeing.core.ui import ui
if TYPE_CHECKING:
from trueseeing.api import CommandMap, CommandPatternMap, ModifierMap, OptionMap, ConfigMap
class MyCommand(Command):
@staticmethod
def create() -> Command:
return MyCommand()
def get_commands(self) -> CommandMap:
return {'t':dict(e=self._test, n='t', d='comando de exemplo')}
def get_command_patterns(self) -> CommandPatternMap:
return dict()
def get_modifiers(self) -> ModifierMap:
return dict()
def get_options(self) -> OptionMap:
return dict()
def get_configs(self) -> ConfigMap:
return dict()
async def _test(self) -> None:
ui.info('olá mundo')
```
#### Assinaturas
Para definir novas assinaturas, implemente `trueseeing.api.Signature` e anuncie-as.
A seguinte classe fornecerá um detector de exemplo como `my-sig`, por exemplo:
```python
from typing import TYPE_CHECKING
from trueseeing.api import Signature
if TYPE_CHECKING:
from trueseeing.api import SignatureMap, ConfigMap
class MySignature(Signature):
@staticmethod
def create() -> Signature:
return MySignature()
def get_sigs(self) -> SignatureMap:
return {'my-sig':dict(e=self._detect, d='assinatura de exemplo')}
def get_configs(self) -> ConfigMap:
return dict()
async def _detect(self) -> None:
self._helper.raise_issue(
self._helper.build_issue(
sigid='my-sig',
title='olá mundo',
cvss='CVSS:3.0/AV:P/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N/',
)
)
```
#### Formatos de Arquivo
Para definir novos formatos de arquivo, primeiramente implemente `Context`s (ABC) para seus formatos, depois implemente `trueseeing.api.FileFormatHandler` para criar e retornar suas instâncias, e anuncie-os.
A seguinte classe fornecerá suporte para arquivo APK sob o tipo chamado `apk2`, por exemplo:
```python
from typing import TYPE_CHECKING
from trueseeing.api import FileFormatHandler
from trueseeing.core.android.context import APKContext
if TYPE_CHECKING:
from typing import Optional, Set
from trueseeing.api import FormatMap, ConfigMap
from trueseeing.core.context import Context, ContextType
class MyAPKContext(APKContext):
# Use um tipo de contexto diferente
def _get_type(self) -> Set[ContextType]:
return {'apk2'}
class APKFileFormatHandler(FileFormatHandler):
@staticmethod
def create() -> FileFormatHandler:
return APKFileFormatHandler()
def get_formats(self) -> FormatMap:
return {'apk2':dict(e=self._handle, r=r'\.apk$', d='formato de arquivo de exemplo', t=None)} # se este handler puder sugerir o tipo de contexto do dispositivo, anuncie em t
def get_configs(self) -> ConfigMap:
return dict()
def _handle(self, path: str) -> Optional[Context]:
return MyAPKContext(path)
```
Então certifique-se de verificar o tipo do contexto em suas assinaturas, fazendo com que sejam ignoradas em contextos não suportados:
```python
context = self._helper.get_context().require_type('apk2')
```
Após a verificação bem-sucedida, `require_type(...)` tentará fazer um downcast para os tipos apropriados para sua conveniência.
Mas por design, funciona apenas para tipos conhecidos (atualmente, o `apk`). Então, se você estiver definindo alguma interface detalhada em suas novas classes de contexto como fazemos para o tipo `apk`, você precisa fazer um downcast aqui, ou seja:
```python
context: MyAPKContext = self._helper.get_context().require_type('apk2') # type:ignore[assignment]
```
É possível definir múltiplos formatos que correspondem ao mesmo padrão. Avaliamos os padrões na ordem do mais restritivo (ou seja, longo) para o menos. Você usa a opção `-F` para forçar algum formato a ser usado com o arquivo alvo, por exemplo:
```
$ trueseeing -F apk2 target.apk
```
#### Requisitos de pacote
Extensões podem ser: a) qualquer pacote colocado em `/ext` (contêiner) ou `~/.trueseeing2/extensions` (pip), ou b) qualquer módulo instalado com o nome prefixado por `trueseeing_ext0_`.
### Origem do Nome do Projeto?
A magia de D&D, [True Seeing](https://www.dandwiki.com/wiki/SRD:True_Seeing).