ai.mainfunc.genspark

0
0
0
public

Arbitrary File Write in ai.mainfunc.genspark (Dirty Stream)

Package ai.mainfunc.genspark
Version Tested 2.8.4 (versionCode 28401)
Developer Genspark / iAI Lab
Play Store https://play.google.com/store/apps/details?id=ai.mainfunc.genspark
CVSS 3.1 7.3 High - AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N

Summary

Genspark’s exported MainActivity accepts ACTION_SEND / ACTION_VIEW intents carrying a content:// URI. The app reads _display_name from the URI and uses it verbatim as the destination filename for the file copy - no sanitization. A zero-permission attacker app supplying a _display_name containing ../ writes arbitrary files into the victim app’s UID-protected internal storage tree.

Vulnerable sink

Lv3/f;->k(Context, Uri, String, String[])String in smali/v3/f.smali:

String name = cursor.getString(cursor.getColumnIndexOrThrow("_display_name"));
File dest = new File(ctx.getCacheDir(), name);          // ← attacker-controlled
FileOutputStream out = new FileOutputStream(dest);
copy(ctx.getContentResolver().openInputStream(src), out);

No getName() extraction, no canonical-path containment check.

Reachability

attacker app → ACTION_SEND (mimeType */*) →
  ai.mainfunc.genspark.MainActivity.onNewIntent →
  Lp7/b; (Flutter PluginRegistry$NewIntentListener) →
  Lp7/b;->b(Uri, …) → Lv3/f;->k(…)

MainActivity exports three */* filters: ACTION_SEND, ACTION_SEND_MULTIPLE, ACTION_VIEW (content/file). No permissions required on the attacker app.

Confirmed capabilities

Anchor: getCacheDir() = /data/data/ai.mainfunc.genspark/cache/. A single ../ segment escapes to the broader internal data tree. Four target subdirectories confirmed writable in one PoC run:

$ adb shell su -c 'find /data/data/ai.mainfunc.genspark -name "POC_*" -type f'
/data/data/ai.mainfunc.genspark/cache/POC_SANITY.txt          (control, no traversal)
/data/data/ai.mainfunc.genspark/code_cache/POC_RING2.bin
/data/data/ai.mainfunc.genspark/shared_prefs/POC_RING2.xml
/data/data/ai.mainfunc.genspark/files/POC_RING2.txt
/data/data/ai.mainfunc.genspark/databases/POC_RING2.db

All five owned by u0_a321 (Genspark’s UID), not the attacker app’s. File contents are the literal _display_name strings used to write them, demonstrating end-to-end attacker control over both filename and bytes.

High-impact targets reachable via shared_prefs/: ai.mainfunc.genspark_preferences.xml, FlutterSharedPreferences.xml, com.facebook.sdk.USER_SETTINGS.xml, appsflyer-data.xml - overwriting these corrupts persisted user state, session data, and SDK auth/identity stores.

Out of scope: external storage writes (the app does not initialize /sdcard/Android/data/ai.mainfunc.genspark/ at all), and deep mkdirs() amplification (the sink does not call mkdirs() before FileOutputStream).

Fix

Replace new File(getCacheDir(), name) with new File(getCacheDir(), new File(name).getName()) to strip path components, or add a canonical-path containment check against getCacheDir() before opening the output stream.

image
v0.3.3[beta]