# iOS 웹뷰
htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요! HackTricks를 지원하는 다른 방법: * **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요! * [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요. * [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다. * 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**를** **팔로우**하세요. * **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
이 페이지의 코드는 [여기](https://github.com/chame1eon/owasp-mstg/blob/master/Document/0x06h-Testing-Platform-Interaction.md)에서 추출되었습니다. 자세한 내용은 해당 페이지를 확인하세요. ## 웹뷰 유형 웹뷰는 애플리케이션 내에서 웹 콘텐츠를 대화식으로 표시하는 데 사용됩니다. iOS 애플리케이션에는 다양한 유형의 웹뷰가 있으며 다른 기능과 보안 기능을 제공합니다. 간단한 개요는 다음과 같습니다: - **UIWebView**는 iOS 12 이후에 권장되지 않으며 **JavaScript**를 비활성화할 수 없어 스크립트 주입 및 **Cross-Site Scripting (XSS)** 공격에 취약합니다. - **WKWebView**는 앱에 웹 콘텐츠를 통합하는 우선적인 옵션으로, 콘텐츠와 보안 기능에 대한 향상된 제어를 제공합니다. **JavaScript**는 기본적으로 활성화되어 있지만 필요한 경우 비활성화할 수 있습니다. 또한 자바스크립트가 자동으로 창을 열지 않도록하는 기능을 지원하며 모든 콘텐츠가 안전하게 로드되도록 보장합니다. 또한 **WKWebView**의 아키텍처는 주요 앱 프로세스에 영향을 미치는 메모리 손상 위험을 최소화합니다. - **SFSafariViewController**는 앱 내에서 표준화된 웹 브라우징 경험을 제공하며, 읽기 전용 주소 필드, 공유 및 탐색 버튼, Safari에서 콘텐츠를 열기 위한 직접 링크를 포함한 특정 레이아웃으로 인식됩니다. **WKWebView**와 달리 **SFSafariViewController**에서는 **JavaScript**를 비활성화할 수 없으며, 앱과 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]; ``` ## 웹뷰 구성 탐색 요약 ### **정적 분석 개요** **웹뷰** 구성을 조사하는 과정에서 두 가지 주요 유형인 **UIWebView**와 **WKWebView**에 초점을 맞추고 있습니다. 바이너리 내에서 이러한 웹뷰를 식별하기 위해 특정 클래스 참조와 초기화 메서드를 검색하는 명령을 사용합니다. - **UIWebView 식별** ```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" ``` #### **Only Secure Content Verification (보안 콘텐츠 확인)** **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 ``` **주요 결과**: - WebView의 인스턴스를 성공적으로 찾고 검사합니다. - JavaScript 활성화 및 안전한 콘텐츠 설정을 확인합니다. 이 요약은 WebView 구성을 정적 및 동적 접근 방식을 통해 분석하는 데 관련된 중요한 단계와 명령을 요약한 것으로, JavaScript 활성화 및 혼합 콘텐츠 감지와 같은 보안 기능에 초점을 맞추고 있습니다. ## WebView 프로토콜 처리 WebView에서 콘텐츠를 처리하는 것은 특히 `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:` 메서드는 WebView에 특정 URL이나 디렉토리를 로드할 수 있으며, 디렉토리가 지정된 경우 민감한 데이터가 노출될 수 있습니다. 이러한 메서드를 소스 코드나 컴파일된 이진 파일에서 찾으려면 다음과 같은 명령을 사용할 수 있습니다: ```bash $ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString" 231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL: ``` **파일 액세스**에 관해서, UIWebView는 일반적으로 허용하지만, WKWebView는 기본적으로 `allowFileAccessFromFileURLs`와 `allowUniversalAccessFromFileURLs` 설정을 도입하여 파일 URL로부터의 액세스를 관리합니다. 두 설정 모두 기본적으로 false로 설정되어 있습니다. 보안 설정을 위해 **WKWebView** 구성을 검사하는 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!'); } }); ``` 마지막으로, 로컬 파일을 유출하기 위한 JavaScript 페이로드의 예는 잘못 구성된 WebView와 관련된 잠재적인 보안 위험을 보여줍니다. 이 페이로드는 파일 내용을 16진수 형식으로 인코딩한 후 서버로 전송합니다. 이는 WebView 구현에서 엄격한 보안 조치의 중요성을 강조합니다. ```javascript String.prototype.hexEncode = function(){ var hex, i; var result = ""; for (i=0; i ``` 네이티브 측면에서는 `JavaScriptBridgeMessageHandler` 클래스에서 JavaScript 호출을 처리합니다. 여기서 숫자를 곱하는 등의 작업 결과가 처리되고 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 웹뷰 내에서 웹 콘텐츠를 효과적으로 디버깅하기 위해서는 `console.log()`로 보낸 메시지가 Xcode 로그에 표시되지 않기 때문에 Safari의 개발자 도구를 사용하는 특정 설정이 필요합니다. 다음은 주요 단계와 요구 사항을 강조한 간소화된 가이드입니다. - **iOS 기기에서의 준비**: iOS 기기에서 Safari 웹 인스펙터를 활성화해야 합니다. 이를 위해 **설정 > Safari > 고급**으로 이동하여 _웹 인스펙터_를 활성화합니다. - **macOS 기기에서의 준비**: macOS 개발 기기에서 Safari 내에서 개발자 도구를 활성화해야 합니다. Safari를 실행하고 **Safari > 기본 설정 > 고급**에 액세스하여 _개발자 메뉴 표시_ 옵션을 선택합니다. - **연결 및 디버깅**: iOS 기기를 macOS 컴퓨터에 연결하고 애플리케이션을 실행한 후, macOS 기기의 Safari를 사용하여 디버깅하려는 웹뷰를 선택합니다. Safari의 메뉴 바에서 _개발_로 이동하고, iOS 기기의 이름 위로 마우스를 올려 웹뷰 인스턴스 목록을 확인한 후, 검사하려는 인스턴스를 선택합니다. 이를 위해 새로운 Safari 웹 인스펙터 창이 열립니다. 그러나 제한 사항을 염두에 두세요: - 이 방법으로 디버깅하려면 macOS 기기가 필요하며, Safari에 의존합니다. - Xcode를 통해 기기에 로드된 애플리케이션의 웹뷰만 디버깅할 수 있습니다. 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)
htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요! HackTricks를 지원하는 다른 방법: * **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요! * [**공식 PEASS & HackTricks 상품**](https://peass.creator-spring.com)을 구매하세요. * [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다. * 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f)이나 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)을 **팔로우**하세요. * **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.