
Scanner de vulnerabilidades para apps iOS/Android sem descompilação (DC25 demo lab, CB17)
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.
Atualmente podemos:
NOTA:
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):
$ docker run --rm -v $(pwd):/out ghcr.io/alterakey/trueseeing
Alternativamente, você pode instalar nosso pacote com 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
Claro, você sempre pode usar o bom e velho pip se necessário:
$ pip install trueseeing
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
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
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
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, mas também obter assistência adequada das IDEs. Veja a seção de detalhes para mais informações.
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, da seguinte forma:
$ flit build
Para hackear, você precisa criar um ambiente de compilação adequado. Com 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 e as ferramentas de validação (zuban e 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)
Atualmente podemos detectar as seguintes classes de vulnerabilidades, em grande parte cobertas pelo OWASP Mobile Top 10 - 2016:
Uso Impróprio da Plataforma (M1)
Dados Inseguros (M2)
Comunicações Inseguras (M3)
Criptografia Insuficiente (M5)
Problemas de Qualidade do Código do Cliente (M7)
Adulteração de Código (M8)
Engenharia Reversa (M9)
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á.
Para definir novos comandos, implemente trueseeing.api.Command e anuncie-os.
A seguinte classe fornecerá um comando de exemplo como t, por exemplo:
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')
Para definir novas assinaturas, implemente trueseeing.api.Signature e anuncie-as.
A seguinte classe fornecerá um detector de exemplo como my-sig, por exemplo:
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/',
)
)
Para definir novos formatos de arquivo, primeiramente implemente Contexts (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:
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:
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:
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
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_.
A magia de D&D, True Seeing.