
CVE-2025-68999용 PoC 익스플로잇 - Happy Addons for Elementor <= 3.20.4의 2차 SQL 인젝션
| CVSS | 8.5 높음 |
| Affected | <= 3.20.4 |
| Patched | 3.20.6 |
| Min. role | 기여자 (edit_posts) |
| Vector | 네트워크 / 낮은 복잡도 / 낮은 권한 |
classes/clone-handler.php의 duplicate_meta_entries()는 수동으로 작성된 대량 INSERT를 사용하여 포스트 메타 행을 복제된 포스트로 복사합니다. 이 함수는 $wpdb->prepare()로 행을 안전하게 가져오지만, 그 후에 $entry->meta_key를 이스케이프 처리 없이 SQL 문자열에 바로 넣습니다:
$_records[] = "( $duplicated_post_id, '{$entry->meta_key}', '{$_value}' )";
// ...
$wpdb->query( $query );
meta_key가 데이터베이스에서 오기 때문에 코드는 이를 신뢰된 값으로 취급합니다. 하지만 기여자는 사용자 정의 필드 패널을 통해 임의의 필드 이름을 설정할 수 있으므로 해당 열의 내용을 제어할 수 있습니다.
공격은 두 단계로 이루어집니다:
add_post_meta()는 이를 안전하게 처리하므로 페이로드는 아무 것도 실행되지 않은 채 데이터베이스에 저장됩니다.duplicate_meta_entries()가 키를 다시 읽어 원시 INSERT에 연결합니다. MySQL은 주입된 하위 쿼리를 실행합니다.정적 분석은 이 취약점을 놓칩니다. 위험한 데이터의 출처가 DB 읽기($wpdb->get_results())이고, 오염 엔진(taint engine)은 이를 살균된 것으로 표시하기 때문입니다. 저장 경계가 오염 체인을 끊습니다.
모든 기여자는 다음을 추출할 수 있습니다:
wp_options의 모든 행 (API 키, 결제 자격 증명)공개 시점에 40만 개 이상의 활성 설치가 영향을 받았습니다.
pip install requests
python3 poc.py https://target.com contributor p4ss
이 스크립트는 HTTP로 인증하고, 주입 페이로드를 사용자 정의 필드 이름으로 저장한 다음, Happy Clone 작업을 트리거하고, 복제된 포스트의 메타 필드에서 유출된 해시를 읽습니다. 출력은 hash.txt에 저장됩니다.
hashcat -m 400 hash.txt rockyou.txt
| 날짜 | 이벤트 |
|---|---|
| 2025년 12월 | SVN diff를 통해 발견. PoC 확인. |
| 2025년 12월 | 전체 라이트업과 PoC와 함께 Patchstack Alliance에 보고. |
| 2026년 1월 | weDevs가 v3.20.6에서 수정 사항을 배포. |
| 2026년 1월 23일 | CVE-2025-68999 게시. CVSS 8.5 높음 배정. |
weDevs는 수동으로 작성된 전체 INSERT를 다음 코드로 교체했습니다:
foreach ( $entries as $entry ) {
update_post_meta( $duplicated_post_id, $entry->meta_key, $entry->meta_value );
}
update_post_meta()는 내부적으로 키와 값 모두에 대해 준비된 명령문(prepared statements)을 사용하여 $wpdb->update()를 호출합니다.