
CVE 재현: cve-2026-63030_60137-wordpress_rce_reproduction
발견자: Searchlight Cyber (GPT-5.6 Sol 경유)
심각도: 치명적 — CVSS 9.8 (CVE-2026-63030), CVSS 9.1 (CVE-2026-60137)
상태: 활발히 악용 중 — CISA KEV에 추가됨
별칭: "wp2shell"
이것은 두 개의 CVE로 구성된 WordPress Core의 인증되지 않은 원격 코드 실행 체인입니다.
| CVE | 구성 요소 | 유형 | CWE |
|---|---|---|---|
| CVE-2026-63030 | WP REST API 일괄 엔드포인트 | 경로 혼동 / 접근 제어 우회 | CWE-436 |
| CVE-2026-60137 | WP_Query author__not_in 매개변수 | SQL 인젝션 | CWE-89 |
개별적으로 각 결함은 심각하지만, 결합하면 인증되지 않은 공격자가 대상에서 임의의 PHP를 실행하고 웹쉘을 배포할 수 있습니다.
WordPress REST API는 /wp-json/wp/v2/batch에 일괄 엔드포인트를 노출합니다. 경로 확인의 결함(WP 6.9의 재작성된 라우팅 미들웨어에서 도입됨)으로 인해 일괄 처리기는 일괄 내부의 내부 하위 요청이 외부 요청의 인증 및 권한 검사를 상속하는지 올바르게 검증하지 않습니다. 공격자는 다음을 수행할 수 있는 일괄 페이로드를 제작할 수 있습니다:
wp/v2/users, wp/v2/plugins)를 호출합니다.WP_REST_Server::dispatch()를 활용하여 위조된 경로 매개변수를 내부 핸들러에 전달합니다.이것은 매개변수 밀반입(parameter smuggling)과 결합될 때 읽기 작업과 일부 쓰기 작업에 대한 모든 인증 가드를 우회합니다.
author__not_in SQL 인젝션WP_Query 클래스는 특정 작성자 ID의 게시물을 제외하기 위한 author__not_in 매개변수를 허용합니다. WP 6.9의 쿼리 정화 리팩터링에서 도입된 WP_Query::get_posts() 메서드의 유형 강제 변환 버그로 인해 특수하게 조작된 연관 배열로 제공되면 author__not_in 값이 적절한 매개변수화 없이 SQL WHERE 절에 직접 삽입됩니다.
인젝션은 생성된 SQL의 post_author IN (...)에서 발생합니다. 원시 SQL 조각으로 배열을 중첩함으로써 공격자는 IN 절을 벗어나 임의의 UNION / INTO OUTFILE 문을 실행할 수 있습니다. 단, 데이터베이스 사용자에게 FILE 권한이 있어야 합니다.
Attacker (unauthenticated)
│
├─ POST /wp-json/wp/v2/batch
│ └─ CVE-2026-63030: Bypass auth, invoke internal query API
│ └─ CVE-2026-60137: Inject SQL via author__not_in
│ └─ UNION SELECT ... INTO OUTFILE 'webshell.php'
│ └─ Webshell deployed to web root
│ └─ RCE achieved
일괄 엔드포인트는 벡터를 제공하고, SQLi는 페이로드 전달을 제공합니다.
| 버전 범위 | 전체 체인 |
|---|---|
| WordPress 6.9.0 – 6.9.4 | ✅ 두 CVE 모두 존재 |
| WordPress 7.0.0 – 7.0.1 | ✅ 두 CVE 모두 존재 |
| WordPress ≤ 6.8.x | CVE-2026-63030만 해당 (SQLi 악용 불가) |
패치는 WordPress 6.9.5 및 7.0.2에서 배포되었습니다(둘 다 2026-07-16 발행).
/wp-json/wp/v2/batch가 200(403/404가 아닌)을 반환하는지 확인합니다.--target 플래그를 사용하여 PoC를 실행합니다(아래 참조)./wp-content/webshell.php?cmd=id에서 웹쉘을 확인합니다.python exploit.py --target https://target.example.com --action deploy-webshell
python exploit.py --target https://target.example.com --action exec --command "id"
python exploit.py --target https://target.example.com --action exec --command "uname -a"
POST /wp-json/wp/v2/batch를 차단하세요.FILE 권한을 제거하세요.define('DISALLOW_FILE_EDIT', true); 및 define('DISALLOW_FILE_MODS', true);를 활성화하세요.wp-content/ 아래에서 예기치 않은 .php 파일을 모니터링하세요.author__not_in을 확인하세요.