hacktricks/mobile-pentesting/android-app-pentesting/android-applications-basics.md

35 KiB

Fundamentos de Aplicações Android

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks:

Encontre vulnerabilidades que importam mais para que você possa corrigi-las mais rapidamente. O Intruder rastreia sua superfície de ataque, executa varreduras proativas de ameaças, encontra problemas em toda a sua pilha tecnológica, de APIs a aplicativos web e sistemas em nuvem. Experimente gratuitamente hoje.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}


Modelo de Segurança Android

Existem duas camadas:

  • O SO, que mantém as aplicações instaladas isoladas umas das outras.
  • A própria aplicação, que permite aos desenvolvedores expor certas funcionalidades e configura as capacidades da aplicação.

Separação de UID

Cada aplicação é atribuída a um User ID específico. Isso é feito durante a instalação do aplicativo para que o aplicativo só possa interagir com arquivos de propriedade de seu User ID ou arquivos compartilhados. Portanto, apenas o próprio aplicativo, certos componentes do SO e o usuário root podem acessar os dados do aplicativo.

Compartilhamento de UID

Duas aplicações podem ser configuradas para usar o mesmo UID. Isso pode ser útil para compartilhar informações, mas se uma delas for comprometida, os dados de ambas as aplicações serão comprometidos. É por isso que esse comportamento é desencorajado. Para compartilhar o mesmo UID, as aplicações devem definir o mesmo valor android:sharedUserId em seus manifestos.

Sandboxing

O Sandbox de Aplicações Android permite executar cada aplicação como um processo separado sob um User ID separado. Cada processo tem sua própria máquina virtual, então o código de um aplicativo é executado isoladamente de outros aplicativos. A partir do Android 5.0(L) o SELinux é aplicado. Basicamente, o SELinux nega todas as interações de processos e depois cria políticas para permitir apenas as interações esperadas entre eles.

Permissões

Quando você instala um aplicativo e ele pede permissões, o aplicativo está solicitando as permissões configuradas nos elementos uses-permission no arquivo AndroidManifest.xml. O elemento uses-permission indica o nome da permissão solicitada dentro do atributo name. Ele também tem o atributo maxSdkVersion que para de pedir permissões em versões superiores à especificada. Observe que os aplicativos Android não precisam pedir todas as permissões no início, eles também podem pedir permissões dinamicamente mas todas as permissões devem ser declaradas no manifesto.

Quando um aplicativo expõe funcionalidades, ele pode limitar o acesso apenas a aplicativos que têm uma permissão especificada. Um elemento de permissão tem três atributos:

  • O nome da permissão
  • O atributo permission-group, que permite agrupar permissões relacionadas.
  • O protection-level que indica como as permissões são concedidas. Existem quatro tipos:
    • Normal: Usado quando não há ameaças conhecidas ao aplicativo. O usuário não é obrigado a aprová-lo.
    • Perigoso: Indica que a permissão concede ao aplicativo solicitante algum acesso elevado. Os usuários são solicitados a aprová-los.
    • Assinatura: Apenas aplicativos assinados pelo mesmo certificado que o exportando o componente podem receber permissão. Este é o tipo mais forte de proteção.
    • AssinaturaOuSistema: Apenas aplicativos assinados pelo mesmo certificado que o exportando o componente ou aplicativos executando com acesso a nível de sistema podem receber permissões

Aplicações Pré-Instaladas

Esses aplicativos geralmente são encontrados nos diretórios /system/app ou /system/priv-app e alguns deles são otimizados (você pode nem mesmo encontrar o arquivo classes.dex). Essas aplicações valem a pena verificar porque às vezes estão executando com muitas permissões (como root).

  • As que vêm com o AOSP (Projeto de Código Aberto Android) ROM
  • Adicionadas pelo fabricante do dispositivo
  • Adicionadas pelo provedor de telefonia celular (se compradas por eles)

Rooting

Para obter acesso root em um dispositivo Android físico, geralmente é necessário explorar 1 ou 2 vulnerabilidades que costumam ser específicas para o dispositivo e versão. Uma vez que o exploit funcionou, geralmente o binário su do Linux é copiado para um local especificado na variável de ambiente PATH do usuário, como /system/xbin.

Uma vez que o binário su está configurado, outro aplicativo Android é usado para interagir com o binário su e processar solicitações de acesso root como Superuser e SuperSU (disponíveis na Google Play Store).

{% hint style="danger" %} Observe que o processo de root é muito perigoso e pode danificar severamente o dispositivo {% endhint %}

ROMs

É possível substituir o SO instalando um firmware personalizado. Fazendo isso é possível estender a utilidade de um dispositivo antigo, contornar restrições de software ou acessar o código Android mais recente. OmniROM e LineageOS são dois dos firmwares mais populares para usar.

Observe que nem sempre é necessário fazer root no dispositivo para instalar um firmware personalizado. Alguns fabricantes permitem o desbloqueio de seus bootloaders de maneira bem documentada e segura.

Implicações

Uma vez que um dispositivo é rooteado, qualquer aplicativo pode solicitar acesso como root. Se um aplicativo malicioso obtiver, ele terá acesso a quase tudo e poderá danificar o telefone.

Fundamentos de Aplicação Android

Esta introdução foi retirada de https://maddiestone.github.io/AndroidAppRE/app_fundamentals.html

Revisão dos Fundamentos

  • Aplicações Android estão no formato de arquivo APK. APK é basicamente um arquivo ZIP. (Você pode renomear a extensão do arquivo para .zip e usar o descompactador para abrir e ver seu conteúdo.)
  • Conteúdo do APK (Não exaustivo)
    • AndroidManifest.xml
    • resources.arsc/strings.xml
    • resources.arsc: um arquivo contendo recursos pré-compilados, como XML binário, por exemplo.
    • res/xml/files_paths.xml
    • META-INF/
      • Certificado vive aqui!
    • classes.dex
      • Bytecode Dalvik para aplicação no formato de arquivo DEX. Este é o código Java (ou Kotlin) compilado que a aplicação executará por padrão.
    • lib/
      • Bibliotecas nativas para a aplicação, por padrão, vivem aqui! Sob o diretório lib/, existem os diretórios específicos da CPU.
      • armeabi: código compilado apenas para processadores baseados em ARM
      • armeabi-v7a: código compilado apenas para processadores baseados em ARMv7 e acima
      • x86: código compilado para X86
      • mips: código compilado apenas para processadores MIPS
    • assets/
      • Quaisquer outros arquivos que possam ser necessários pelo aplicativo.
      • Bibliotecas nativas adicionais ou arquivos DEX podem ser incluídos aqui. Isso pode acontecer especialmente quando autores de malware querem tentar "esconder" código adicional, nativo ou Dalvik, não incluindo-o nos locais padrão.
    • res/
      • o diretório contendo recursos não compilados em resources.arsc

Dalvik & Smali

A maioria das aplicações Android são escritas em Java. Kotlin também é suportado e interoperável com Java. Para facilitar, pelo resto deste workshop, quando me refiro a "Java", você pode assumir que eu quero dizer "Java ou Kotlin". Em vez do código Java ser executado na Máquina Virtual Java (JVM) como aplicações de desktop, no Android, o **Java é compilado para o formato de bytecode _Dalvik Executable (DEX)_** **. Para versões anteriores do Android, o bytecode era traduzido pela máquina virtual Dalvik. Para versões mais recentes do Android, o Android Runtime (ART) é usado. Se os desenvolvedores escrevem em Java e o código é compilado para bytecode DEX, para fazer engenharia reversa, trabalhamos na direção oposta. \

Fluxograma do processo do desenvolvedor. Java para bytecode DEX

Fluxograma do processo do Engenheiro Reverso. Bytecode DEX para SMALI para Java Decompilado

Smali é a versão legível por humanos do bytecode Dalvik. Tecnicamente, Smali e baksmali são os nomes das ferramentas (montador e desmontador, respectivamente), mas no Android, muitas vezes usamos o termo "Smali" para nos referir às instruções. Se você já fez engenharia reversa ou arquitetura de computadores em código C/C++ compilado. SMALI é como a linguagem de montagem: entre o código fonte de alto nível e o bytecode.

Encontre vulnerabilidades que importam mais para que você possa corrigi-las mais rapidamente. O Intruder rastreia sua superfície de ataque, executa varreduras proativas de ameaças, encontra problemas em toda a sua pilha tecnológica, de APIs a aplicativos web e sistemas em nuvem. Experimente gratuitamente hoje.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}


Intents

Intents são o principal meio pelo qual aplicativos Android se comunicam entre seus componentes ou com outros aplicativos. Esses objetos de mensagem também podem transportar dados entre aplicativos ou componentes, de forma semelhante a como as solicitações GET/POST são usadas em comunicações HTTP.

Então, um Intent é basicamente uma mensagem que é passada entre componentes. Intents podem ser direcionados a componentes ou aplicativos específicos, ou podem ser enviados sem um destinatário específico. Para ser simples, Intent pode ser usado:

  • Para iniciar uma Activity, normalmente abrindo uma interface de usuário para um aplicativo
  • Como broadcasts para informar o sistema e aplicativos sobre mudanças
  • Para iniciar, parar e se comunicar com um serviço em segundo plano
  • Para acessar dados via ContentProviders
  • Como callbacks para lidar com eventos

Uma implementação inadequada pode resultar em vazamento de dados, funções restritas sendo chamadas e manipulação do fluxo do programa.

Intent-Filter

Um Intent Filter especifica os tipos de Intent que uma activity, serviço ou Broadcast Receiver podem responder. Ele especifica o que uma activity ou serviço pode fazer e que tipos de broadcasts um Receiver pode lidar. Ele permite que o componente correspondente receba Intents do tipo declarado. Intent Filters são tipicamente definidos através do arquivo AndroidManifest.xml. Para Broadcast Receiver também é possível defini-los em código. Um Intent Filter é definido por sua categoria, ação e filtros de dados. Ele também pode conter metadados adicionais.

No Android, uma activity/service/content provider/broadcast receiver é público quando exported está definido como true, mas um componente é também público se o manifesto especifica um Intent filter para ele. No entanto, desenvolvedores podem explicitamente tornar componentes privados (independentemente de quaisquer filtros de intent) definindo o atributo exported como false para cada componente no arquivo de manifesto. Desenvolvedores também podem definir o atributo permission para exigir uma certa permissão para acessar o componente, restringindo assim o acesso ao componente.

Intents Implícitos

Intents são criados programaticamente usando um construtor de Intent:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

O Action do intent previamente declarado é ACTION_SEND e o Extra é um Uri mailto (o Extra é a informação adicional que o intent está esperando).

Este intent deve ser declarado dentro do manifesto como no seguinte exemplo:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Um intent-filter precisa corresponder à ação, dados e categoria para receber uma mensagem.

O processo de "Resolução de Intent" determina qual aplicativo deve receber cada mensagem. Esse processo considera o atributo de prioridade, que pode ser definido na declaração do intent-filter, e aquele com a maior prioridade será selecionado. Essa prioridade pode ser definida entre -1000 e 1000 e os aplicativos podem usar o valor SYSTEM_HIGH_PRIORITY. Se um conflito surgir, uma janela de "escolha" aparece para que o usuário possa decidir.

Intents Explícitos

Um intent explícito especifica o nome da classe que está sendo alvo:

Intent downloadIntent = new (this, DownloadService.class):

Em outras aplicações, para acessar o intent previamente declarado, você pode usar:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Pending Intents

Esses permitem que outras aplicações tomem ações em nome da sua aplicação, usando a identidade e permissões do seu app. Ao construir um Pending Intent deve-se especificar uma intent e a ação a realizar. Se a intent declarada não for Explícita (não declara qual intent pode chamá-la), uma aplicação maliciosa poderá realizar a ação declarada em nome do app vítima. Além disso, se uma ação não for especificada, o app malicioso poderá fazer qualquer ação em nome da vítima.

Broadcast Intents

Ao contrário dos intents anteriores, que são recebidos apenas por um app, os broadcast intents podem ser recebidos por múltiplos apps. No entanto, a partir da versão 14 da API, é possível especificar o app que deve receber a mensagem usando Intent.set Package.

Alternativamente, também é possível especificar uma permissão ao enviar o broadcast. O app receptor precisará ter essa permissão.

Existem dois tipos de Broadcasts: Normal (assíncrono) e Ordenado (síncrono). A ordem é baseada na prioridade configurada dentro do elemento receptor. Cada app pode processar, retransmitir ou descartar o Broadcast.

É possível enviar um broadcast usando a função sendBroadcast(intent, receiverPermission) da classe Context.
Você também pode usar a função sendBroadcast do LocalBroadCastManager que garante que a mensagem nunca saia do app. Usando isso, você nem precisará exportar um componente receptor.

Sticky Broadcasts

Esse tipo de Broadcasts pode ser acessado muito tempo depois de terem sido enviados.
Eles foram depreciados no nível 21 da API e é recomendado não usá-los.
Eles permitem que qualquer aplicação fareje os dados, mas também os modifique.

Se você encontrar funções contendo a palavra "sticky" como sendStickyBroadcast ou sendStickyBroadcastAsUser, verifique o impacto e tente removê-las.

Deep links permitem acionar uma Intent via URL. Uma aplicação pode declarar um esquema de URL dentro de uma atividade para que, sempre que o dispositivo Android tentar acessar um endereço usando esse esquema, a atividade da aplicação seja chamada:

Neste caso, o esquema é myapp:// (note também a categoria BROWSABLE)

Se dentro do intent-filter você encontrar algo como isto:

Então, está esperando algo como http://www.example.com/gizmos

Se você encontrar algo assim:

Isso significará que está esperando uma URL começando por example://gizmos
Neste caso, você poderia tentar abusar da funcionalidade criando uma web com os seguintes payloads. Ele tentará navegar para páginas arbitrárias e tentar executar JS:

<a href="example://gizmos/https://google.com">click here</a>
<a href="example://gizmos/javascript://%250dalert(1)">click here</a>

Para encontrar o código que será executado no App, vá para a atividade chamada pelo deeplink e procure a função onNewIntent.

Aprenda como chamar deep links sem usar páginas HTML.

AIDL - Linguagem de Definição de Interface Android

A Linguagem de Definição de Interface Android (AIDL) permite que você defina a interface de programação que tanto o cliente quanto o serviço concordam em usar para comunicar-se entre si usando comunicação entre processos (IPC). No Android, um processo normalmente não pode acessar a memória de outro processo. Então, para se comunicarem, eles precisam decompor seus objetos em primitivas que o sistema operacional possa entender e transportar os objetos através dessa fronteira para você. O código para fazer esse transporte é tedioso de escrever, então o Android lida com isso para você com AIDL.

Serviços que usam AIDL são referidos como Serviços Vinculados. Na classe do Serviço, você encontrará o método onBind. É aqui que a interação começa, portanto é a parte inicial do código a ser revisada em busca de potenciais vulnerabilidades.

Um serviço vinculado é o servidor em uma interface cliente-servidor. Ele permite que componentes (como atividades) se vinculem ao serviço, enviem solicitações, recebam respostas e realizem comunicação entre processos (IPC). Um serviço vinculado normalmente existe apenas enquanto atende outro componente da aplicação e não roda indefinidamente em segundo plano.

Messenger

Um Messenger é outro tipo de mecanismo IPC. Como o Messenger também é um "Serviço Vinculado", os dados passados do aplicativo cliente também são processados através do método onBind. Portanto, a revisão de código deve começar neste método e você deve procurar pela invocação de funcionalidades sensíveis ou manipulação insegura de dados.

Binder

É raro encontrar uma classe Binder invocada diretamente, pois é muito mais fácil usar AIDL (que abstrai a classe Binder). No entanto, é bom saber que Binder é um driver de nível de kernel que move dados da memória de um processo para a de outro (https://www.youtube.com/watch?v=O-UHvFjxwZ8).

Componentes

Estes incluem: Atividades, Serviços, Receptores de Transmissão e Provedores.

Atividade Inicial e outras atividades

Uma atividade Android é uma tela da interface do usuário do aplicativo Android. Dessa forma, uma atividade Android é muito semelhante a janelas em um aplicativo de desktop. Um aplicativo Android pode conter uma ou mais atividades, ou seja, uma ou mais telas.

A atividade inicial é o que a maioria das pessoas considera como o ponto de entrada para um aplicativo Android. A atividade inicial é a atividade que é iniciada quando um usuário clica no ícone de um aplicativo. Você pode determinar a atividade inicial olhando para o manifesto do aplicativo. A atividade inicial terá as seguintes intenções MAIN e LAUNCHER listadas.

Lembre-se de que nem todo aplicativo terá uma atividade inicial, especialmente aplicativos sem uma UI. Exemplos de aplicativos sem UI (e, portanto, sem atividade inicial) são aplicativos pré-instalados que realizam serviços em segundo plano, como correio de voz.

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

As Activities podem ser exportadas, permitindo que outros processos no dispositivo iniciem a Activity. Por padrão, elas não são exportadas, mas você pode exportá-las configurando:

<service android:name=".ExampleExportedService" android:exported="true"/>

Note que a capacidade de bypassar proteções de atividade nem sempre é uma vulnerabilidade, você precisa verificar a qual dado você obteve acesso. Além disso, algumas atividades retornam dados para um chamador. Nestes cenários, você precisa procurar pelo método setResult e verificar os dados que são passados no parâmetro Intent. Se for dado sensível, você pode ter uma vulnerabilidade de vazamento de informação e é explorável com apps capazes de se comunicar com a Atividade.

O código de uma atividade começa com o método onCreate.

Subclasse de Aplicação

Aplicações Android podem definir uma subclasse de Application. Aplicações podem, mas não precisam definir uma subclasse personalizada de Application. Se um app Android define uma subclasse de Application, essa classe é instanciada antes de qualquer outra classe na aplicação.

Se o método attachBaseContext é definido na subclasse Application, ele é chamado primeiro, antes do método onCreate.

Serviços

Serviços funcionam em segundo plano sem uma UI. Eles são usados para realizar processos de longa duração, mesmo se o usuário começar a usar uma aplicação diferente.

Há uma miríade de maneiras que eles podem ser iniciados e, portanto, são um ponto de entrada para aplicações. A maneira padrão que um serviço pode ser iniciado como um ponto de entrada para uma aplicação é através de Intents.

Quando o método startService é chamado para iniciar um Serviço, o método onStart no Serviço é executado. Ele funcionará indefinidamente até que o método stopService seja chamado. Se o serviço é necessário apenas enquanto o cliente está conectado, o cliente deve "vincular-se" a ele usando o método bindService.

Para um serviço vinculado (veja a seção anterior), os dados serão passados para o método onBind.

Por exemplo, um serviço pode tocar música em segundo plano enquanto o usuário está em uma aplicação diferente, ou pode buscar dados pela rede sem bloquear a interação do usuário com uma atividade.

Um serviço pode ser exportado, o que permite que outros processos no dispositivo iniciem o serviço. Por padrão, serviços não são exportados, mas isso pode ser configurado no Manifest:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receivers

Broadcasts podem ser vistos como um sistema de mensagens e broadcast receivers são os ouvintes. Se uma aplicação registrou um receiver para um broadcast específico, o código desse receiver é executado quando o sistema envia o broadcast. Note que, neste caso, várias apps podem receber a mesma mensagem.

Existem 2 maneiras que uma app pode registrar um receiver: no Manifest da app ou registrado dinamicamente no código da app usando a chamada de API registerReceiver. No manifest, você pode limitar os broadcasts que aceita através do uso de permissões dentro do elemento receiver. Quando definido dinamicamente, você pode passar a permissão para o método registerReceiver.

Em ambos os casos, para registrar o receiver, os filtros de intent para o receiver são definidos. Esses filtros de intent são os broadcasts que devem acionar o receiver.

Quando os broadcasts específicos para os quais o receiver está registrado são enviados, onReceive na classe BroadcastReceiver é executado.

Uma aplicação pode registrar um receiver para a mensagem de bateria baixa, por exemplo, e mudar seu comportamento com base nessa informação.

Broadcasts podem ser assíncronos (todos os receivers recebem) ou síncronos (o broadcast é recebido de maneira ordenada com base na prioridade definida para recebê-lo).

{% hint style="danger" %} Note que qualquer aplicação pode se definir como prioridade máxima para receber um Broadcast. {% endhint %}

Para examinar o código implementado em um Broadcast Receiver, você precisa procurar pelo método onReceive da classe do receiver.
Note que Broadcasts Ordenados podem descartar o Intent recebido ou até modificá-lo usando um dos métodos setter. Portanto, os receivers devem validar os dados.

Content Provider

Content Providers são a maneira de apps compartilharem dados estruturados, como bancos de dados relacionais. Portanto, é muito importante usar permissões e definir o nível de proteção apropriado para protegê-los.
Content Providers podem usar os atributos readPermission e writePermission para especificar quais permissões uma app deve ter. Essas permissões têm precedência sobre o atributo de permissão.
Além disso, eles também podem permitir exceções temporárias definindo grantUriPermission como verdadeiro e depois configurando os parâmetros apropriados no elemento grant-uri-permission dentro do elemento provider no arquivo de manifesto.

O grant-uri-permission tem três atributos: path, pathPrefix e pathPattern:

  • path: Permite especificar o caminho inteiro a excluir
  • pathPrefix: Permite especificar o início do caminho
  • pathPattern: Permite o uso de curingas e substituições simbólicas para obter um controle mais granular.

É importante validar e higienizar a entrada recebida para evitar vulnerabilidades potenciais como injeção de SQL.

Recursos do Content Provider:

  • O componente Content Provider fornece dados de uma aplicação para outras mediante solicitação.
  • Você pode armazenar os dados no sistema de arquivos, em um banco de dados SQLite, na web ou em qualquer outro local de armazenamento persistente que sua app possa acessar.
  • Através do content provider, outras apps podem consultar ou até modificar os dados (se o content provider permitir).
  • Content Provider é útil em casos em que uma app deseja compartilhar dados com outra app.
  • É muito semelhante a bancos de dados e possui quatro métodos.
  • insert()
  • update()
  • delete()
  • query()

FileProvider

Este é um tipo de Content Provider que irá compartilhar arquivos de uma pasta. Você pode declarar um file provider assim:

<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true" android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>

Observe o atributo android:exported porque se estiver true, aplicativos externos poderão acessar as pastas compartilhadas.
Note que a configuração android:resource="@xml/filepaths" está indicando que o arquivo res/xml/filepaths.xml contém a configuração de quais pastas este FileProvider vai compartilhar. Este é um exemplo de como indicar para compartilhar uma pasta nesse arquivo:

<paths>
<files-path path="images/" name="myimages" />
</paths>
Compartilhar algo como **`path="."`** pode ser **perigoso** mesmo que o provedor não seja exportado se houver outra vulnerabilidade em alguma parte do código que tentou acessar esse provedor.\
Você poderia **acessar** uma **imagem** dentro dessa pasta com `content://com.example.myapp.fileprovider/myimages/default_image.jpg`

O elemento `<paths>` pode ter vários filhos, cada um especificando um diretório diferente para compartilhar. Além do elemento **`<files-path>`**, você pode usar o elemento **`<external-path>`** para compartilhar diretórios no **armazenamento externo**, e o elemento **`<cache-path>`** para compartilhar diretórios no seu **diretório de cache interno**.\
[Para mais informações sobre atributos específicos de provedores de arquivo, acesse aqui.](https://developer.android.com/reference/androidx/core/content/FileProvider)

[Mais informações sobre FileProviders aqui](https://developer.android.com/training/secure-file-sharing/setup-sharing).

## WebViews

WebViews são efetivamente **navegadores web** embutidos em Aplicativos Android.\
O conteúdo de WebViews pode ser obtido de sites remotos ou pode ser arquivos incluídos no aplicativo.\
WebViews são **vulneráveis às mesmas vulnerabilidades que afetam qualquer navegador web**. No entanto, existem algumas **configurações** que podem ser úteis para **limitar** a **superfície de ataque**.

Existem dois tipos de WebViews no Android:

* O **WebViewClient**, mais adequado para renderização simples de HTML. Este não executará a função de alerta JS. Portanto, testes de XSS usando essa função serão inválidos.
* O **WebChrome** **client**, é um navegador Chrome.

Note que **navegadores WebView não têm acesso aos cookies do navegador nativo**.

Para carregar uma URL ou arquivo é possível usar as funções **`loadUrl`**, **`loadData`** ou **`loadDataWithBaseURL`**. **É importante acessar apenas URLs sanitizadas.**\
A segurança do WebView pode ser configurada através do objeto **`WebSettings`**.\
Por exemplo, a execução de código JS pode ser desativada usando o método **`setJavaScriptEnabled`** com o valor **`false`**. Isso irá **remover** a possibilidade de um **XSS** e outras vulnerabilidades relacionadas a JS.

A funcionalidade "Bridge" do JavaScript **injeta objetos Java em um WebView tornando-os acessíveis ao JS**. A partir do Android 4.2, os métodos devem ser anotados com **`@JavascriptInterface`** para serem acessíveis ao JavaScript.

Se **`true`** for passado para **`setAllowContentAccess`**, **WebViews poderão acessar Content Providers** via esquema **`content://`**. Isso obviamente representa um risco de segurança. Note que se esse acesso for concedido, é muito importante **garantir** que a URL **`content://`** seja **segura**.

Por padrão, arquivos locais podem ser acessados por WebViews via URLs file://, mas existem várias maneiras de prevenir esse comportamento:

* Passar **`false`** para **`setAllowFileAccess`**, impede o acesso ao sistema de arquivos com exceção de ativos via `file:///android_asset` _e_ `file:///android_res`. Esses caminhos devem ser usados apenas para dados não sensíveis (como imagens), então isso deve ser seguro.
* O método **`setAllowFileAccess`** indica se um caminho de uma URL `file://` deve ser capaz de acessar o conteúdo de outras URLs de esquema de arquivo.
* O método **`setAllowUniversalAccessFromFileURLs`** indica se um caminho de uma URL `file://` deve ser capaz de acessar conteúdo de qualquer origem.

## Outros Componentes de Aplicativos

### **Assinatura de Aplicativos**

* O Android exige que **todos os aplicativos sejam assinados digitalmente com um certificado** antes de poderem ser instalados. O Android usa esse certificado para identificar o autor de um aplicativo.
* Para executar aplicativos no dispositivo, eles devem ser assinados. Quando um aplicativo é instalado em um dispositivo, o **gerenciador de pacotes verifica** se o aplicativo foi devidamente assinado com o certificado no arquivo apk ou não.
* O aplicativo pode ser autoassinado ou pode ser assinado por uma AC.
* A assinatura de aplicativos garante que um aplicativo não possa acessar outro aplicativo, exceto por meio de IPC bem definido e também que seja passado sem modificações para o dispositivo.

### **Verificação de Aplicativos**

* O Android 4.2 e versões posteriores suportam a verificação de aplicativos. Os usuários podem optar por ativar a "Verificação de Aplicativos" e ter aplicativos avaliados por um verificador de aplicativos antes da instalação.
* A verificação de aplicativos pode alertar o usuário se eles tentarem instalar um aplicativo que possa ser prejudicial; se um aplicativo for especialmente ruim, ele pode bloquear a instalação.

## Gerenciamento de Dispositivos Móveis

MDM ou Gerenciamento de Dispositivos Móveis são conjuntos de software usados para **garantir controle e requisitos de segurança** sobre dispositivos móveis. Esses conjuntos usam os recursos referidos como API de Administração de Dispositivos e requerem que um aplicativo Android seja instalado.

Geralmente, as soluções de MDM realizam funções como impor políticas de senha, forçar a criptografia de armazenamento e habilitar a limpeza remota de dados do dispositivo.

<figure><img src="/.gitbook/assets/image (675).png" alt=""><figcaption></figcaption></figure>

Encontre vulnerabilidades que importam mais para que você possa corrigi-las mais rapidamente. Intruder rastreia sua superfície de ataque, executa varreduras de ameaças proativas, encontra problemas em toda a sua pilha de tecnologia, de APIs a aplicativos web e sistemas em nuvem. [**Experimente gratuitamente**](https://www.intruder.io/?utm\_source=referral\&utm\_campaign=hacktricks) hoje.

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}

***

<details>

<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Outras maneiras de apoiar o HackTricks:

* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas dicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).

</details>