기준
취약점 설명
파일 업로드 기능이 존재하는 페이지에 서버의 웹 언어와 같은 확장자의 파일을 업로드하여 서버 내에서 업로드된 파일이 실행 가능할 경우 발생되는 취약점입니다.
허용되지 않아야 하는 확장자(.asp, .jsp, .php, .cgi 등)가 업로드되는 것도 안되지만 가장 위험한 것은 Server Side Script가 작성된 파일이 업로드되어 실행되는 것이 가장 위험한 부분입니다.
Server Side Script가 업로드되어 실행되면 공격자가 의도하는 대로 서버 내부에서 악성코드를 실행시킬 수 있는 공격(Remote Code Execution, RCE)도 가능하며 다양한 방식의 공격이 가능합니다.
서버 내에서 명령어를 실행시켜 정보를 확인하거나 서버의 내부 파일을 업/다운로드하는 방식으로 중요 정보가 포함된 파일을 탈취하거나 서버를 장악하는 방식으로 공격이 가능합니다.
공격 방법
(해당 취약점은 DVWA를 활용하여 실습해보도록 하겠습니다.)
1. Low Level
페이지의 형태는 파일을 업로드를 할 수 있도록 구성되어 있습니다.
소스 코드를 확인해보면 보안 조치가 되어있지 않은 것을 알 수 있습니다.
업로드한 파일이 'hackable/uploads/'에 업로드되는 것을 확인할 수 있습니다.
우선 업로드할 파일을 작성해보도록 하겠습니다.
업로드가 될 경우 command변수에 명령어를 삽입하여 실행시킬 수 있는 웹쉘입니다.
따로 구현된 필터링이 없기 때문에 정상적으로 등록되는 것을 알 수 있습니다.
업로드를 진행해보도록 하겠습니다.
정상적으로 업로드되고 파일이 업로드된 경로까지 노출되는 것을 확인할 수 있습니다.
해당 URL로 접근해보도록 하겠습니다.
업로드된 경로로 접근하여 command를 입력해보니 정상적으로 실행되는 것을 확인할 수 있습니다.
명령어를 입력하여 /etc/passwd 정보를 획득할 수도 있습니다.
2. Medium Level
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// Is it an image?
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
페이지의 형태는 전과 동일합니다.
소스 코드를 확인해보면 Low Level과는 달리 이미지파일만 업로드할 수 있는 것을 알 수 있습니다.
Low Level과 같은 방식으로 업로드해보면 업로드가 되지 않는 것을 확인할 수 있습니다.
확장자를 바꿔 업로드 과정 중 확장자를 바꾸는 방식으로 시도해보도록 하겠습니다.
Low Level에서 사용한 웹쉘 파일의 확장자를 바꿔 업로드를 시도하는 중 파라미터를 변조하는 방식으로 진행해보려 합니다.
위의 사진처럼 업로드되는 과정 중에 파일의 확장자를 php로 바꿔주었습니다.
정상적으로 업로드되는 것을 확인할 수 있습니다.
업로드된 파일의 확장자가 php로 보이지만 접근하여 바꿔준 확장자로 업로드됐는지 확인해보도록 하겠습니다.
파라미터를 변조하여 업로드한 파일의 업로드 시간이 서버의 시간과 같은 것을 확인할 수 있습니다.
3. High Level
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Is it an image?
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
페이지의 형태는 전과 동일한 것을 확인할 수 있습니다.
소스 코드를 확인해보면 전과 달리 보안 조치가 조금더 추가된 것을 확인할 수 있는데 허용된 파일은 jpg, jpeg, png이며 파일이 이미지 파일인 것을 확인하여 업로드하는 것을 알 수 있습니다.
전과 동일한 방식으로 업로드해봤지만 안되는 것을 확인할 수 있습니다.
파일 업로드 시에 파일의 확장자를 바꿔 업로드해야하는데 getimagesize()로 이미지 헤더를 검증하므로 GIF헤더(GIF89a)를 추가하여 검증을 우회하여 주었습니다.
또한 파일 업로드 시에 우회하는 방법을 사용해보았으나 우회가 되지 않아 마지막에 png를 넣어주어 업로드 시도하였습니다.
이에 덧붙여 High Level에서 되지는 않지만 종종 사용되는 확장자 우회방법을 몇가지말해보도록 하겠습니다.
확장자 우회 방법
1) 대소문자 치환 : jsp -> .Jsp, .jSp, .jsP, .JsP 등등
2) Null Byte : [파일이름].php%00.jpg, [파일이름].php%zz.jpg
(%00, %zz 뒤의 확장자가 null 처리되어 앞에 입력한 확장자로 업로드됩니다.)
3) 확장자 대체
asp -> cer, cdx, asa
jsp -> war, jspx, jsv, jsw
php -> php3, htm, html
본론으로 돌아와서 업로드된 파일을 확인해보도록 하겠습니다.
파일이 정상적으로 업로드된 것을 확인할 수 있습니다.
업로드된 파일에 명령어를 삽입해봤지만 업로드된 파일을 이미지 파일로 인식하여 명령어가 실행되지 않습니다.
이를 우회하여 실행하기 위해 File Inclusion 취약점을 활용하여 파일을 실행시켜보도록 하겠습니다.
File Inclusion 취약점이 존재하면 확장자가 php, jsp, asp가 아니더라도 실행할 수 있습니다.
확장자가 다르게 업로드되었지만 정상적으로 파일이 실행되어 명령어를 실행시킬 수 있습니다.
단, 입력 시에 'page=file/../../../hackable/uploads/rokefoke1.php.png&cmd=cat%20/etc/passwd'와 같이 &를 가운데에 삽입하여 명령어를 입력해주면 실행시킬 수 있습니다.