Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
wp2shell-poc — wp2shell (CVE-2026-63030 & CVE-2026-60137) - 완전한 RCE 체인 | Kitploit
도구/GitHubGitHub/icex0/wp2shell-poc
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingCommand and ControlAuthenticationRed TeamingPayload Development
GitHubicex0/wp2shell-poc

wp2shell-poc

wp2shell (CVE-2026-63030 & CVE-2026-60137) - 완전한 RCE 체인

저장소 보기
7371689일 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

wp2shell-poc

Searchlight Cyber의 wp2shell 권고와 관련된 인증되지 않은 WordPress REST 배치 경로 혼동(route-confusion) SQL 삽입에 대한 독립적인 개념 증명(PoC)입니다.

이 저장소는 Searchlight Cyber의 공식 점검 도구가 아닙니다. check는 SQLi 경로를 확인하고, read는 데이터베이스 읽기를 시연하며, shell은 제공된 관리자 자격 증명을 사용하거나 먼저 SQLi-to-admin 브리지를 실행하여 플러그인 기반 명령 셸을 엽니다.

wp2shell — 사전 인증 SQLi-to-admin 브리지를 실행하는 shell 명령

영향을 받는 버전

Searchlight Cyber 권고에 나열된 wp2shell RCE 노출 범위는 다음과 같습니다.

버전 범위상태
<= 6.8.5영향을 받지 않음
6.9.0 – 6.9.4영향 받음
7.0.0 – 7.0.1영향 받음

작동 방식

REST 배치 엔드포인트(/batch/v1)는 인증이 없으며, 하나의 호출에서 여러 하위 요청을 실행하고 각 하위 요청이 자체적으로 검증 및 권한 검사를 받도록 합니다.

serve_batch_request_v1()은 두 개의 병렬 배열, 즉 $matches(하위 요청별 일치하는 핸들러)와 $validation(하위 요청별 검증 결과)을 만든 다음 디스패치할 때 동일한 오프셋으로 둘 다 인덱싱합니다. wp_parse_url()에 실패하는 경로를 가진 하위 요청은 $validation에는 추가되지만 $matches에는 추가되지 않으므로 배열이 어긋나게 되고, 하위 요청이 다른 하위 요청의 핸들러 아래에서 디스패치됩니다. 이것이 경로 혼동입니다.

PoC는 이 프리미티브를 두 번 중첩합니다:

  1. requests 본문을 가진 POST /wp/v2/posts 요청은 배치 핸들러 자체 아래에서 디스패치됩니다. posts 요청으로 검증되었기 때문에 requests 목록은 배치 스키마와 대조하여 검사되지 않으므로 하위 요청은 GET을 사용할 수 있습니다. 메서드 허용 목록이 우회됩니다.
  2. 내부 배치 안에서 GET /wp/v2/posts/999999 항목-라우트 요청은 author_exclude, orderby, per_page 같은 posts 컬렉션 쿼리 매개변수를 전달합니다. 999999 ID는 존재할 필요가 없습니다. 단지 컬렉션 전용 매개변수를 검증하지 않는 항목 라우트와 일치시키기 위한 흔하지 않은 포스트 ID일 뿐입니다. 그런 다음 이 desync로 인해 동일한 요청이 posts get_items() 아래에서 디스패치되고, 여기서 author_exclude는 WP_Query의 author__not_in 쿼리 변수에 매핑되며, 취약한 빌드는 이를 SQL에 문자열로 삽입합니다.

그 결과 인증 전에 도달할 수 있는 boolean 및 시간 기반 블라인드 SQL 삽입이 발생합니다. 이 PoC에는 SQLi-to-admin 체인에서 사용되는 UNION 가짜 포스트 프리미티브도 포함되어 있습니다.

여기서 구현된 RCE 경로는 다음과 같습니다:

  1. UNION 가짜 wp_posts 행을 사용하여 posts 컬렉션을 통해 공격자 제어 콘텐츠를 렌더링합니다. 렌더 브리지는 /wp/v2/posts/999999 항목-라우트 소스를 사용합니다. SQLi 읽기가 get_items()에 도달하기 위해 사용하는 것과 동일한 라우트입니다.
  2. 해당 렌더링을 사용하여 WordPress가 실제 oEmbed 캐시 포스트를 만들게 합니다.
  3. SQLi를 통해 해당 실제 캐시 포스트 ID를 복구합니다.
  4. 하나의 오염된 배치 요청에서 해당 ID를 커스터마이저 변경 세트(customizer changeset), 내비게이션 항목, 요청 훅 형태로 재해석합니다.
  5. 동일한 요청이 POST /wp/v2/users에 도달하여 생성된 관리자를 만들게 합니다.
  6. 생성된 관리자로 로그인하고 플러그인 업로드 동작을 사용하여 명령을 실행합니다.

1~5단계는 인증 전이며, 명령 실행 단계는 인증된 관리자 플러그인 업로드입니다.

요구 사항

Python 3.8+ 및 표준 라이브러리. 타사 종속성은 없습니다.

사용법

저장소 디렉터리에서 실행합니다:

root@kitploit:~
./wp2shell.py <command> <url> [options]

또는 pip install .를 실행하여 PATH에 wp2shell 명령을 추가할 수 있습니다.

check — 비파괴 취약점 확인

먼저 수동적 WordPress 마커와 공개 버전 힌트를 출력한 다음, 무해한 배치 마커 프로브를 보냅니다. 취약한 배치 구현은 경로 혼동 마커 패턴인 parse_path_failed, block_cannot_read, rest_batch_not_allowed와 함께 HTTP 207을 반환합니다.

마커 프로브는 WordPress 코어 수정을 기반으로 합니다. 잘못된 /// 요청은 parse_path_failed를 만들고, /wp/v2/posts 요청은 배치 허용 스페이서 역할을 하며, /wp/v2/block-renderer/... 라우트는 배치가 허용되지 않지만 핸들러에 익명으로 도달하면 block_cannot_read를 반환하고, /batch/v1은 rest_batch_not_allowed를 반환합니다. 취약한 빌드에서는 구문 분석 오류로 인해 배치 핸들러 배열이 어긋나므로 스페이서 요청이 블록 렌더러 핸들러 아래에서 디스패치됩니다. 수정된 빌드는 배열을 일치된 상태로 유지하므로, 제작된 프로브에 대해 이 세 가지가 모두 나타나는 패턴은 나타나지 않아야 합니다.

기본적으로 check는 여기서 멈추고 SQLi 페이로드를 보내지 않습니다. 활성 SQLi 확인도 원한다면 --confirm-sqli를 사용하십시오. 확인은 먼저 UNION 읽기 프리미티브를 시도하고, UNION 반사가 불가능하면 짝을 이루는 타이밍 프로브로 대체합니다.

신호는 서로 독립적입니다. 버전 힌트는 힌트일 뿐이며, 마커 패턴은 경로 혼동을 보여주고, --confirm-sqli는 페이로드가 데이터베이스에 도달했음을 보여줍니다. WAF가 페이로드를 차단할 수 있으므로 확인 실패가 버그가 없음을 증명하지는 않습니다.

root@kitploit:~
./wp2shell.py check http://target
./wp2shell.py check targets.txt          # scan every URL in the file

read — SQL 삽입을 통한 데이터 추출

root@kitploit:~
./wp2shell.py read http://target                      # server fingerprint
./wp2shell.py read http://target --preset users       # user logins and password hashes
./wp2shell.py read http://target --query "SELECT @@version"

기본적으로 추출은 --technique auto를 사용하며, 다음 순서로 사용 가능한 방법을 시도합니다:

  1. union — UNION을 통해 가짜 WP_Post 행을 만들고 REST 응답에서 제목을 ||HEX(value)||로 다시 읽습니다. 페이로드는 orderby=none 및 per_page=500과 함께 동일한 /wp/v2/posts/999999 소스 라우트를 사용하므로 가짜 행이 렌더링된 포스트로 유지됩니다. 값당 요청 1회.
  2. error — 대상이 MySQL 오류를 반영할 때(예: WP_DEBUG_DISPLAY 켜짐) 요청당 약 15바이트를 유출하는 EXTRACTVALUE/UPDATEXML.
  3. blind — boolean 이진 탐색으로 문자당 약 8개 요청. posts 컬렉션의 X-WP-Total 헤더를 참/거짓 신호로 읽으며 반영된 값이 필요 없습니다.

--technique union|error|blind로 하나를 강제로 지정할 수 있습니다. 이러한 읽기 경로는 데이터베이스 행을 쓰지 않습니다.

shell — 명령 실행

--user 및 --password를 사용하면 shell은 제공된 관리자 자격 증명으로 로그인하고 WordPress 플러그인 업로드 동작을 사용합니다.

자격 증명이 없으면 shell은 먼저 사전 인증 SQLi-to-admin 브리지를 실행하고 생성된 관리자로 로그인한 다음 플러그인 셸을 업로드합니다.

root@kitploit:~
./wp2shell.py shell http://target --user admin --password '<recovered>' --cmd id
./wp2shell.py shell http://target --user admin --password '<recovered>' -i   # interactive shell
./wp2shell.py shell http://target --cmd id                                   # pre-auth bridge
./wp2shell.py shell http://target -i                                         # pre-auth interactive

shell은 플러그인 웹셸(임의 경로와 실행별 토큰으로 잠김)을 업로드하고 해당 경로를 출력합니다. 업로드된 웹셸은 자동으로 제거됩니다. 사전 인증 브리지가 관리자를 생성한 경우 해당 생성 계정은 셸 세션이 끝난 후 자동으로 제거됩니다.

옵션

해결 방법

WordPress 7.0.2로 업데이트하거나, 사이트가 6.9 브랜치에 있다면 6.9.5로 업데이트하십시오. 그때까지는 /wp-json/batch/v1과 rest_route=/batch/v1 쿼리 매개변수를 모두 엣지에서 차단하거나, rest_pre_dispatch 필터를 통해 배치 엔드포인트에 인증을 요구하십시오.

법적 고지

공인된 보안 테스트 전용입니다. 소유하고 있거나 명시적인 서면 허가를 받은 시스템에 대해서만 사용하십시오. 어떠한 보증도 제공되지 않으며 오용에 대한 책임도 지지 않습니다.

참고 자료

  • WordPress 7.0.2 릴리스 공지 — https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
  • Searchlight Cyber wp2shell 권고 — https://slcyber.io/research-center/wp2shell-pre-authentication-rce-in-wordpress-core/
  • sergiointel/wp2shell-poc SQLi-to-admin 브리지 — https://github.com/sergiointel/wp2shell-poc
도구 다운로드
옵션적용 대상설명
--proxy URL모두HTTP 프록시(예: Burp)를 통해 트래픽을 라우팅합니다.
--timeout N모두요청 제한 시간(초)입니다.
--sleep Ncheck--confirm-sqli의 타이밍 폴백에서 사용하는 지연 시간입니다.
--samples Ncheck--confirm-sqli의 타이밍 폴백에서 사용하는 타이밍 쌍 수입니다.
--confirm-sqlicheck활성 SQLi 확인 페이로드도 전송합니다.
--presetreadfingerprint 또는 users.
--techniquereadauto(기본값), union(인밴드, 가짜 포스트를 위조), error(인밴드, DB 오류 표시 필요), blind 중 하나입니다.
--queryread읽을 스칼라 SQL 표현식입니다.
--prefixread데이터베이스 테이블 접두사(기본값 wp_).
--max-length Nread값당 읽을 최대 문자 수(기본값 128).
--user / --passwordshell선택적 관리자 자격 증명. 둘 다 생략하면 사전 인증 브리지를 사용합니다.
--cmdshell실행할 명령(-i 사용 시 생략).
-i / --interactiveshell배포 후 대화형 셸을 엽니다.