# CVE-2024-0244 – A heap buffer overflow in the Canon MF753Cdw printer

Unauthenticated heap overflow in Canon MF753Cdw fax SOAP parser yields arbitrary free(), chained with BJNP buffers to hijack a function pointer and run shellcode.

- Payout: Research
- Severity: high
- Program: Canon MF753Cdw
- Write-up by: Connor Ford
- Disclosed: 2026-09-23
- CVE: CVE-2024-0244
- Write-up quality: 9/10
- Original: https://www.thezdi.com/blog/2026/9/23/cve-2024-0244-a-heap-buffer-overflow-in-the-canon-mf753cdw-printer
- Library page: https://bugbountylibrary.com/r/blog%3Athezdi-com-blog-2026-9-23-cve-2024-0244-a-heap-buffer-overflow-in-the-canon-mf753cdw-printer
- Tags: area:devices domain:iot domain:network impact:rce kind:research platform:research sev:high tech:rest technique:chained technique:reverse-engineering technique:source-review vuln:memory-corruption vuln:rce

**Target:** Printer fax driver SOAP endpoint /wsd/print and BJNP protocol service
**Root cause:** The fax binary payload's destination number length byte is trusted; the number is copied into a fixed phone_number array with no bounds check, overflowing into a void* member of the heap object that is later passed to free().
**Steps:**
1. Install Canon fax driver, submit fax job, capture SOAP traffic to `/wsd/print` with Wireshark
2. Identify binary payload where each string is preceded by a length byte (destination number = primarynumberhere)
3. Set destination number length byte to `0xff` and send long string of A's as the fax number
4. Observe printer crash/reboot and free()-related log messages
5. Patch free() calls to `dtdo_free_with_log()` via UART shell to log freed addresses
6. Resend malformed payload and confirm the pointer passed to free() is fully attacker-controlled
**How found:** Prior Pwn2Own experience on the sibling MF743Cdw suggested the obvious cadm service was picked over; instead targeted the obscure fax driver. Captured SOAP traffic, noticed the only binary SOAP message, spotted length-prefixed strings, fuzzed the length byte to 0xff, saw crash plus free() logs, then instrumented free() via UART to confirm a controlled pointer.
**Exploitation:** Send BJNP request #1 containing a fake heap chunk with valid metadata at a known fixed address; send BJNP request #2 containing shellcode at another known fixed address. Trigger the fax arbitrary free() with the fake chunk address, placing BJNP buffer 1 on the heap free list. The fax flow's next allocation lands on that chunk; close and reopen the BJNP session so client data overwrites the allocated object, replacing a function pointer with the address of BJNP buffer 2 shellcode. All Canon dynamic memory is RWX, so jumping there executes shellcode (demo: fetch image and write to framebuffer).
**Escalation:** Chained arbitrary free with BJNP fixed-address buffers to convert a heap overflow into controlled function-pointer hijack and code execution, avoiding unreliable heap-grooming approaches.
**Insight:** Length-prefixed binary blobs inside SOAP/print protocols are prime overflow candidates: mutate the length byte, watch for free()-related crash logs, and instrument allocator calls via debug shell to confirm control of the freed pointer. On Canon, BJNP's fixed-address, null-byte-tolerant buffers plus RWX memory turn any arbitrary free into a reliable shellcode staging primitive.
