# Zoom RCE from Pwn2Own 2021

Zero-click heap overflow in Zoom chat's AES decryption of ResponseKey messages allows remote code execution via crafted XMPP stanza.

- Payout: unconfirmed
- Severity: critical
- Program: Zoom
- Credited: Thijs Alkemade, Daan Keuper
- Disclosed: 2021-08-23
- Write-up quality: 10/10
- Original: https://sector7.computest.nl/post/2021-08-zoom/
- Library page: https://bugbountylibrary.com/r/blog%3Asector7-computest-nl-post-2021-08-zoom
- Tags: domain:desktop impact:rce kind:bounty platform:blog sev:critical technique:chained technique:reverse-engineering technique:source-review vuln:memory-corruption vuln:rce

**Target:** Zoom Meetings client (Windows) chat XMPP handler
**Root cause:** AESDecode allocates a fixed 1024-byte buffer for decrypted data but fails to validate that the decrypted length fits, unlike the RSA path. A ResponseKey message with an AES-encrypted <encoded> element larger than 1024 bytes overflows the heap buffer.
**Steps:**
1. Send a chat message with an unknown key identifier to trigger a RequestKey from the victim.
2. Respond with a ResponseKey message containing an AES-encrypted <encoded> element larger than 1024 bytes.
3. The client decrypts using AES and overflows the 1024-byte heap buffer with attacker-controlled data.
4. Heap groom to place a target object (e.g., libcurl struct) after the overflow buffer.
5. Overwrite a function pointer/vtable to redirect execution to a ROP chain in a non-CFG OpenSSL DLL.
6. Leak an address from OpenSSL DLL via a crafted HTTPS request to bypass ASLR.
7. Execute ROP chain to achieve arbitrary code execution.
**How found:** While reverse-engineering Zoom's chat protocol, researchers noticed incorrect buffer size calculations around OpenSSL calls (e.g., overallocating for base64). They focused on OpenSSL usage and found the missing length check in AESDecode for ResponseKey messages.
**Exploitation:** Attacker sends crafted XMPP stanzas to a victim who has accepted external contact or is in the same multi-user chat. The overflow is triggered automatically without user interaction. Heap grooming places a libcurl object after the overflow buffer, overwriting a function pointer. A ROP chain in a non-CFG OpenSSL DLL is used to bypass DEP and CFG, leading to code execution.
**Escalation:** Chained with an info leak via a URL redirection bug to bypass ASLR, and used non-CFG OpenSSL DLLs to bypass Control Flow Guard.
**Insight:** When auditing crypto protocol implementations, compare validation between different algorithm paths (e.g., RSA vs AES). A missing check in one path can lead to memory corruption. Also, libraries without CFG (like OpenSSL DLLs) can be leveraged to bypass mitigations.
