Post

[CVE-2024-48029] 취약점 분석 보고서

CVE-2024-48029 WordPress의 SB Random Posts Widget 플러그인에서 파일 이름 필터링 부재로 인한 LFI 취약점

1. CVE-2024-48029란?

CVE ID: CVE-2024-48029
CVSS 심각도 점수: 7.2
영향을 받는 버전: ≤ 1.0

SB Random Posts Widget에서 Simple Random Posts 위젯에서 발생한 해당 취약점은 include문에 대한 파일 이름의 필터링이 없어 발생되는 LFI 취약점으로 서버의 모든 php파일에 접근 할 수 있다.

CVE-2024-48029

2. 환경 구축

XAMPP 3.3.0, Wordpress 6.6.2, SB Random Posts Widget 1.0

해당 플러그인 설치 후, 활성화

image.png

3. 분석

해당 플러그인은 글, 페이지, 템플릿 등을 모아서 포스트 해주는 위젯을 가지고 있다.

1
2
3
4
5
6
7
8
9
10
// classes.php 
if ( $q->have_posts() ) :
	echo '<div class="random-posts '.$atts['type'].'"><ul>';
	while ( $q->have_posts() ) :
		$q->the_post();
		include dirname(__FILE__) . '/parts/shortcode-content-'.$atts['type'].'.php';
	endwhile;
	wp_reset_query();
	echo '</ul></div>';
endif;

이때 글, 페이지, 템플릿을 이름과 이미지를 가져오는 php파일을 include 하는데 그 기능에 파일 이름을 처리하는 과정에서 필터링이 없이 문자열로 가져오게 된다.

include dirname(__FILE__) . ‘/parts/shortcode-content-‘.$atts[‘type’].’.php’;

dirname(__FILE__) → 현재 디렉토리 경로

즉, 현재 디렉토리의 /parts/shortcode-content-‘.$atts[‘type’].’.php 파일을 불러오는 것.

$atts[‘type’]에 따라 불러오는 파일이 달라짐

불러오는 파일 목록

image.png

$atts[’type’]값은 위젯 layout 파라미터에서 가져온다.

image.png

4. POC

위 취약점 테스트를 위해 해당 플러그인 폴더 안에 secret.php라는 간단한 테스트용 php파일을 만들었다.

image.png

그 후, 해당 글의 공개 패킷을 잡아보면

image.png

layout 파라미터에 image_text라고 적혀 있는 걸 확인할 수 있다.

image.png

layout 파라미터 값을 /../../secret이라 작성하면

include dirname(__FILE__) . ‘/parts/shortcode-content-/../../secret.php’; 가 입력되게 되고

블로그에는 해당 파일 내용이 포스팅된다.

image.png

이로써 서버에 있는 모든 php파일에 접근이 가능한 취약점을 확인 하였다.

5. 패치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$item_file = sanitize_file_name( 'shortcode-content-'. $atts['type'] .'.php' );
	$view_file = dirname(__FILE__) . '/parts/' . $item_file;
	 	       
	if ( ! file_exists ( $view_file ) ) {
	 	  $view_file = dirname(__FILE__) . '/parts/shortcode-content-image_only.php';
	}
	
    if ( $q->have_posts() ) :
		echo '<div class="random-posts'.$atts['type'].'"><ul>';
		while ( $q->have_posts() ) :
			$q->the_post();
			include dirname(__FILE__) .'/parts/' . $view_file;
		endwhile;
		wp_reset_query();
		echo '</ul></div>';
    endif;

패치로 인해 1.1 버전부터는 sanitize_file_name 함수를 이용해 필터링을 하게 되었다.

This post is licensed under CC BY 4.0 by the author.