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

37 KiB

Conceitos Básicos de Aplicativos Android

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Encontre vulnerabilidades que são mais importantes 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 de tecnologia, desde APIs até aplicativos da web e sistemas em nuvem. Experimente gratuitamente hoje.

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


Modelo de Segurança do Android

Existem duas camadas:

  • O SO, que mantém os aplicativos instalados isolados uns dos outros.
  • O próprio aplicativo, que permite aos desenvolvedores expor determinadas funcionalidades e configura as capacidades do aplicativo.

Separação de UID

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

Compartilhamento de UID

Dois aplicativos podem ser configurados para usar o mesmo UID. Isso pode ser útil para compartilhar informações, mas se um deles for comprometido, os dados de ambos os aplicativos serão comprometidos. É por isso que esse comportamento é desencorajado.
Para compartilhar o mesmo UID, os aplicativos devem definir o mesmo valor android:sharedUserId em seus manifestos.

Isolamento

O Sandbox de Aplicativos Android permite executar cada aplicativo como um processo separado sob um ID de usuário separado. Cada processo tem sua própria máquina virtual, portanto, 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, em seguida, cria políticas para permitir apenas as interações esperadas entre eles.

Permissões

Quando você instala um aplicativo e ele solicita 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 possui o atributo maxSdkVersion, que impede a solicitação de permissões em versões superiores à especificada.
Observe que os aplicativos Android não precisam solicitar todas as permissões no início, eles também podem solicitar 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 possuem uma permissão especificada.
Um elemento de permissão possui três atributos:

  • O nome da permissão
  • O atributo permission-group, que permite agrupar permissões relacionadas.
  • O nível de proteção 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 precisa aprovar.
  • Perigoso: Indica que a permissão concede ao aplicativo solicitante algum acesso elevado. Os usuários são solicitados a aprová-los.
  • Assinatura: Somente aplicativos assinados pelo mesmo certificado que o que exporta o componente podem receber permissão. Este é o tipo de proteção mais forte.
  • AssinaturaOuSistema: Somente aplicativos assinados pelo mesmo certificado que o que exporta o componente ou aplicativos em execução com acesso de nível do sistema podem receber permissões.

Aplicativos Pré-Instalados

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

  • Os que são enviados com o ROM do AOSP (Android OpenSource Project)
  • Adicionados pelo fabricante do dispositivo
  • Adicionados pelo provedor de telefonia celular (se comprado deles)

Rooting

Para obter acesso root a um dispositivo Android físico, geralmente é necessário explorar 1 ou 2 vulnerabilidades que costumam ser específicas para o dispositivo e versão.
Depois que a exploração funcionar, geralmente o binário su do Linux é copiado para uma localização especificada na variável de ambiente PATH do usuário, como /system/xbin.

Depois que o binário su estiver 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 rooting é muito perigoso e pode danificar gravemente o dispositivo. {% endhint %}

ROMs

É possível substituir o sistema operacional instalando um firmware personalizado. Fazendo isso, é possível estender a utilidade de um dispositivo antigo, contornar restrições de software ou obter acesso ao código mais recente do Android.
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 acesso, ele poderá ter acesso a quase tudo e poderá danificar o telefone.

Fundamentos de Aplicativos Android

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

Revisão dos Fundamentos

  • Os aplicativos 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 unzip 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/
  • O certificado fica aqui!
  • classes.dex
  • Bytecode Dalvik para aplicativo no formato de arquivo DEX. Este é o código Java (ou Kotlin) compilado que o aplicativo executará por padrão.
  • lib/
  • Bibliotecas nativas para o aplicativo, por padrão, ficam aqui! Sob o diretório lib/, existem os diretórios específicos do processador.
  • 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 os autores de malware desejam tentar "ocultar" código adicional, nativo ou Dalvik, não incluindo-o nos locais padrão.
  • res/
  • o diretório que contém recursos não compilados em resources.arsc

Dalvik & Smali

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

Fluxograma do processo do desenvolvedor. Java para bytecode DEX

Fluxograma do processo de engenharia reversa. Bytecode DEX para SMALI para Java descompilado

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, frequentemente usamos o termo "Smali" para se 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 nível superior e o bytecode.

Encontre as vulnerabilidades que mais importam 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 de tecnologia, de APIs a aplicativos da 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 os aplicativos Android se comunicam entre seus componentes ou com outros aplicativos. Esses objetos de mensagem também podem transportar dados entre aplicativos ou componentes, semelhante à forma como as solicitações GET/POST são usadas nas comunicações HTTP.

Portanto, um Intent é basicamente uma mensagem que é passada entre componentes. Intents podem ser direcionados para componentes ou aplicativos específicos, ou podem ser enviados sem um destinatário específico.
Para simplificar, um Intent pode ser usado:

  • Para iniciar uma Activity, abrindo uma interface do usuário para um aplicativo
  • Como transmissões para informar o sistema e os aplicativos sobre alterações
  • Para iniciar, parar e se comunicar com um serviço em segundo plano
  • Para acessar dados por meio de ContentProviders
  • Como callbacks para lidar com eventos

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

Intent-Filter

Um Intent Filter especifica os tipos de Intent que uma atividade, serviço ou Receptor de Transmissão pode responder. Ele especifica o que uma atividade ou serviço pode fazer e quais tipos de transmissões um Receptor pode manipular. Ele permite que o componente correspondente receba Intents do tipo declarado. Os Intent Filters são tipicamente definidos por meio do arquivo AndroidManifest.xml. Para Receptor de Transmissão, 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 atividade/serviço/provedor de conteúdo/receptor de transmissão é público quando o atributo exported é definido como true, mas um componente também é público se o manifesto especificar um Intent filter para ele. No entanto,
os desenvolvedores podem tornar explicitamente os componentes privados (independentemente de quaisquer filtros de intenção)
definindo o atributo exported como false para cada componente no arquivo manifesto.
Os desenvolvedores também podem definir o atributo permission para exigir uma determinada permissão para acessar o componente, restringindo assim o acesso ao componente.

Intenções Implícitas

Intenções são criadas programaticamente usando um construtor de Intenções:

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

A Ação do intent previamente declarado é ACTION_SEND e o Extra é um Uri de mailto (o Extra é a informação extra que o intent está esperando).

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

<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 intenção" 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 o que tiver 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 ocorrer um conflito, uma janela de "escolha" aparece para que o usuário possa decidir.

Intenções Explícitas

Uma intenção explícita especifica o nome da classe que está sendo direcionada:

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

Em outras aplicações, para acessar a intenção previamente declarada, você pode usar:

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

Intenções Pendentes

Essas 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 uma Intenção Pendente, deve-se especificar uma intenção e a ação a ser executada. Se a intenção declarada não for explícita (não declara qual intenção pode chamá-la), um aplicativo malicioso pode executar a ação declarada em nome do aplicativo da vítima. Além disso, se uma ação não for especificada, o aplicativo malicioso poderá fazer qualquer ação em nome da vítima.

Intenções de Transmissão

Ao contrário das intenções anteriores, que são recebidas apenas por um aplicativo, as intenções de transmissão podem ser recebidas por vários aplicativos. No entanto, a partir da versão API 14, é possível especificar o aplicativo que deve receber a mensagem usando Intent.setPackage.

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

Existem dois tipos de transmissões: Normais (assíncronas) e Ordenadas (síncronas). A ordem é baseada na prioridade configurada dentro do receptor. Cada aplicativo pode processar, retransmitir ou descartar a transmissão.

É possível enviar uma transmissão usando a função **sendBroadcast(intent, receiverPermission) ** da classe Context.
Você também pode usar a função sendBroadcast do LocalBroadCastManager para garantir que a mensagem nunca saia do aplicativo. Usando isso, você nem precisa exportar um componente receptor.

Transmissões Persistentes

Esse tipo de transmissão pode ser acessado muito tempo depois de ser enviado.
Essas foram descontinuadas no nível da API 21 e é recomendado não usá-las.
Elas permitem que qualquer aplicativo intercepte os dados, mas também os modifique.

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

Deep links permitem acionar uma Intenção por meio de uma URL. Um aplicativo pode declarar um esquema de URL dentro de uma atividade, para que toda vez que o dispositivo Android tente acessar um endereço usando esse esquema, a atividade do aplicativo seja chamada:

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

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

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

Se você encontrar algo como isso:

Significará que está esperando uma URL que comece com example://gizmos
Nesse caso, você pode tentar abusar da funcionalidade criando uma página da web com as seguintes cargas úteis. Ela 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 aplicativo, vá para a atividade chamada pelo deeplink e procure a função onNewIntent.

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

AIDL - Android Interface Definition Language

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. Portanto, para se comunicarem, eles precisam decompor seus objetos em primitivas que o sistema operacional possa entender e enviar os objetos através dessa fronteira para você. O código para fazer essa transferência é tedioso de escrever, então o Android lida com isso para você com o AIDL.

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

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 a outro componente do aplicativo e não é executado indefinidamente em segundo plano.

Messenger

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

Binder

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

Componentes

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

Atividade de Lançamento e outras atividades

Uma atividade Android é uma tela da interface do usuário do aplicativo Android. Nesse sentido, 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 de lançamento é o que a maioria das pessoas considera como o ponto de entrada para um aplicativo Android. A atividade de lançamento é a atividade que é iniciada quando um usuário clica no ícone de um aplicativo. Você pode determinar a atividade de lançamento olhando o manifesto do aplicativo. A atividade de lançamento terá as seguintes intenções MAIN e LAUNCHER listadas.

Lembre-se de que nem todo aplicativo terá uma atividade de lançamento, especialmente aplicativos sem interface do usuário. Exemplos de aplicativos sem uma interface do usuário (e, portanto, uma atividade de lançamento) são aplicativos pré-instalados que executam 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 atividades podem ser exportadas, permitindo que outros processos no dispositivo iniciem a atividade. Por padrão, elas não são exportadas, mas você pode exportá-las definindo:

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

Observe que a capacidade de burlar as proteções de atividades nem sempre é uma vulnerabilidade, você precisa verificar a qual dados você obteve acesso. Além disso, algumas atividades retornam dados para o chamador. Nesses cenários, você precisa procurar pelo método setResult e verificar os dados que são passados como parâmetro para o Intent. Se forem dados sensíveis, pode haver uma vulnerabilidade de vazamento de informações e ela pode ser explorada por aplicativos capazes de se comunicar com a atividade.

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

Subclasse de Aplicativo

Aplicativos Android podem definir uma subclasse de Application. Os aplicativos podem, mas não precisam, definir uma subclasse personalizada de Application. Se um aplicativo Android define uma subclasse de Application, essa classe é instanciada antes de qualquer outra classe no aplicativo.

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

Serviços

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

Existem várias maneiras de iniciá-los e, portanto, são um ponto de entrada para aplicativos. A maneira padrão de iniciar um serviço como ponto de entrada para um aplicativo é por meio de Intents.

Quando o método startService é chamado para iniciar um Serviço, o método onStart no Serviço é executado. Ele será executado indefinidamente até que o método stopService seja chamado. Se o serviço for necessário apenas enquanto o cliente estiver 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 reproduzir música em segundo plano enquanto o usuário está em um aplicativo diferente, ou pode buscar dados pela rede sem bloquear a interação do usuário com uma atividade.

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

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

Receptores de Transmissão

As transmissões podem ser consideradas um sistema de mensagens e os receptores de transmissão são os ouvintes. Se um aplicativo tiver registrado um receptor para uma transmissão específica, o código desse receptor será executado quando o sistema enviar a transmissão. Note que, nesse caso, vários aplicativos podem receber a mesma mensagem.

Existem 2 maneiras pelas quais um aplicativo pode registrar um receptor: no Manifest do aplicativo ou registrado dinamicamente no código do aplicativo usando a chamada de API registerReceiver. No manifesto, você pode limitar as transmissões que aceita por meio do uso de permissões dentro do elemento receptor. Quando definido dinamicamente, você pode passar a permissão para o método registerReceiver.

Em ambos os casos, para registrar o receptor, são definidos os filtros de intenção para o receptor. Esses filtros de intenção são as transmissões que devem acionar o receptor.

Quando as transmissões específicas para as quais o receptor está registrado são enviadas, o método onReceive na classe BroadcastReceiver é executado.

Um aplicativo pode registrar um receptor para a mensagem de bateria fraca, por exemplo, e alterar seu comportamento com base nessas informações.

As transmissões podem ser assíncronas (todos os receptores as recebem) ou síncronas (a transmissão é recebida de maneira ordenada com base na prioridade definida para recebê-la).

{% hint style="danger" %} Observe que qualquer aplicativo pode se definir como prioridade máxima para receber uma transmissão. {% endhint %}

Para examinar o código implementado em um Receptor de Transmissão, você precisa procurar pelo método onReceive da classe do receptor.
Observe que as Transmissões Ordenadas podem descartar a Intenção recebida ou até mesmo modificá-la usando um dos métodos setter. Portanto, os receptores devem validar os dados.

Provedor de Conteúdo

Os Provedores de Conteúdo são a maneira como os aplicativos compartilham 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.
Os Provedores de Conteúdo podem usar os atributos readPermission e writePermission para especificar quais permissões um aplicativo 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 true e, em seguida, configurando os parâmetros apropriados no elemento grant-uri-permission dentro do elemento provedor no arquivo manifesto.

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

  • path: Permite especificar o caminho inteiro a ser excluído
  • 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 sanitizar a entrada recebida para evitar vulnerabilidades potenciais, como injeção de SQL.

Recursos do Provedor de Conteúdo:

  • O componente Provedor de Conteúdo fornece dados de um aplicativo para outros 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 seu aplicativo possa acessar.
  • Por meio do provedor de conteúdo, outros aplicativos podem consultar ou até mesmo modificar os dados (se o provedor de conteúdo permitir).
  • O Provedor de Conteúdo é útil em casos em que um aplicativo deseja compartilhar dados com outro aplicativo.
  • É muito semelhante a bancos de dados e possui quatro métodos.
  • insert()
  • update()
  • delete()
  • query()

FileProvider

Este é um tipo de Provedor de Conteúdo que irá compartilhar arquivos de uma pasta. Você pode declarar um provedor de arquivos da seguinte forma:

<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, pois se estiver definido como true, aplicativos externos poderão acessar as pastas compartilhadas.
Observe que a configuração android:resource="@xml/filepaths" indica que o arquivo res/xml/filepaths.xml contém a configuração das pastas que esse FileProvider irá compartilhar. Este é um exemplo de como indicar o compartilhamento de 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 tente acessar esse provedor.
Você pode 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 diretório de cache interno.
Para obter mais informações sobre atributos específicos de provedores de arquivos, clique aqui.

Mais informações sobre FileProviders aqui.

WebViews

WebViews são navegadores da web incorporados em aplicativos Android.
O conteúdo dos WebViews pode ser obtido de sites remotos ou pode ser arquivos incluídos no aplicativo.
Os WebViews são vulneráveis às mesmas vulnerabilidades que afetam qualquer navegador da 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 de HTML simples. Isso não executará a função de alerta JS. Portanto, testes de XSS usando essa função serão inválidos.
  • O cliente WebChrome, é um navegador Chrome.

Observe que os 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 por meio 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 removerá a possibilidade de um XSS e outras vulnerabilidades relacionadas ao JS.

A funcionalidade de JavaScript "Bridge" 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, os WebViews poderão acessar Provedores de Conteúdo por meio do esquema content://. Isso obviamente representa um risco de segurança. Observe que, se esse acesso for concedido, é muito importante garantir que a URL content:// seja segura.

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

  • Passar false para setAllowFileAccess, impede o acesso ao sistema de arquivos com exceção dos ativos via file:///android_asset e file:///android_res. Esses caminhos devem ser usados apenas para dados não sensíveis (como imagens), portanto, 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 do aplicativo

Assinatura do aplicativo

  • O Android requer 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 o aplicativo no dispositivo, ele deve ser assinado. Quando o 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 Autoridade de Certificação (CA).
  • A assinatura do aplicativo garante que um aplicativo não possa acessar nenhum outro aplicativo, exceto por meio de IPC bem definido, e também que ele seja transmitido sem modificações para o dispositivo.

Verificação do aplicativo

  • O Android 4.2 e posterior oferecem suporte à verificação do aplicativo. Os usuários podem optar por ativar a opção "Verificar aplicativos" e ter os aplicativos avaliados por um verificador de aplicativos antes da instalação.
  • A verificação do aplicativo pode alertar o usuário se ele tentar 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 Mobile Device Management são suítes de software usadas para garantir controle e requisitos de segurança em dispositivos móveis. Essas suítes usam recursos referidos como API de Administração de Dispositivos e requerem a instalação de um aplicativo Android.

Geralmente, as soluções de MDM executam funções como impor políticas de senha, forçar a criptografia de armazenamento e permitir a exclusão remota de dados do dispositivo.

Encontre as vulnerabilidades que mais importam 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 de tecnologia, de APIs a aplicativos da web e sistemas em nuvem. Experimente gratuitamente hoje mesmo.

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


☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥