Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/michalbednarski/resourcepoison
Sicurezza AndroidEscalation di PrivilegiAnalisi delle VulnerabilitàExploitSicurezza MobilePaper e Ricerca
GitHubmichalbednarski/resourcepoison

ResourcePoison

Writeup ed exploit per CVE-2025-22441: escalatione dei privilegi da app installata al processo SystemUI su Android dovuta al passaggio di ApplicationInfo non attendibile a LoadedApk

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
10829630 anni faRevisionato da Kitploit

La correzione per questo problema è apparsa come CVE-2025-22441: bollettino patch follow up

Passare ApplicationInfo in giro

ApplicationInfo è una struttura che definisce varie informazioni sull'app installata, in particolare il percorso del file apk da cui vengono caricati risorse e codice

Di solito viene passato dal sistema alle applicazioni, tuttavia a volte ci sono casi in cui un chiamante non di sistema potrebbe fornirne uno proprio. Ad esempio in passato c'è stata una vulnerabilità nel metodo bindBackupAgent(), dove un attaccante poteva passare come parametro un proprio oggetto ApplicationInfo con valori uid e sourceDir che non venivano verificati rispetto alle app realmente installate nel sistema, perché quel metodo era pensato per essere chiamato internamente da system_server, ma era esposto a adb shell

Questa volta, però, ho esaminato attentamente il campo ApplicationInfo all'interno di RemoteViews

RemoteViews è un oggetto che descrive una vista che può provenire da un altro processo. Questo è soprattutto usato per i widget della schermata home, dove l'app che fornisce il widget costruisce RemoteViews e poi viene "applicato" all'interno del processo della schermata home

Altri punti in cui vengono usati RemoteViews sono le notifiche (applicate dal processo SystemUI) e i dialoghi di autofill (forniti dal servizio di autofill, applicati da system_server)

Il campo RemoteViews.mApplication viene serializzato tramite Parcel e quindi può provenire da processi remoti e ogni volta che RemoteViews vengono applicati viene usato dal seguente metodo (snippet sorgente):```java private Context getContextForResourcesEnsuringCorrectCachedApkPaths(Context context) { if (mApplication != null) { if (context.getUserId() == UserHandle.getUserId(mApplication.uid) && context.getPackageName().equals(mApplication.packageName)) { return context; } try { LoadedApk.checkAndUpdateApkPaths(mApplication); return context.createApplicationContext(mApplication, Context.CONTEXT_RESTRICTED); } catch (NameNotFoundException e) { Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found"); } }

return context;

}

La parte più interessante qui è la chiamata a `LoadedApk.checkAndUpdateApkPaths()`, poiché si tratta di un metodo statico che modificherà alcuni stati globali [(snippet source)](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/app/LoadedApk.java;l=2275-2302;drc=5916ee589c4880e2d8a1a9ad6dc852108e4c44c1)```java
public static void checkAndUpdateApkPaths(ApplicationInfo expectedAppInfo) {
    // Get the LoadedApk from the cache
    ActivityThread activityThread = ActivityThread.currentActivityThread();
    if (activityThread == null) {
        Log.e(TAG, "Cannot find activity thread");
        return;
    }
    checkAndUpdateApkPaths(activityThread, expectedAppInfo, /* cacheWithCode */ true);
    checkAndUpdateApkPaths(activityThread, expectedAppInfo, /* cacheWithCode */ false);
}

private static void checkAndUpdateApkPaths(ActivityThread activityThread,
        ApplicationInfo expectedAppInfo, boolean cacheWithCode) {
    String expectedCodePath = expectedAppInfo.getCodePath();
    LoadedApk loadedApk = activityThread.peekPackageInfo(
            expectedAppInfo.packageName, /* includeCode= */ cacheWithCode);
    // If there is load apk cached, or if the cache is valid, don't do anything.
    if (loadedApk == null || loadedApk.getApplicationInfo() == null
            || loadedApk.getApplicationInfo().getCodePath().equals(expectedCodePath)) {
        return;
    }
    // Duplicate framework logic
    List<String> oldPaths = new ArrayList<>();
    LoadedApk.makePaths(activityThread, expectedAppInfo, oldPaths);

    // Force update the LoadedApk instance, which should update the reference in the cache
    loadedApk.updateApplicationInfo(expectedAppInfo, oldPaths);
}

Parliamo di cosa succede in questi metodi

Prima chiamiamo checkAndUpdateApkPaths con 3 parametri, con cacheWithCode impostato sia su true che su false. L'oggetto LoadedApk può essere costruito in due modalità, con mIncludeCode impostato su true o false, che a livello di SDK corrisponde a un Context con il flag CONTEXT_INCLUDE_CODE impostato o meno

Questo metodo userà prima ActivityThread.peekPackageInfo(), che restituirà l'istanza LoadedApk già memorizzata nella cache, quindi se l'app non ha precedentemente costruito un LoadedApk con packageName e includeCode corrispondenti, peekPackageInfo() restituirà null e checkAndUpdateApkPaths() non farà nulla

Tornando a RemoteViews.getContextForResourcesEnsuringCorrectCachedApkPaths(), abbiamo context.createApplicationContext(mApplication, Context.CONTEXT_RESTRICTED) lì, il flag CONTEXT_INCLUDE_CODE non è stato specificato (lo stesso vale per i contesti passati come argomento a quel metodo) e quindi quel metodo userà sempre LoadedApk con mIncludeCode=false

Pertanto, per RemoteViews l'aggiornamento della versione con il codice non è necessario, poiché RemoteViews usa sempre Context senza codice. Il messaggio del commit dice solo che ci sono due punti in cui ApplicationInfo può essere memorizzato nella cache e penso che rimuovere l'aggiornamento della versione con il codice non causerebbe problemi qui (poiché checkAndUpdateApkPaths() è usato solo da AppWidgetHostView e RemoteViews). Tuttavia, la controargomentazione è evitare la possibilità di avere varie cache fuori sincronia, e sebbene rimuovere la chiamata con cacheWithCode=true elimini l'impatto più grave di questo bug, non risolve completamente il problema, poiché la modifica delle sole risorse (invece del codice) potrebbe comunque essere preziosa per un attaccante

Scarica lo strumento