1. CVE-2024-6028이란?
CVE ID: CVE-2024-6028
CVSS 심각도 점수: 9.8
영향을 받는 버전: ≤ 6.5.8.3
WordPress용 Quiz Maker 플러그인은 사용자가 제공한 매개변수에서 이스케이프가 충분하지 않고 기존 SQL 쿼리에 대한 준비가 충분하지 않아 6.5.8.3 이전 모든 버전에서 ‘ays_questions’ 매개변수를 통한 시간 기반 SQL 주입에 취약하다. 이를 통해 인증되지 않은 공격자가 기존 쿼리에 추가 SQL 쿼리를 추가하여 데이터베이스에서 민감한 정보를 추출할 수 있다.
2. 환경구축
XAMPP 3.3.0, Wordpress 6.6.2, Quiz Maker for Wordpress 6.5.8.3
Quiz Maker 플러그인을 활성화 후, 간단한 수학 퀴즈를 작성한다.
작성된 퀴즈의 Shortcode를 이용해 글을 배포해 준다.
3. 분석
우선 ‘ays_questions’ 매개변수를 통해 sql 인젝션이 가능하므로 해당 부분을 찾아보면
class-quiz-maker-public.php에서 찾을 수 있다.
‘ays_questions’ 매개변수에 관련된 sql문과 취약한 부분을 찾아보면
//4982라인
$questions_answers = (isset($_REQUEST["ays_questions"])) ? Quiz_Maker_Admin::recursive_sanitize_text_field( $_REQUEST['ays_questions'] ) : array();
//5130~5141라인
if (is_array($questions_answers)) {
$quests = array();
$questions_cats = array();
$quiz_questions_ids = array();
$question_bank_by_categories1 = array();
foreach($questions_answers as $key => $val){
$question_id = explode('-', $key)[2];
$quiz_questions_ids[] = strval($question_id);
}
$questions_categories = $this->get_questions_categories( implode( ',', $quiz_questions_ids ) );
// ......
//6902~6923라인
public static function get_questions_categories($q_ids){
global $wpdb;
if($q_ids == ''){
return array();
}
$sql = "SELECT DISTINCT c.id, c.title
FROM {$wpdb->prefix}aysquiz_categories c
JOIN {$wpdb->prefix}aysquiz_questions q
ON c.id = q.category_id
WHERE q.id IN ({$q_ids})";
$result = $wpdb->get_results($sql, 'ARRAY_A');
error_log($sql);
$cats = array();
foreach($result as $res){
$cats[$res['id']] = $res['title'];
}
return $cats;
}
$questions_answers 초기화 부분을 보면 Quiz_Maker_Admin::recursive_sanitize_text_field로 필터링되어 있다.
recursive_sanitize_text_field함수는 아래와 같이 정의되어 있다.
public static function recursive_sanitize_text_field($array) {
foreach ( $array as $key => &$value ) {
if ( is_array( $value ) ) {
$value = self::recursive_sanitize_text_field($value);
} else {
$value = sanitize_text_field( $value );
}
}
return $array;
}
하지만 태그(<,>)나 인코딩 문자 개행 및 탭문자를 필터링할 뿐 다른 특수 문자를 필터링하지 않으므로 sql에 취약하다.
위 사진은 문제를 다 풀고 finish 버튼을 누른 패킷을 잡아 파라미터들을 확인해 본 것이다.
파라미터 중 취약점이 있는 ays_questions파라미터를 확인할 수 있으며
5136번 라인의 $question_id 초기화 부분은 ays_questions파라미터 형식을 보면 이해할 수 있다.
ays_questions파라미터는 ays_questions[ays-question-1]=3 값으로 전달되고 배열 형식으로 작성된다.
$question_id는 $questions_answers 즉, ays_questions의 키 값을 -를 기준으로 추출한 3번째 요소로 초기화된다.
현재 사진에서는 ays-question-1 → 1이 된다.
4. POC
이제 sql 문의 형식을 log를 이용해 살펴보면 $q_ids 즉, $question_id가 IN 연산자 뒤에 들어가는 걸 확인할 수 있다.
그러면 $question_id를 이용해 sql 뒤에 악성 쿼리를 삽입이 가능하다.
$question_id값에 1)+or+sleep(5 을 넣어보면
sleep함수가 정상적으로 들어가는 걸 확인할 수 있다.
5. 패치
$sql = $wpdb->prepare(
"SELECT DISTINCT c.id, c.title
FROM {$wpdb->prefix}aysquiz_categories c
JOIN {$wpdb->prefix}aysquiz_questions q
ON c.id = q.category_id
WHERE q.id IN ( $in_pholders )",
array( ...$in_values )
);
6.5.8.4 버전 이후부터는 sql문이 prepare 함수로 sql 인젝션을 방지하게 패치되었다.
'One-day 취약점 분석' 카테고리의 다른 글
[CVE-2024-56017] One-day 취약점 분석 (1) | 2025.01.06 |
---|---|
[CVE-2024-5324] One-day 취약점 분석 (0) | 2024.12.22 |
[CVE-2023-4596] One-day 취약점 분석 (0) | 2024.12.07 |
[CVE-2024-8236] One-day 취약점 분석 (0) | 2024.12.03 |
[CVE-2024-38687] One-day 취약점 분석 (0) | 2024.11.23 |