
Piotnet Forms Pro <= 2.1.40 - 인증되지 않은 임의 파일 업로드 → RCE
이 취약점은 piotnetforms_ajax_form_builder 함수의 부적절한 파일 유형 검증에서 비롯됩니다. 이 플러그인은 php, phpt, php5, php7, exe만 차단하는 불완전한 확장자 블랙리스트를 사용하며, .phtml 또는 .phar와 같은 위험한 대안을 허용합니다.
AJAX 핸들러는 인증 요구 사항 없이 등록됩니다:
// inc/forms/ajax-form-builder.php:9-10
add_action( 'wp_ajax_piotnetforms_ajax_form_builder', 'piotnetforms_ajax_form_builder' );
add_action( 'wp_ajax_nopriv_piotnetforms_ajax_form_builder', 'piotnetforms_ajax_form_builder' );
파일 검증은 MIME 유형이나 매직 바이트 검증 없이 불완전한 확장자 블랙리스트에만 의존합니다:
// inc/forms/ajax-form-builder.php:678-688
$not_allowed_extensions = [ 'php', 'phpt', 'php5', 'php7', 'exe' ];
$file_extension = pathinfo( $file_name_san, PATHINFO_EXTENSION );
if ( in_array( strtolower( $file_extension ), $not_allowed_extensions ) ) {
wp_die();
}
// .phar, .phtml, .php8, .pht, etc. all pass through freely
move_uploaded_file( $file['tmp_name'][$i], $new_file );
업로드 디렉터리에는 디렉터리 목록 노출을 방지하기 위한 빈 index.html만 있으며, PHP 실행을 차단하는 .htaccess는 없습니다. 업로드된 파일은 공개적으로 접근 가능한 다음 위치에 저장됩니다:
/wp-content/uploads/piotnetforms/files/{filename}-{uniqid}.{ext}
파일 URL은 piotnetforms_export_form_submission AJAX 액션(역시 nopriv)을 통해 인증 없이 조회할 수 있어, 완전한 인증되지 않은 RCE 체인이 완성됩니다.
이는 CVE-2026-4885에 존재하는 것과 동일한 복사-붙여넣기 버그입니다 — 두 플러그인 모두 동일한 개발자의 동일한 취약한 업로드 처리 코드를 공유합니다.
대화형 모드:
python3 shadow.py
단일 대상:
python3 shadow.py -u https://target.com
python3 shadow.py -u https://target.com -s shadow.phtml
대량 스캔:
python3 shadow.py -f targets.txt -t 20
python3 shadow.py -f targets.txt -t 20 -s shadow.phtml
CLI 옵션:
-u, --url - 대상 URL-f, --file - 대상 파일 (줄당 하나)-s, --shell - 사용자 지정 PHP 셸 (GIF89a 자동 앞에 추가됨)-t, --threads - 동시 스레드 수 (기본값: 5)-h, --help - 도움말 표시piotnetforms_export_form_submission(인증 없음)을 통한 URL 유출shell.txt에 저장.php .phpt .php5 .php7 .exe
우회 확장자: .phtml .phar .shtml .php8
pip install httpx
이 도구는 공인된 보안 테스트 및 교육 목적으로만 사용됩니다. 허가되지 않은 시스템 테스트는 금지됩니다.