
인증되지 않은 임의 파일 업로드 -> WPLP Cookie Consent(gdpr-cookie-consent) <= 4.4.1에서의 RCE - 기술 분석 및 PoC
CVE-2026-75865에 대한 개념 증명(PoC) 및 기술 문서입니다. 이 취약점은 WordPress용 WPLP Cookie Consent – Cookie Banner & Consent Management for GDPR, CCPA & Google Consent Mode 플러그인(슬러그 gdpr-cookie-consent)에서 인증되지 않은 임의 파일 업로드를 통해 원격 코드 실행으로 이어지는 취약점으로, 4.4.1 이하 모든 버전에 영향을 미칩니다.
| 주요 정보 |
|---|
| CVE | CVE-2026-75865 |
| 심각도 | 치명적(Critical) — CVSS 3.1 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| 취약점 유형 | CWE-862 (인가 누락) + CWE-434 (위험한 유형의 파일 무제한 업로드) |
| 영향 버전 | gdpr-cookie-consent ≤ 4.4.1 |
| 수정 버전 | 4.4.2 |
| CVE 배포 기관 | Wordfence |
| 공개일 | 2026-09-01 |
| 발견자 | Supakiad S. (m3ez) |
이 플러그인의 SaaS "커넥터" REST 엔드포인트는 요청 인증을 벤더의 SaaS 애플리케이션에 위임하며, SaaS는 Bearer JWT를 검증합니다. 그러나 플러그인은 검증 엔드포인트가 HTTP 200으로 응답하는지만 확인할 뿐입니다. JWT와 대상 사이트 간의 소유권 바인딩이 없으므로 SaaS에서 발급된 유효한 토큰(예: 무료 계정에서 발급된 토큰)은 모두 허용됩니다.
그런 다음 saas_upload_logo() 함수는 공격자가 제공한 base64 블롭(blob)을 공격자가 지정한 파일명으로 공개 디렉토리인 wp-content/uploads/에 콘텐츠나 확장자 검증 없이 기록합니다. 엔드포인트를 보호하는 저장된 API 토큰(master_key)도 실제로는 비밀이 아닙니다. 플러그인 자체의 /store-auth 라우트가 동일한 JWT 검증 후 요청 파라미터에서 이 토큰을 덮어쓰기 때문입니다. 따라서 인증되지 않은 요청부터 웹 루트에서 실행되는 페이로드까지의 전체 공격 체인에는 대상 URL과 무료 SaaS 계정만 있으면 됩니다.
이 취약점은 4.4.2에서 업로드 엔드포인트를 완전히 제거하고 커넥터 신뢰 모델(JWT 소유권 바인딩, hash_equals(), HMAC 요청 서명)을 재설계하여 수정되었습니다.
전체 기술 분석: REPORT.md
| 파일 | 설명 |
|---|---|
REPORT.md | 상세 기술 문서: 라인 참조 코드가 포함된 근본 원인 분석, 4.4.1 → 4.4.2 수정 비교, 공격 체인, 탐지 및 완화 방법 |
cve_2026_75865.py | PoC 스크립트 — 대상 목록을 스캔하고 취약한 사이트를 탐지하며 전체 체인(관리자 열거 → 마스터 키 덮어쓰기 → 페이로드 업로드 → 검증)을 실시간 출력과 함께 실행 |
payload.php | 기본적으로 사용되는 최소한의 무해한 페이로드: 마커 문자열을 출력하고 자체 삭제(?delete=1)를 지원 |
git clone https://github.com/ghostpels/CVE-2026-75865.git
cd CVE-2026-75865
pip install requests # colorama는 선택 사항입니다 (컬러 로그)
# 1. 유효한 SaaS JWT(app.wplegalpages.com의 모든 계정)를 jwt.txt에 저장합니다
# 2. 대상 목록을 만들고 테스트 권한이 있는 시스템에 대해서만 실행합니다:
python cve_2026_75865.py -l targets.txt -o vuln.txt -t 40 --marker CVE-2026-75865-POC
검증된 페이로드 URL은 각 대상이 검증되는 즉시 vuln.txt에 한 줄씩 실시간으로 추가됩니다.
| 옵션 | 기본값 | 설명 |
|---|---|---|
-l, --list | (필수) | 대상 목록, URL 한 줄당 하나 |
-o, --output | vuln.txt | 검증된 페이로드 URL, 실시간 추가 |
-t, --threads | 40 | 동시 작업자 수 |
--shell | payload.php | 스크립트 옆에 있는 페이로드 파일; 업로드 이름 = 파일의 기본 이름 |
--filename | — | 사용자 지정 업로드 파일명 (해당 확장자가 먼저 시도되고, 그다음 --exts가 시도됨) |
--exts | php,phtml,php5,php74,php7,php3,php4,phar | 기본 확장자가 차단된 경우의 대체 확장자 |
--jwt-file | jwt.txt | SaaS JWT, 첫 번째 비어 있지 않은 줄 |
--marker | — | 페이로드 응답에 나타나야 유효한 것으로 간주되는 문자열 |
--timeout | 15 | 요청당 제한 시간(초) |
-k, --insecure | 꺼짐 | TLS 검증 비활성화 |
-v, --verbose | 꺼짐 | 연결 오류 세부 정보 표시 |
이 저장소는 교육 및 방어적 보안 연구 목적으로만 게시됩니다. 이 도구는 소유한 시스템이나 명시적인 서면 테스트 허가를 받은 시스템에 대해서만 사용하십시오. 저자는 이 자료의 오용이나 이로 인한 피해에 대해 책임을 지지 않습니다.