35 KiB
Conceitos Básicos de Aplicações Android
Aprenda a hackear a AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-me no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para HackTricks e HackTricks Cloud github repos.
Encontre 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 tecnológica, 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" %}
Modelo de Segurança Android
Existem duas camadas:
- O SO, que mantém aplicativos instalados isolados uns dos outros.
- O próprio aplicativo, que permite aos desenvolvedores expor certas funcionalidades e configurar as capacidades do aplicativo.
Separação de UID
Cada aplicativo é atribuído a um ID de Usuário específico. Isso é feito durante a instalação do aplicativo para que o aplicativo só possa interagir 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, esse comportamento é desencorajado.
Para compartilhar o mesmo UID, os aplicativos devem definir o mesmo valor android:sharedUserId
em seus manifestos.
Isolamento
A 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, 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 negou todas as interações de processos e então criou 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á pedindo 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 de nome. 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 tem 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 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 em execução com acesso de nível de 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 enviados com o ROM do AOSP (Projeto de Código Aberto Android)
- 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 o exploit 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ível 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 obter acesso ao 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 carregadores de inicialização de maneira bem documentada e segura.
Implicações
Depois 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
- O formato de aplicativos Android é referido como formato de arquivo APK. É essencialmente um arquivo ZIP (renomeando a extensão do arquivo para .zip, os conteúdos podem ser extraídos e visualizados).
- Conteúdo do APK (não exaustivo)
- AndroidManifest.xml
- resources.arsc/strings.xml
- resources.arsc: contém recursos pré-compilados, como XML binário.
- res/xml/files_paths.xml
- META-INF/
- Aqui é onde o Certificado está localizado!
- classes.dex
- Contém bytecode Dalvik, representando o código Java (ou Kotlin) compilado que o aplicativo executa por padrão.
- lib/
- Armazena bibliotecas nativas, segregadas por arquitetura de CPU em subdiretórios.
armeabi
: código para processadores baseados em ARMarmeabi-v7a
: código para processadores baseados em ARMv7 e superioresx86
: código para processadores X86mips
: código apenas para processadores MIPS- assets/
- Armazena arquivos diversos necessários pelo aplicativo, potencialmente incluindo bibliotecas nativas adicionais ou arquivos DEX, às vezes usados por autores de malware para ocultar código adicional.
- res/
- Contém recursos que não são compilados em resources.arsc
Dalvik & Smali
- A maioria dos aplicativos Android é desenvolvida em Java ou Kotlin (intercambiáveis neste contexto quando referidos como "Java").
- Em vez de executar código Java na Máquina Virtual Java (JVM) como aplicativos de desktop, o Android compila o Java em Bytecode Executável Dalvik (DEX).
- A tradução do bytecode historicamente era tratada pela máquina virtual Dalvik, enquanto versões mais recentes do Android usam o Android Runtime (ART).
- O processo de engenharia reversa envolve a descompilação do bytecode DEX de volta para um formato legível por humanos.
Smali é a forma legível por humanos do bytecode Dalvik. Embora "Smali" e "baksmali" tecnicamente se refiram às ferramentas de montagem e desmontagem, no contexto do Android, "Smali" muitas vezes denota as instruções em si. SMALI é semelhante à linguagem de montagem, servindo como intermediário entre o código-fonte e o bytecode.
Encontre 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 tecnológica, de APIs a aplicativos da web e sistemas em nuvem. Experimente gratuitamente hoje.
Intenções
As intenções 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 ao uso de solicitações GET/POST em comunicações HTTP.
Portanto, uma Intenção é basicamente uma mensagem que é passada entre componentes. As intenções podem ser direcionadas para componentes ou aplicativos específicos, ou podem ser enviadas sem um destinatário específico.
Para ser simples, a Intenção pode ser usada para:
- Iniciar uma Activity, normalmente abrindo uma interface de usuário para um aplicativo
- Como transmissões para informar o sistema e aplicativos sobre alterações
- 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, chamadas de funções restritas e manipulação do fluxo do programa.
Filtro de Intenção
Um Filtro de Intenção especifica os tipos de Intenção aos quais uma atividade, serviço ou Receptor de Transmissão pode responder. Ele especifica o que uma atividade ou serviço pode fazer e que tipos de transmissões um Receptor pode manipular. Ele permite que o componente correspondente receba Intenções do tipo declarado. Os Filtros de Intenção são tipicamente definidos via arquivo AndroidManifest.xml. Para Receptor de Transmissão, também é possível defini-los em código. Um Filtro de Intenção é definido por suas categorias, ações 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 exported
é definido como true
, mas um componente também é público se o manifesto especificar um Filtro de Intenção para ele. No entanto,
os desenvolvedores podem tornar os componentes explicitamente privados (independentemente de quaisquer filtros de intenção)
definindo o atributo ** exported
como false
** para cada componente no arquivo de 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
As 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 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 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 o com maior prioridade será selecionado. Essa prioridade pode ser definida entre -1000 e 1000 e os aplicativos podem usar o valor SYSTEM_HIGH_PRIORITY
. Se surgir 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á direcionando:
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);
Intenções Pendentes
Estas permitem que outras aplicações realizem ações em nome da sua aplicação, utilizando a identidade e permissões da sua aplicação. Ao construir uma Intenção Pendente, deve ser especificada uma intenção e a ação a ser realizada. Se a intenção declarada não for Explícita (não declara qual intenção pode chamá-la), uma aplicação maliciosa poderá realizar a ação declarada em nome da aplicação da vítima. Além disso, se uma ação não for especificada, a aplicação maliciosa poderá realizar 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 uma aplicação, as intenções de transmissão podem ser recebidas por várias aplicações. No entanto, a partir da versão da API 14, é possível especificar a aplicação que deve receber a mensagem usando Intent.setPackage.
Alternativamente, também é possível especificar uma permissão ao enviar a transmissão. A aplicação receptora 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 elemento receptor. Cada aplicação pode processar, retransmitir ou descartar a Transmissão.
É possível enviar uma transmissão usando a função **sendBroadcast(intent, receiverPermission)
** da classe Context
.
Também é possível usar a função sendBroadcast
do LocalBroadCastManager
para garantir que a mensagem nunca saia da aplicação. Usando isso, nem será necessário exportar um componente receptor.
Transmissões Persistentes
Este tipo de Transmissões pode ser acessado muito tempo após serem enviadas.
Foram descontinuadas no nível da API 21 e é recomendado não utilizá-las.
Elas permitem que qualquer aplicação espie os dados, mas também os modifique.
Se encontrar funções contendo a palavra "persistentes" como sendStickyBroadcast
ou sendStickyBroadcastAsUser
, verifique o impacto e tente removê-las.
Links Profundos / Esquemas de URL
Links profundos permitem acionar uma Intenção via URL. Uma aplicação 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 da aplicação será chamada:
Neste caso, o esquema é myapp://
(observe também a categoria BROWSABLE
)
Se dentro do intent-filter
encontrar algo como isto:
Então, está esperando algo como http://www.example.com/gizmos
Se encontrar algo como isto:
Significará que está esperando um URL iniciando por example://gizmos
Neste caso, poderia tentar abusar da funcionalidade criando um site 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 aplicativo, vá para a atividade chamada pelo deeplink e procure a função onNewIntent
.
Saiba 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 definir a interface de programação com a qual o cliente e o serviço concordam para comunicar 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 comunicar, eles precisam decompor seus objetos em primitivas que o sistema operacional pode 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 o trata para você com o AIDL.
Os serviços que usam o AIDL são chamados de Serviços Vinculados. Na classe do Serviço, você encontrará o método onBind
. Este é 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 vive apenas enquanto serve a outro componente de aplicativo e não é executado em segundo plano indefinidamente.
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 por este método e você deve procurar pela 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 a de outro (https://www.youtube.com/watch?v=O-UHvFjxwZ8).
Componentes
Estes 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. 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 de lançamento é o que a maioria das pessoas pensa 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 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 interface do usuário (e, portanto, sem 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"/>
Note 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 um chamador. Nestes cenários, você precisa procurar pelo método setResult
e verificar os dados que são passados para o parâmetro Intent. Se forem dados sensíveis, você pode ter 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
Os 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, esta classe é instanciada antes de qualquer outra classe no aplicativo.
Se o método attachBaseContext
for definido na subclasse de Application, ele é chamado primeiro, antes do método onCreate
.
Serviços
Serviços rodam 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 é através 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 só for necessário 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, o que permite 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 nesse receptor é executado quando o sistema envia 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, os filtros de intenção para o receptor são definidos. 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 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 nessa informação.
A transmissão pode ser assíncrona (cada receptor a recebe) ou síncrona (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 o Intent recebido ou até mesmo modificá-lo 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 configurando o grantUriPermission
como true e, em seguida, configurando os parâmetros apropriados no elemento grant-uri-permission
dentro do elemento do provedor no arquivo de 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 sob demanda.
- Você pode armazenar os dados no sistema de arquivos, em um banco de dados SQLite, na web ou em qualquer outra localização de armazenamento persistente que seu aplicativo possa acessar.
- Através 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 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 for true
aplicativos externos poderão acessar as pastas compartilhadas.
Observe 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 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ê 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 arquivos, acesse aqui.
Mais informações sobre FileProviders aqui.
WebViews
WebViews são efetivamente navegadores da web incorporados em aplicativos Android.
O conteúdo dos WebViews pode ser obtido de sites remotos ou de 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 via 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 via URLs file://, mas existem várias maneiras de evitar esse comportamento:
- Passar
false
parasetAllowFileAccess
, impede o acesso ao sistema de arquivos com exceção de ativos viafile:///android_asset
efile:///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 URLfile://
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 URLfile://
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 digitalmente assinados com um certificado antes de poderem ser instalados. O Android usa este 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 assinado por uma AC.
- A assinatura do aplicativo garante que um aplicativo não pode acessar nenhum outro aplicativo, exceto por meio de IPC bem definido e também que ele é passado sem modificações para o dispositivo.
Verificação do Aplicativo
- O Android 4.2 e posterior suportam a verificação do aplicativo. Os usuários podem optar por ativar "Verificar apps" 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 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 requisitos de controle e segurança sobre dispositivos móveis. Esses conjuntos usam os recursos referidos como API de Administração de Dispositivos e exigem a instalação de um aplicativo Android.
Geralmente, as soluções de MDM realizam funções como impor políticas de senha, forçar a criptografia do armazenamento e permitir a limpeza remota dos dados do dispositivo.
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, 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" %}
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra The PEASS Family, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o HackTricks e HackTricks Cloud github repos.