hacktricks/mobile-pentesting/ios-pentesting/ios-basics.md

211 lines
22 KiB
Markdown

```markdown
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
# Separação de Privilégios e Sandbox
Aplicações acessíveis pelo usuário rodam como o usuário **mobile** enquanto processos críticos do sistema rodam como **root**.\
No entanto, o sandbox permite um melhor controle sobre ações que processos e aplicações podem executar.
Por exemplo, mesmo que dois processos rodem como o mesmo usuário (mobile), eles **não têm permissão para acessar ou modificar os dados um do outro**.
Cada aplicação é instalada em **`private/var/mobile/Applications/{ID aleatório}`**\
Uma vez instaladas, as aplicações têm acesso limitado de leitura a algumas áreas e funções do sistema (SMS, chamada telefônica...). Se uma aplicação deseja acessar uma **área protegida,** um **pop-up solicitando permissão** aparece.
# Proteção de Dados
Desenvolvedores de aplicativos podem aproveitar as APIs de _Proteção de Dados_ do iOS para implementar **controle de acesso refinado** para dados do usuário armazenados na memória flash. As APIs são construídas em cima do **Secure Enclave Processor** (SEP). O SEP é um coprocessador que fornece **operações criptográficas para proteção de dados e gerenciamento de chaves**. Uma chave de hardware específica do dispositivo - o **device UID** (ID Único) - é **embutida no enclave seguro**, garantindo a integridade da proteção de dados mesmo quando o kernel do sistema operacional está comprometido.
Quando um **arquivo é criado** no disco, uma nova chave **AES de 256 bits é gerada** com a ajuda do gerador de números aleatórios baseado em hardware do enclave seguro. O **conteúdo do arquivo é então criptografado com a chave gerada**. E então, essa **chave é salva criptografada com uma chave de classe** junto com **o ID da classe,** com **ambos os dados criptografados pela chave do sistema,** dentro do **metadado** do arquivo.
![](<../../.gitbook/assets/image (473).png>)
Para descriptografar o arquivo, o **metadado é descriptografado usando a chave do sistema**. Então, **usando o ID da classe** a **chave de classe é recuperada** **para descriptografar a chave do arquivo e descriptografar o arquivo.**
Arquivos podem ser atribuídos a uma de **quatro** **diferentes** **classes de proteção**, que são explicadas em mais detalhes no [Guia de Segurança da Plataforma Apple](https://help.apple.com/pdf/security/en_US/apple-platform-security-guide.pdf):
* **Proteção Completa (NSFileProtectionComplete)**: Uma chave derivada do código de acesso do usuário e do device UID protege esta chave de classe. A chave derivada é apagada da memória logo após o dispositivo ser bloqueado, tornando os dados inacessíveis até que o usuário desbloqueie o dispositivo.
* **Protegido a Menos que Aberto (NSFileProtectionCompleteUnlessOpen)**: Esta classe de proteção é semelhante à Proteção Completa, mas, se o arquivo estiver aberto quando desbloqueado, o aplicativo pode continuar acessando o arquivo mesmo se o usuário bloquear o dispositivo. Esta classe de proteção é usada quando, por exemplo, um anexo de e-mail está sendo baixado em segundo plano.
* **Protegido Até a Primeira Autenticação do Usuário (NSFileProtectionCompleteUntilFirstUserAuthentication)**: O arquivo pode ser acessado assim que o usuário desbloquear o dispositivo pela primeira vez após a inicialização. Ele pode ser acessado mesmo se o usuário bloquear o dispositivo subsequentemente e a chave de classe não for removida da memória.
* **Sem Proteção (NSFileProtectionNone)**: A chave para esta classe de proteção é protegida apenas com o UID. A chave de classe é armazenada em "Armazenamento Apagável", que é uma região da memória flash no dispositivo iOS que permite o armazenamento de pequenas quantidades de dados. Esta classe de proteção existe para apagamento remoto rápido (deleção imediata da chave de classe, o que torna os dados inacessíveis).
Todas as chaves de classe, exceto `NSFileProtectionNone`, são criptografadas com uma chave derivada do device UID e do código de acesso do usuário. Como resultado, a descriptografia só pode ocorrer no próprio dispositivo e requer o código de acesso correto.
Desde o iOS 7, a classe de proteção de dados padrão é "Protegido Até a Primeira Autenticação do Usuário".
[**FileDP**](https://github.com/abjurato/FileDp-Source) é um programa que você pode carregar e usar dentro do iPhone para **inspecionar a classe de proteção de dados** de cada arquivo.
## O Keychain
O keychain é um **container criptografado** onde cada aplicativo pode **armazenar** pedaços de **informação sensível** e apenas o mesmo aplicativo (ou aplicativos autorizados) pode recuperar o conteúdo.\
O iOS **gera sua própria senha para o keychain** e **armazena** uma versão **criptografada** desta chave no dispositivo. Esta senha é criptografada com AES usando uma chave AES criada por uma função **PBKDF2** do **código de acesso do usuário + sal** (o **UID de 256 bits do dispositivo** **acessível** **apenas** pelo chipset do enclave **seguro** no dispositivo). Devido ao uso deste UID do dispositivo como sal, um dispositivo não será capaz de descriptografar o keychain de um dispositivo diferente mesmo conhecendo o código de acesso dos usuários.
O acesso ao Keychain é gerenciado pelo daemon **`securityd`**, que concede acesso de acordo com os `Keychain-access-groups`, `application-identifier` e `application-group` entitlements do aplicativo.
A [API Keychain](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html) inclui as seguintes operações principais:
* `SecItemAdd`
* `SecItemUpdate`
* `SecItemCopyMatching`
* `SecItemDelete`
As únicas maneiras de tentar força bruta (BF) nesta senha é despejando a chave criptografada e BF o código de acesso + sal (a função **pbkdf2** usa **pelo menos 10000 iterações**). Ou tentando **BF dentro do dispositivo** para evitar BFing o sal, no entanto, o enclave seguro garante que haja pelo menos um **atraso de 5s entre 2 tentativas de senha falhadas**.
Você pode configurar **proteção de dados para itens do Keychain** definindo a chave `kSecAttrAccessible` na chamada para `SecItemAdd` ou `SecItemUpdate`. Os seguintes valores de acessibilidade configuráveis para kSecAttrAccessible são as classes de Proteção de Dados do Keychain:
* **`kSecAttrAccessibleAlways`**: Os dados no item do Keychain podem **sempre ser acessados**, independentemente de o dispositivo estar bloqueado.
* **`kSecAttrAccessibleAlwaysThisDeviceOnly`**: Os dados no item do Keychain podem **sempre** **ser** **acessados**, independentemente de o dispositivo estar bloqueado. Os dados **não serão incluídos em um backup do iCloud** ou local.
* **`kSecAttrAccessibleAfterFirstUnlock`**: Os dados no item do Keychain não podem ser acessados após uma reinicialização até que o **dispositivo tenha sido desbloqueado uma vez** pelo usuário.
* **`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`**: Os dados no item do Keychain não podem ser acessados após uma reinicialização até que o **dispositivo tenha sido desbloqueado uma vez** pelo usuário. Itens com este atributo **não migram para um novo dispositivo**. Assim, após restaurar de um backup de um dispositivo diferente, esses itens não estarão presentes.
* **`kSecAttrAccessibleWhenUnlocked`**: Os dados no item do Keychain podem ser acessados **apenas enquanto o dispositivo está desbloqueado** pelo usuário.
* **`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`**: Os dados no item do Keychain podem ser acessados **apenas enquanto o dispositivo está desbloqueado** pelo usuário. Os dados **não serão incluídos em um backup do iCloud ou local**.
* **`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`**: Os dados no Keychain podem ser acessados **apenas quando o dispositivo está desbloqueado**. Esta classe de proteção **está disponível apenas se um código de acesso estiver configurado** no dispositivo. Os dados **não serão incluídos em um backup do iCloud ou local**.
**`AccessControlFlags`** definem os mecanismos com os quais os usuários podem autenticar a chave (`SecAccessControlCreateFlags`):
* **`kSecAccessControlDevicePasscode`**: Acessar o item via um código de acesso.
* **`kSecAccessControlBiometryAny`**: Acessar o item via uma das impressões digitais registradas no Touch ID. Adicionar ou remover uma impressão digital não invalidará o item.
* **`kSecAccessControlBiometryCurrentSet`**: Acessar o item via uma das impressões digitais registradas no Touch ID. Adicionar ou remover uma impressão digital _irá_ invalidar o item.
* **`kSecAccessControlUserPresence`**: Acessar o item via uma das impressões digitais registradas (usando Touch ID) ou recorrer ao código de acesso.
Observe que as chaves protegidas pelo Touch ID (via `kSecAccessControlBiometryAny` ou `kSecAccessControlBiometryCurrentSet`) são protegidas pelo Secure Enclave: O Keychain mantém apenas um token, não a chave real. A chave reside no Secure Enclave.
O iPhone usa o **código de acesso introduzido pelo usuário ao desbloquear o dispositivo para descriptografar os segredos no keychain**.
O iOS usa o _**AppIdentifierPrefix**_ (ID da Equipe) e o _**BundleIdentifier**_ (fornecido pelo desenvolvedor) para impor **controle de acesso sobre itens do keychain**. Então, a mesma equipe **pode** **configurar** **2 aplicativos para compartilhar itens do keychain**.
Quando um processo de backup é iniciado, os **dados do keychain que são salvos permanecem criptografados e a senha do keychain não está incluída no backup**.
{% hint style="warning" %}
**Em um dispositivo com jailbreak, o keychain não está protegido.**
{% endhint %}
### **Persistência de Dados do Keychain**
No iOS, quando um aplicativo é desinstalado, os dados do Keychain usados pelo aplicativo são retidos pelo dispositivo, ao contrário dos dados armazenados pelo sandbox do aplicativo, que são apagados. No caso de um **usuário vender seu dispositivo sem realizar uma redefinição de fábrica, o comprador do dispositivo pode ser capaz de acessar as contas de aplicativos e dados do usuário anterior reinstalando** os mesmos aplicativos usados pelo usuário anterior. Isso não requereria habilidade técnica para ser realizado.
Não há uma API do iOS que os desenvolvedores possam usar para forçar a limpeza de dados quando um aplicativo é desinstalado. Em vez disso, os desenvolvedores devem tomar as seguintes medidas para evitar que os dados do Keychain persistam entre instalações de aplicativos:
* Quando um aplicativo é lançado pela primeira vez após a instalação, limpe todos os dados do Keychain associados ao aplicativo. Isso impedirá que o segundo usuário do dispositivo ganhe acesso acidental às contas do usuário anterior. O seguinte exemplo em Swift é uma demonstração básica deste procedimento de limpeza:
```
```objectivec
let userDefaults = UserDefaults.standard
if userDefaults.bool(forKey: "hasRunBefore") == false {
// Remove Keychain items here
// Update the flag indicator
userDefaults.set(true, forKey: "hasRunBefore")
userDefaults.synchronize() // Forces the app to update UserDefaults
}
```
* Ao desenvolver a funcionalidade de logout para uma aplicação iOS, certifique-se de que os dados do Keychain são apagados como parte do logout da conta. Isso permitirá que os usuários limpem suas contas antes de desinstalar uma aplicação.
# **Capacidades da Aplicação**
**Cada aplicação tem um diretório caseiro único e é isolada (sandboxed)**, de modo que não podem acessar recursos protegidos do sistema ou arquivos armazenados pelo sistema ou por outras aplicações. Essas restrições são implementadas através de políticas de sandbox (também conhecidas como _profiles_), que são aplicadas pelo [Trusted BSD (MAC) Mandatory Access Control Framework](http://www.trustedbsd.org/mac.html) através de uma extensão do kernel.
Algumas [**capacidades/permissões**](https://help.apple.com/developer-account/#/dev21218dfd6) podem ser configuradas pelos desenvolvedores da aplicação (por exemplo, Proteção de Dados ou Compartilhamento de Keychain) e terão efeito direto após a instalação. No entanto, para outras, **o usuário será explicitamente solicitado na primeira vez que a aplicação tentar acessar um recurso protegido**.
[_Purpose strings_](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy/accessing_protected_resources?language=objc#3037322) ou _strings de descrição de uso_ são textos personalizados que são oferecidos aos usuários no alerta de solicitação de permissão do sistema ao pedir permissão para acessar dados ou recursos protegidos.
![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQw8W2q7BB5-il7r%2Fpermission_request_alert.png?alt=media)
Se tiver o código-fonte original, você pode verificar as permissões incluídas no arquivo `Info.plist`:
* Abra o projeto com o Xcode.
* Encontre e abra o arquivo `Info.plist` no editor padrão e procure pelas chaves que começam com `"Privacy -"`.
Você pode mudar a visualização para exibir os valores brutos clicando com o botão direito e selecionando "Show Raw Keys/Values" (desta forma, por exemplo, `"Privacy - Location When In Use Usage Description"` se transformará em `NSLocationWhenInUseUsageDescription`).
Se tiver apenas o IPA:
* Descompacte o IPA.
* O `Info.plist` está localizado em `Payload/<appname>.app/Info.plist`.
* Converta-o se necessário (por exemplo, `plutil -convert xml1 Info.plist`) conforme explicado no capítulo "iOS Basic Security Testing", seção "The Info.plist File".
* Inspecione todas as _chaves de strings de propósito no Info.plist_, geralmente terminando com `UsageDescription`:
```markup
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Sua localização é usada para fornecer direções passo a passo até seu destino.</string>
```
## Capacidades do Dispositivo
As capacidades do dispositivo são usadas pela App Store para garantir que apenas dispositivos compatíveis sejam listados e, portanto, tenham permissão para baixar a aplicação. Elas são especificadas no arquivo `Info.plist` da aplicação sob a chave [`UIRequiredDeviceCapabilities`](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/plist/info/UIRequiredDeviceCapabilities).
```markup
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
```
> Normalmente, você encontrará a capacidade `armv7`, o que significa que o aplicativo é compilado apenas para o conjunto de instruções armv7, ou se é um aplicativo universal de 32/64 bits.
Por exemplo, um aplicativo pode depender completamente do NFC para funcionar (por exemplo, um aplicativo ["NFC Tag Reader"](https://itunes.apple.com/us/app/nfc-taginfo-by-nxp/id1246143596)). De acordo com o [arquivo de referência de compatibilidade de dispositivos iOS](https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html), o NFC está disponível apenas a partir do iPhone 7 (e iOS 11). Um desenvolvedor pode querer excluir todos os dispositivos incompatíveis definindo a capacidade do dispositivo `nfc`.
## Entitlements
> Entitlements são pares de chave-valor que são assinados em um aplicativo e permitem autenticação além de fatores de tempo de execução, como o ID de usuário UNIX. Como os entitlements são assinados digitalmente, eles não podem ser alterados. Entitlements são usados extensivamente por aplicativos do sistema e daemons para **realizar operações privilegiadas específicas que, de outra forma, exigiriam que o processo fosse executado como root**. Isso reduz muito o potencial de escalonamento de privilégios por um aplicativo do sistema ou daemon comprometido.
Por exemplo, se você quiser definir a capacidade "Proteção de Dados Padrão", você precisaria ir até a aba **Capabilities** no Xcode e habilitar **Data Protection**. Isso é escrito diretamente pelo Xcode no arquivo `<appname>.entitlements` como o entitlement `com.apple.developer.default-data-protection` com o valor padrão `NSFileProtectionComplete`. No IPA, podemos encontrar isso no `embedded.mobileprovision` como:
```markup
<key>Entitlements</key>
<dict>
...
<key>com.apple.developer.default-data-protection</key>
<string>NSFileProtectionComplete</string>
</dict>
```
Para outras capacidades, como HealthKit, o usuário deve ser solicitado a dar permissão, portanto, não é suficiente adicionar os direitos, chaves especiais e strings devem ser adicionadas ao arquivo `Info.plist` do aplicativo.
# Fundamentos de Objective-C e Swift
**Objective-C** possui um **runtime dinâmico**, então quando um programa Objective-C é executado no iOS, ele chama bibliotecas cujos **endereços são resolvidos em tempo de execução** comparando o nome da função enviada na mensagem contra uma lista de todos os nomes de funções disponíveis.
No início, apenas aplicativos criados pela Apple rodavam nos iPhones, então eles tinham **acesso a tudo** já que eram **confiáveis**. No entanto, quando a Apple **permitiu** **aplicativos de terceiros,** a Apple simplesmente removeu os arquivos de cabeçalho das funções poderosas para "escondê-las" dos desenvolvedores. No entanto, os desenvolvedores descobriram que funções "seguras" precisavam de algumas dessas funções não documentadas e apenas criando um **arquivo de cabeçalho personalizado com os nomes das funções não documentadas, era possível invocar essas poderosas funções ocultas.** De fato, a Apple, antes de permitir a publicação de um aplicativo, verifica se o aplicativo chama alguma dessas funções proibidas.
Então, apareceu o Swift. Como **Swift é estaticamente vinculado** (não resolve o endereço das funções em tempo de execução como Objective-C), é mais fácil verificar as chamadas que um programa Swift vai fazer através de análise estática de código.
# Gerenciamento de Dispositivos
A partir da versão 6 do iOS, existe **suporte integrado para capacidade de gerenciamento de dispositivos** com controles de granulação fina que permitem a uma organização controlar os dispositivos apple corporativos.\
O registro pode ser **iniciado pelo usuário instalando um agente** para acessar os aplicativos corporativos. Neste caso, o dispositivo geralmente pertence ao usuário.\
Ou a **empresa pode indicar os números de série** dos dispositivos comprados ou o ID do pedido de compra e especificar o perfil MDM para instalar nesses dispositivos. Note que a Apple **não permite registrar um dispositivo particular desta forma duas vezes**. Uma vez que o primeiro perfil é deletado, o usuário precisa dar consentimento para instalar outro.
O usuário pode ver as políticas instaladas em _**Configurações**_ --> _**Geral**_ --> _**Gerenciamento de Dispositivos e Perfis**_
Como essas políticas MDM estão verificando e limitando outros aplicativos, elas estão **rodando com mais privilégios**.\
Uma política MDM pode **exigir** que os **usuários** tenham um **código de acesso** definido com uma **complexidade mínima** de senha.\
Os perfis são vinculados ao deviceID, **assinados** e **criptografados** pelo servidor MDM e são **à prova de adulteração**. Eles **não podem** ser **removidos** sem **perder** todos os **dados corporativos**.\
Perfis MDM permitem **apagar** todos os **dados** se houver X **tentativas falhas** de senha. Além disso, o **administrador** pode **apagar remotamente** o iPhone a qualquer momento via interface MDM.
Agentes MDM também **verificam** possíveis **jailbreaks do dispositivo**, pois isso é um estado muito perigoso para um iPhone.
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras maneiras de apoiar o HackTricks:
* Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas dicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>