[하루한줄] CVE-2025-20260: ClamAV PDF parer의 Heap 메모리 손상으로 인한 취약점
URL
Target
- ClamAV < 1.4.3, 1.09
Explain
Cisco ClamAV는 이메일 첨부파일, 파일 업로드, 네트워크 트래픽 내 파일을 검사하기 위해 PDF, Office 문서, 압축 파일 등을 자체 파서(libclamav)로 분석하는 오픈소스 안티바이러스 엔진입니다.
PDF 파일의 경우 cli_scanpdf()를 시작으로 객체 파싱(pdf_extract_obj)과 스트림 디코딩(pdf_decodestream) 과정을 거쳐 악성 여부를 판단합니다.
CVE-2025-20260은 PDF 스트림 객체의 /Length 필드 처리 과정에서 길이 검증이 불완전하여 발생하는 취약점으로, 특수 제작된 PDF 파일을 스캔하도록 유도할 경우 힙 기반 버퍼 오버플로우가 발생합니다.
이로 인해 ClamAV 프로세스가 충돌하며 서비스 거부(DoS)가 유발됩니다.
1. Root Cause
취약점의 핵심 원인은 PDF 스트림 길이 값(/Length)에 대한 신뢰입니다.
ClamAV는 PDF 스트림을 디코딩할 때 /Length 필드 값을 기준으로 스트림 데이터를 처리하지만, 이 값이 실제 할당된 힙 버퍼 크기를 초과하는 경우에 대한 상한 검증이 충분하지 않습니다.
개념적으로 문제 되는 흐름은 다음과 같습니다.
length = pdf_stream_length; // PDF 내부 /Length 값
buf = malloc(alloc_size); // 내부 기준으로 할당
memcpy(buf, stream_data, length); // length 검증 부족
이로 인해 length > alloc_size 인 경우 힙 버퍼 경계를 초과한 쓰기(OOB write)가 발생하고, 해당 힙 오염은 이후 메모리 해제 단계까지 영향을 미칩니다.
2. PoC 설명 (clamshank.py)
공개된 PoC(clamshank.py)는 다음과 같은 방식으로 악성 PDF를 생성합니다.
- 정상적인 PDF 구조 유지
- 스트림 객체의
/Length필드 뒤에 비정상적인 숫자 추가 - ASCII85 인코딩된 약 1GB 크기의 대용량 스트림 삽입
# 대용량 스트림 생성
payload =b"A" * (1024 *1024 *1024)
이 PDF를 ClamAV에서 스캔하도록 유도하면, /Length 값이 스트림 디코딩 과정에 그대로 사용하고, 실제 힙 버퍼 크기보다 큰 데이터가 처리되면서 힙 메모리 손상이 발생합니다.
3. Crash 분석 (Core Dump 기준)
PoC 실행 후 ClamAV는 다음 호출 경로로 진입합니다.
main
└─ scanmanager
└─ cli_scanpdf
└─ pdf_extract_obj
└─ pdf_decodestream
└─ free() → SIGSEGV
GDB 분석 결과, pdf_decodestream() 내부에서 이미 손상된 힙 포인터가 free()의 인자로 전달되는 것이 확인됩니다.
free(0xa005c064a005c064)
메모리 내용을 확인하면 동일한 패턴이 반복되어 덮어써져 있으며, 이는 스트림 처리 과정에서 힙 객체 내부 필드가 공격자 제어 데이터로 오염되었음을 의미합니다.
4. Patch
Cisco는 PDF 스트림 처리 로직에서 /Length 값에 대한 상한 검증을 강화했습니다.
length = pdf_stream_length;
if (length > max_allowed_stream_size)
return CL_EFORMAT;
buf = malloc(alloc_size);
memcpy(buf, stream_data, length);
/Length 값이 내부적으로 허용 가능한 최대 크기를 초과할 경우, 스트림 디코딩을 진행하지 않고 즉시 오류를 반환하고, 힙 할당 크기와 디코딩 길이 간 불일치를 차단합니다.
Reference
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.