
Assistente de avaliação de deeplink, Intent e bridge WebView do Android para hacking ético
Ajudante de avaliação de deeplink, Intent e ponte WebView para Android
O apk-interceptor é um APK de teste Android portátil para avaliações de segurança de aplicações autorizadas. Ajuda engenheiros de segurança a verificar como uma aplicação Android lida com pontos de entrada externos, tais como esquemas URI personalizados, deeplinks, Activities exportadas e pontes JavaScript WebView.
A ferramenta é intencionalmente restrita:
android.permission.INTERNETcontent://Durante as avaliações de segurança de aplicações Android, muitas descobertas de análise estática ainda precisam de uma pequena prova de conceito no dispositivo antes de serem confirmadas: registar um esquema URI personalizado, enviar uma Intent explícita, servir um payload local content:// ou verificar se o JavaScript consegue alcançar uma ponte WebView.
Construir uma nova aplicação de teste descartável para cada caso é repetitivo e propenso a erros. Pequenas diferenças nas entradas do manifesto, autoridades, concessões URI, nomes de pacotes ou construção de Intent podem atrasar a verificação e tornar os resultados mais difíceis de reproduzir.
O apk-interceptor foi criado para tornar esse passo de confirmação repetível. Em vez de escrever um novo APK PoC para cada avaliação, constrói esta ferramenta com o esquema autorizado ou ID de aplicação de que precisas, executas o teste no dispositivo e manténs o fluxo de trabalho restrito por design: sem permissão INTERNET, sem transmissão de dados externos, sem execução de shell e sem dependência de root.
O apk-interceptor é útil para estas tarefas de avaliação:
Walkthroughs detalhados de vulnerabilidades:
content://A aplicação mantém um registo de avaliação em memória para Intents enviadas, deeplinks recebidos, callbacks da ponte, resultados JavaScript e erros. Os registos desaparecem quando o processo da aplicação é morto. Como os registos não são persistidos, captura evidências com capturas de ecrã ou gravação do ecrã enquanto trabalhas.
O apk-interceptor é uma ferramenta de confirmação, não uma framework de descoberta ou exploração. Assume que já sabes o que testar (esquema, classe Activity, nome da ponte) a partir da análise estática, e dá-te uma forma segura e no dispositivo de verificar a alcançabilidade e capturar evidências. É construído para ser instalado num dispositivo de avaliação e até partilhado com um cliente, por isso não inclui permissão INTERNET, execução de shell, exfiltração de dados nem requisito de root.
Onde se posiciona em relação às ferramentas Android habituais:
As duas áreas onde o apk-interceptor tem a vantagem mais clara sobre as alternativas:
adb/análise estática não consegue mostrar.content:// → WebView: um fornecedor não exportado de ficheiro único cujo payload é entregue apenas através de uma concessão de leitura de Intent temporária, além de um WebView de autoteste local para validar primeiro a sintaxe do payload.O apk-interceptor trata o envio e a interceção de forma diferente, e isto é o mais importante de compreender antes de o usar:
| Ação | Módulo | Esquema personalizado necessário em tempo de compilação? |
|---|---|---|
| Enviar uma Intent ou deeplink para outra aplicação | Sender | Não, escreve qualquer URI, pacote ou Activity em tempo de execução |
| Intercetar (receber) um deeplink para um esquema personalizado | Interceptor | Sim, o esquema é fixado no APK em tempo de compilação |
Para enviar um deeplink manipulado para a aplicação avaliada, não precisas de recompilar: usa o modo Implicit Deeplink do separador Sender e escreve qualquer URI.
Para intercetar um deeplink, ou seja, fazer com que o Android encaminhe um esquema personalizado para o apk-interceptor para poderes observar um possível hijack de esquema, deves compilar o APK com esse esquema via --scheme. O esquema é fixo em tempo de compilação propositadamente (uma salvaguarda de design); o apk-interceptor nunca regista esquemas arbitrários em tempo de execução. Se mudares o esquema que estás a avaliar, recompila e reinstala.
adb para instalação no dispositivo e teste opcional por linha de comandosCompila o APK com o esquema URI personalizado que estás autorizado a avaliar:
./build-interceptor.sh --scheme <esquema_personalizado_autorizado>
adb install ./out/apk-interceptor-<esquema_personalizado_autorizado>-debug.apk
Flags opcionais de compilação:
./build-interceptor.sh \
--scheme <esquema_personalizado_autorizado> \
--app-id <id.da.aplicação.personalizado> \
--output ./out
--app-id define o ID da aplicação instalada (a identidade do pacote no dispositivo e a autoridade content://<applicationId>.payload) em tempo de compilação. O padrão é com.sterrasec.apkinterceptor. Substitui-o com --app-id quando precisares de várias compilações instaláveis separadamente para diferentes avaliações. O equivalente no Windows é build-interceptor.bat.
O esquema padrão intercept-poc-example é um placeholder inofensivo. O script de compilação recusa-se a produzir um APK de avaliação com esse esquema padrão.
No primeiro lançamento de cada versão da aplicação, o apk-interceptor mostra um diálogo de uso autorizado. Depois de tocares em I understand, a mesma versão não mostra o diálogo novamente. O separador Sender ainda mostra um aviso persistente porque pode enviar Intents para outras aplicações.
| Sender | Payload | Interceptor |
|---|---|---|
![]() | ![]() | ![]() |
Usa este separador para verificar a interceção de esquemas URI personalizados.
O que mostra:
Fluxo de trabalho básico:
Sobre o Send Test Deeplink: envia sempre <scheme>://test?<os teus params> com um host test fixo, por isso destina-se a confirmar que o apk-interceptor recebe e regista o esquema, não para conduzir as rotas específicas de deeplink da aplicação avaliada. Para enviar um deeplink manipulado que corresponda ao host ou caminho exigido pela aplicação avaliada, usa antes o modo Implicit Deeplink do separador Sender.
Exemplo com adb:
adb shell am start -W \
-a android.intent.action.VIEW \
-d 'my-authorized-scheme://test?source=adb\&message=hello%20world'
Usa \& ao enviar vários parâmetros de query através de adb shell; caso contrário, a shell do dispositivo pode tratar & como um separador de comandos.
Resultado esperado:
RECEIVEDUsa este separador para enviar Intents controladas durante um teste autorizado.
Modos:
Intent(ACTION_VIEW, Uri.parse(uri))Campos e controlos:
Fluxo de trabalho de deeplink implícito:
Fluxo de trabalho de Activity explícita:
Notas:
content:// é útil ao testar se uma Activity alvo passa dados não confiáveis de Intent para um WebView.data da Intent, o que substituiria o URI que escreves no modo Implicit Deeplink, por isso a opção está oculta nesse modo.PayloadProvider não está exportado. A aplicação avaliada consegue ler o content:// anexado apenas porque a Intent lhe concede acesso temporário de leitura via FLAG_GRANT_READ_URI_PERMISSION. Mantém essa flag ativada e entrega o URI através da Intent. Um URI content:// aberto de qualquer outra forma não será legível por outra aplicação.Usa este separador para criar um payload HTML local e validar a sintaxe da ponte JavaScript no próprio WebView de autoteste do apk-interceptor.
O que contém:
content:// geradoFormato do URI do payload gerado:
content://<applicationId>.payload/current.html
O fornecedor serve apenas este ficheiro fixo:
filesDir/payloads/current.html
Fluxo de trabalho de autoteste do payload:
localBridge.BRIDGE_RESULT, console.log e evaluateJavascript result no registo.Exemplo de JavaScript de autoteste:
console.log("payload loaded");
window.localBridge.logResult(window.localBridge.getInfo());
A ponte de autoteste expõe:
window.<nomeDaPonte>.logResult("mensagem");
window.<nomeDaPonte>.getInfo();
Limitação importante:
O WebView de autoteste confirma que o teu payload local e a sintaxe de chamada à ponte funcionam dentro do apk-interceptor. Não consegue observar se o WebView de outra aplicação executou o teu payload ou chamou a sua própria ponte. Para a aplicação avaliada, verifica através da UI, registos, hooks de teste ou Chrome DevTools dessa aplicação, se a aplicação for debuggable.
Risco:
Uma aplicação Android regista um esquema URI personalizado em vez de um App Link verificado. Qualquer outra aplicação pode registar o mesmo esquema, pelo que o Android pode mostrar um seletor de aplicações ou encaminhar links para uma aplicação diferente.
Usa o apk-interceptor para verificar:
Passos:
Evidências a capturar:
Risco:
A aplicação avaliada confia nos parâmetros do deeplink para navegação, carregamento de URL, flags de funcionalidade, seleção de conta ou renderização sem validação suficiente.
Usa o apk-interceptor para verificar:
Passos:
Exemplo de placeholder:
my-authorized-scheme://open?next=https%3A%2F%2Fauthorized-test.example%2Flanding
Não utilizes domínios ou contas reais de terceiros a menos que estejam explicitamente no âmbito.
Risco:
Uma Activity exportada executa ações sensíveis ou exibe dados sensíveis sem verificar o chamador, o estado do utilizador ou a autorização necessária.
Usa o apk-interceptor para verificar:
Passos:
content://.Evidências a capturar:
content://Risco:
A aplicação avaliada carrega dados não confiáveis de content:// da Intent num WebView que também expõe uma ponte JavaScript via addJavascriptInterface.
Usa o apk-interceptor para verificar:
content://Passos:
Limitação importante:
O apk-interceptor não pode receber resultados de outra aplicação a menos que essa aplicação os devolva ou exiba explicitamente. A ferramenta foi concebida para entregar um payload local e validar sintaxe, não para exfiltrar dados.
Verifica que o APK não solicita acesso à rede:
aapt dump permissions ./out/apk-interceptor-<scheme>-debug.apk
Esperado: sem android.permission.INTERNET.
Aciona um deeplink explicitamente para o apk-interceptor:
adb shell am start -W \
-n com.sterrasec.apkinterceptor/.InterceptActivity \
-a android.intent.action.VIEW \
-d 'my-authorized-scheme://test?source=adb'
Aciona um deeplink através do resolvedor do Android:
adb shell am start -W \
-a android.intent.action.VIEW \
-d 'my-authorized-scheme://test?source=adb'
O comando explícito confirma o comportamento da InterceptActivity. O comando implícito confirma o intent-filter do manifesto e o comportamento do resolvedor.
Os testes unitários correm na JVM com Robolectric, por isso não é necessário dispositivo ou emulador. Abrangem o PayloadProvider, incluindo as verificações de whitelist de caminhos e traversal que impedem o fornecedor de servir qualquer coisa que não seja o único ficheiro current.html.
./gradlew testDebugUnitTest
Os resultados dos testes são escritos em app/build/reports/tests/testDebugUnitTest/index.html. A mesma tarefa corre no CI em cada push e pull request para main.
android.permission.INTERNET/current.html é servido pelo PayloadProviderMIT
| Cenário | Módulo | O Que Ajuda a Verificar |
|---|
| Hijacking de esquema URI personalizado | Interceptor | Se outra aplicação pode registar o mesmo esquema personalizado e receber links |
| Manipulação de parâmetros de deeplink | Sender | Se a aplicação avaliada aceita parâmetros inseguros de query/path |
| Exposição de Activity exportada | Sender | Se uma Activity exportada pode ser lançada diretamente por outra aplicação |
Exposição de ponte WebView via content:// | Payload + Sender | Se um payload HTML local consegue alcançar uma ponte JavaScript WebView |
| Verificação de sintaxe de payload local | Payload | Se o teu payload HTML/JS é executado no WebView de autoteste |
| Ferramenta | Função | Como o apk-interceptor difere |
|---|
| jadx / MobSF / QARK / Semgrep | Encontrar pontos de entrada vulneráveis (estático) | O apk-interceptor não analisa nem descompila; confirma uma descoberta que já tens |
deep-C / NSdeepLink / adb am start | Enumerar e enviar deeplinks | O apk-interceptor também pode enviar, mas o seu diferencial é receber um esquema sequestrado e mostrar o URI exato e os parâmetros |
| drozer | Framework de ataque geral no dispositivo (agente + frequentemente root) | O apk-interceptor é um único APK leve com proteções de segurança deliberadas, âmbito mais reduzido e distribuição mais fácil e segura para o cliente |
| Metasploit / Frida | Armar ou hook (ex.: RCE com addJavascriptInterface) | O apk-interceptor apenas verifica a alcançabilidade da ponte com um payload inofensivo; nunca exfiltra nem executa comandos shell |