Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-0073-Research — CVE-2026-0073 est une RCE avec un score de sévérité CVSS de 8,3, et nous expliquerons ici comment elle fonctionne. | Kitploit
Outils/GitHubGitHub/novaek/cve-2026-0073-research
Analyse des VulnérabilitésExploitationRétro-ingénierieSécurité WebAnalyse de Binaires
GitHubnovaek/cve-2026-0073-research

CVE-2026-0073-Research

CVE-2026-0073 est une RCE avec un score de sévérité CVSS de 8,3, et nous expliquerons ici comment elle fonctionne.

Voir le dépôt
5116il y a 5 moisPas encore vérifié

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

Recherche CVE-2026-0073

CVE-2026-0073 est une RCE avec un score de sévérité CVSS de 8,3, et ici nous expliquerons comment elle fonctionne.

Première partie : Analyse du code :

Au départ, la seule chose qui pourrait éventuellement être intéressante est d'en apprendre davantage sur le bug lui-même.

Ma première source est : https://www.tenable.com/cve/CVE-2026-0073

Cette source nous indique que le fichier auth.cpp montre une fonction appelée adbd_tls_verify_cert qui possède un flux permettant une RCE non authentifiée.

L'objectif principal maintenant est d'obtenir le code source de auth.cpp.

Comme je n'ai pas pu le trouver dans un dépôt officiel, j'ai trouvé ce dépôt créé par Project-Awaken à l'adresse : https://github.com/Project-Awaken/android_packages_modules_adb/blob/12/daemon/auth.cpp

et le voilà ! notre mystérieuse fonction :

int adbd_tls_verify_cert(X509_STORE_CTX* ctx, std::string* auth_key) {
    if (!auth_required) {
        // Any key will do.
        LOG(INFO) << __func__ << ": auth not required";
        return 1;
    }

    bool authorized = false;
    X509* cert = X509_STORE_CTX_get0_cert(ctx);
    if (cert == nullptr) {
        LOG(INFO) << "got null x509 certificate";
        return 0;
    }
    bssl::UniquePtr<EVP_PKEY> evp_pkey(X509_get_pubkey(cert));
    if (evp_pkey == nullptr) {
        LOG(INFO) << "got null evp_pkey from x509 certificate";
        return 0;
    }

    IteratePublicKeys([&](std::string_view public_key) {
        // TODO: do we really have to support both ' ' and '\t'?
        std::vector<std::string> split = android::base::Split(std::string(public_key), " \t");
        uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
        const std::string& pubkey = split[0];
        if (b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) {
            LOG(ERROR) << "Invalid base64 key " << pubkey;
            return true;
        }

        RSA* key = nullptr;
        if (!android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key)) {
            LOG(ERROR) << "Failed to parse key " << pubkey;
            return true;
        }

        bool verified = false;
        bssl::UniquePtr<EVP_PKEY> known_evp(EVP_PKEY_new());
        EVP_PKEY_set1_RSA(known_evp.get(), key);
        if (EVP_PKEY_cmp(known_evp.get(), evp_pkey.get())) {
            LOG(INFO) << "Matched auth_key=" << public_key;
            verified = true;
        } else {
            LOG(INFO) << "auth_key doesn't match [" << public_key << "]";
        }
        RSA_free(key);
        if (verified) {
            *auth_key = public_key;
            authorized = true;
            return false;
        }

        return true;
    });

    return authorized ? 1 : 0;
}

Mais la partie intéressante de la fonction est la suivante :

bool verified = false;
bssl::UniquePtr<EVP_PKEY> known_evp(EVP_PKEY_new());
EVP_PKEY_set1_RSA(known_evp.get(), key);
if (EVP_PKEY_cmp(known_evp.get(), evp_pkey.get())) {
  LOG(INFO) << "Matched auth_key=" << public_key;
  verified = true;
} else {
  LOG(INFO) << "auth_key doesn't match [" << public_key << "]";
}

Pourquoi ? parce que verified est défini comme un booléen qui autorise ou non la connexion, et il n'est modifié qu'avec l'instruction "if". Le problème ? le EVP_PKEY_cmp(known_evp.get(), evp_pkey.get()) ne retourne pas toujours 1 ou 0, mais aussi -1 et -2 car EVP_PKEY_cmp() retourne 1 si les clés correspondent, 0 si elles ne correspondent pas, -1 si les types de clés sont différents et -2 si l'opération n'est pas prise en charge.

Il valide donc les certificats de clés différentes ou si l'opération n'est pas prise en charge, même si la clé ne correspond pas.

Afin de valider notre session, nous devrons forcer l'une de ces deux options.

Deuxième partie : Production du POC et rétro-ingénierie du protocole de connexion ADB

Afin d'essayer d'exploiter cette faille, nous devrons engager une session TLS.

Cela ne fonctionne que si l'attaquant et l'appareil ciblé sont tous deux capables d'utiliser TLS. Cependant, la décision d'utiliser TLS n'est prise que par l'appareil ciblé.

Si l'appareil ciblé autorise TLS, vous pouvez engager une session TLS.

Tout se passe ici :

  • Premièrement : les paquets CNXN (paquets de connexion)
  • Deuxièmement : les paquets STLS (paquets de mise à niveau vers TLS)
  • Troisièmement : la poignée de main TLS (avec une clé EC au lieu de RSA)

Essayons de faire fonctionner cela

Télécharger l’outil