# Remote Deserialization Bug in Microsoft's RDP Client through Smart Card Extension (CVE-2021-38666)

RDP client deserializes smart card DeviceIoRequest PDUs via RPC NDR engine without validating InputBufferLength, causing heap OOB read and DWORD byteswap heap corruption.

- Payout: $5,000
- Severity: critical
- Program: Microsoft
- Credited: Valentino Ricotta
- Disclosed: 2021-12-10
- CVE: CVE-2021-38666
- Write-up quality: 8/10
- Original: https://thalium.github.io/blog/posts/deserialization-bug-through-rdp-smart-card-extension/
- Library page: https://bugbountylibrary.com/r/blog%3Athalium-github-io-blog-posts-deserialization-bug-through-rdp-smart-card-extension
- Tags: domain:desktop domain:network impact:dos impact:rce kind:bounty platform:blog sev:critical tech:windows technique:fuzzing technique:source-review vuln:deserialization vuln:memory-corruption

**Target:** mstsc.exe / mstscax.dll RDPDR smart card virtual channel (W32SCard)
**Root cause:** PDU->InputBufferLength is trusted and passed to MesDecodeBufferHandleCreate/NdrMesTypeDecode3; the NDR endianness-conversion pass byteswaps FC_ULONG fields across the whole claimed length, and attacker-controlled cAtrs/cReaders array counts extend the walk past the real buffer.
**Steps:**
1. Connect to malicious RDP server that opens RDPDR and smart card sub-channel.
2. Send Device Control Request PDU with IoControlCode `0x000900E8` (LocateCardsByATRA_Call).
3. Set InputBufferLength larger than actual InputBuffer, e.g. `00 80 2d 00`.
4. Craft InputBuffer with mismatched endianness DataRepresentation and large cAtrs/cReaders to force byteswaps past buffer end.
5. Observe crash in `NdrSimpleTypeConvert+0x307` (`mov eax,[rdx]; bswap eax`) or heap corruption in mstscax.dll.
**How found:** Fuzzed RDPDR virtual channel with modified WinAFL and network harness; many nonsensical crashes across modules seemed like fuzzer breakage, but recurring crash in RPCRT4.DLL NdrSimpleTypeConvert led to tracing call stacks into W32SCard functions sharing MesDecodeBufferHandleCreate/NdrMesTypeDecode3 pattern, then mapping IoControlCode to smart card spec structures.
**Exploitation:** No PoC achieved. Attacker-controlled server sends crafted smart card PDUs; NDR conversion pass byteswaps DWORDs every 76 bytes across heap, corrupting vtables/pointers. Author theorizes heap spray plus aligned byteswap could hijack a vtable for RCE but did not demonstrate it.
**Escalation:** Heap corruption from repeated DWORD byteswaps could damage vtable pointers; author hypothesized vtable hijack via heap spray but did not achieve it.
**Insight:** When fuzzing a protocol with many similar handlers, cluster crashes by shared code pattern (here MesDecodeBufferHandleCreate + NdrMesTypeDecode3) rather than dismissing them as noise; a length field trusted by a deserializer's endianness-conversion pre-pass can corrupt heap even without a full parse.
