File Upload_(2)_double_extension

HackBeom·2022년 10월 24일
0

이번에는 필터링된 코드들을 하나씩 우회하여 웹쉘을 업로드 해 보겠다.


일반 파일 확장자인 .php를 업로드 하려고 시도 하면


txt or png 파일만을 업로드가 가능하다고 한다.
그렇다면 소스코드를 보자

<?php
$myfile_save_dir = 'upload/';
if($_FILES['fileToUpload']['size'] >= 1024 * 1024 * 1){ exit("<script>alert(`file is too big`);history.go(-1);</script>"); } // file size limit(1MB). do not remove it.

?>

우선 코드를 해석하기 위해 나눠서 보면
1. 파일이 업로드 될 장소 or 디렉토리 or 폴더
2. 파일 크기가 너무 크지 않도록 크기제한 설정

<?php
	$extension = explode(".",$_FILES['fileToUpload']['name'])[1];
if($extension == "txt" || $extension == "png"){
    echo $_FILES[ 'myfile' ][ 'type' ];
    move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $myfile_save_dir . $_FILES['fileToUpload']['name']);
    exit("<script>alert(`upload ok`);location.href=`file.php`;</script>");
}
else{
    exit("<script>alert(`txt or png only`);history.go(-1);</script>");
?>

explode 함수로 인하여 .을 구분자로 1번째에 있는 값을 extension변수에 넣겠다. (할당하겠다)
즉 filename.txt 라면 txt가 extension 변수에 들어가게 된다.
그 후 extension 변수에 있는 값이 txt or png 면 업로드가 진행 아니라면 스크립트 출력으로
해석된다.

.을 구분자로 1번째에 있는 값이라고 하면
[0].[1] 이라면 [파일이름].[확장자] 이런식이다.
여기서 이중확장자를 사용하면 [0].[1].[2] => [webshell].[txt].[php]라고 할 수 있고 해당 파일이 위 검증 로직에서는 [1]째 값을 가져가기 때문에 txt라고 해석되어 정상적으로 업로드가 되지만
뒤에있는 확장자 php는 검증하지 않기 때문에 webshell이 동작하게 되어 취약점이 발생한다.

아래는 실습과정이다.


일반적인 webshell.php는 검증로직 때문에 업로드가 가능하지 않는다.


이중 확장자로 업로드를 할 경우

업로드가 정상적으로 진행이 되었고

웹 쉘이 정상적으로 동작이 된다.
해당 취약점이 터지는 이중확장자를 필터링 한다고 가정하고 시큐어코딩을 해 보면

<?php
$myfile_save_dir = 'upload/';
if($_FILES['fileToUpload']['size'] >= 1024 * 1024 * 1){ exit("<script>alert(`file is too big`);history.go(-1);</script>"); }

$file_path = pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION);
$allow_extension = array("txt", "png");
if(in_array($file_path, $allow_extension)){
    echo $_FILES[ 'myfile' ][ 'type' ];
    move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $myfile_save_dir . $_FILES['fileToUpload']['name']);
    exit("<script>alert(`upload ok`);location.href=`file.php`;</script>");
}
else{
    exit("<script>alert(`txt or png only`);history.go(-1);</script>");

}
?>

위와 같이 필터링이 가능하다.

0개의 댓글