Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
ResourcePoison — Writeup e exploit para CVE-2025-22441: Escalação de privilégio de aplicativo instalado para o processo SystemUI no Android devido à passagem de ApplicationInfo não confiável para LoadedApk | Kitploit
Ferramentas/GitHubGitHub/michalbednarski/resourcepoison
Segurança AndroidEscalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoSegurança MóvelPapers e Pesquisa
GitHubmichalbednarski/resourcepoison

ResourcePoison

Writeup e exploit para CVE-2025-22441: Escalação de privilégio de aplicativo instalado para o processo SystemUI no Android devido à passagem de ApplicationInfo não confiável para LoadedApk

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver Repositório
1082963há 0 anosRevisado pelo Kitploit

A correção para este problema apareceu como CVE-2025-22441: boletim patch acompanhamento

Passando ApplicationInfo por aí

ApplicationInfo é uma estrutura que define várias informações sobre o aplicativo instalado, principalmente o caminho para o arquivo apk do qual recursos e código são carregados

Normalmente ele é passado do sistema para os aplicativos, no entanto, às vezes há casos em que um chamador não pertencente ao sistema pode fornecer um próprio. Por exemplo, no passado houve vulnerabilidade no método bindBackupAgent(), onde o atacante podia passar como parâmetro um objeto ApplicationInfo próprio com valores de uid e sourceDir que não eram verificados em relação aos aplicativos realmente instalados no sistema, porque esse método deveria ser chamado internamente pelo system_server, mas estava exposto ao adb shell

Desta vez, porém, examinei de perto o campo ApplicationInfo dentro de RemoteViews

RemoteViews é um objeto que descreve uma visualização que pode vir de outro processo. Isso é usado principalmente para widgets da tela inicial, onde o aplicativo que fornece o widget constrói RemoteViews e então ele é "aplicado" dentro do processo da tela inicial

Outros lugares onde RemoteViews são usados incluem notificações (aplicadas pelo processo SystemUI) e diálogos de preenchimento automático (fornecidos pelo serviço de preenchimento automático, aplicados pelo system_server)

O campo RemoteViews.mApplication é serializado através de Parcel e, portanto, pode vir de processos remotos e, sempre que RemoteViews são aplicados, ele é usado pelo seguinte método (fonte do trecho):```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;

}

O mais interessante aqui é a chamada `LoadedApk.checkAndUpdateApkPaths()`, pois este é um método estático e modificará algum estado global [(fonte do trecho)](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);
}

Vamos discutir o que está acontecendo nesses métodos

Primeiro, estamos chamando checkAndUpdateApkPaths com 3 parâmetros, com cacheWithCode definido tanto como true quanto como false. O objeto LoadedApk pode ser construído em dois modos, ou com mIncludeCode sendo true ou false, o que, em termos de SDK, corresponde a um Context com a flag CONTEXT_INCLUDE_CODE definida ou não

Esse método primeiro usará ActivityThread.peekPackageInfo(), que retornará a instância de LoadedApk já armazenada em cache; portanto, se o aplicativo não tiver construído anteriormente um LoadedApk com packageName e includeCode correspondentes, peekPackageInfo() retornará null e checkAndUpdateApkPaths() não fará nada

Voltando a RemoteViews.getContextForResourcesEnsuringCorrectCachedApkPaths(), temos context.createApplicationContext(mApplication, Context.CONTEXT_RESTRICTED) ali; a flag CONTEXT_INCLUDE_CODE não foi especificada (o mesmo ocorre com os contextos passados como argumento para esse método) e, portanto, esse método sempre usará LoadedApk com mIncludeCode=false

Portanto, para RemoteViews, atualizar a versão com código é desnecessário, pois RemoteViews sempre usam Context sem código. A mensagem do commit apenas diz que há dois lugares onde ApplicationInfo pode ser armazenado em cache e acredito que remover a atualização da versão com código não causaria problemas aqui (já que checkAndUpdateApkPaths() é usado apenas por AppWidgetHostView e RemoteViews). O contra-argumento para isso, no entanto, é evitar a possibilidade de dessincronizar vários caches e, embora remover a chamada com cacheWithCode=true elimine o impacto mais severo desse bug, isso não corrige completamente o problema, pois a modificação apenas de recursos (em vez de código) ainda pode ser valiosa para um atacante

LoadedApk.updateApplicationInfo()

Baixar ferramenta