이 문서에 포함된 어떠한 내용도 불법적이거나 비윤리적인 목적으로 보안 도구나 방법론을 사용하도록 가르치거나 장려하지 않습니다. 항상 책임감 있는 태도로 행동하세요. 여기에 설명된 도구나 기법을 사용하기 전에 개인 테스트 환경 또는 허가를 받았는지 확인하세요. |
[ 환경 ]
DVWA | v1.9 |
Burp Suite | Community Edition v2024.11.2 |
$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' ];
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
확장자 검증만으로는 불충분
MIME 타입 검증 부족
업로드 디렉토리 보호 부족
Midium level에서 진행했던것 처럼 Content-Type을 image/jpeg로 변경해서 전송하는 경우 소스코드에서 확인하였듯이 아래 조건이 아니기 때문에 [그림 2]와 같이 차단되는것을 확인할 수 있다.
High level에서는 getimagesize( )를 사용하여 파일이 실제로 이미지인지 확인하고 있다. getimagesize( )는 PHP에서 제공하는 함수로, 이미지 파일의 크기와 속성에 대한 정보를 가져오는 데 사용된다. 이 함수는 이미지를 읽고 그 파일의 기본적인 속성을 반환하므로 이미지 파일 처리나 검증 작업에 유용하다.
함수 정의
array getimagesize(string $filename, array &$image_info = null)
반환되는 배열 정보
getimagesize()가 반환하는 배열은 다음과 같은 정보를 포함한다.
인덱스 | 설명 |
0 | 이미지의 너비 (픽셀 단위) |
1 | 이미지의 높이 (픽셀 단위) |
2 | 이미지의 MIME 타입을 나타내는 정수값 |
3 | MTML에서 사용할 수 있는 width와 height 속성 문자열 |
mime | 이미지의 MIME 타입 (예: imge/jpeg) |
MIME 타입 값 ($imageInfo[2])
getimagesize()는 이미지 타입을 정수로 반환하며, 주요 값은 다음과 같다.
값 | 타입 |
1 | GIF |
2 | JPEG |
3 | PNG |
4 | SWF |
5 | PSD |
6 | BMP |
7 | TIFF (기본) |
8 | TIFF (모서리) |
9 | JPC |
10 | JP2 |
11 | JPX |
12 | JB2 |
13 | SWC |
14 | IFF |
15 | WBMP |
16 | XBM |
getimagesize( )는 이미지와 관련된 정보를 쉽게 얻을 수 있는 강력한 도구이면서 이미지 검증과 관리에 필수적으지만, 완벽한 보안 대책은 아니다. 이를 우회하기 위해 Burp Suite로 Intercept 하여 다음과 같이 변경한다.
ㅁ filename="simple-php-web-shell.php.jpeg" ㅁ Content-Type: image/jpeg ㅁ HTTP Body 시작 부분에 GIF 파일 시그니처 GIF89a 추가 |
이렇게 변경 후 전송하면 파일 확장자 검증 부분에서 마지막 .을 기준으로 오른쪽의 내용을 확장자로 가져와서 검증하기 때문에 허용 확장자명인 jpeg가된다. 여기서 주의할점은 확장자만 변경한다고, 이미지 파일로 인식하지 않는다. 그렇기 때문에 HTTP Body 시작점에 GIF 이미지의 Signature를 입력하여, 이미지라고 인식시켜 검증을 우회할 수있다.
업로드된 경로에 접근해보면, WebShell은 PHP이나 업로드 당시 파일 Signature를 GIF로 변경하였기 때문에 PHP가 실행되는게 아니라 이미지가 출력된다.
이상태에서는 WebShell을 실행 시킬 수 없기 때문에 다른 취약점과 연계해야 한다. 사용할 취약점은 File Inclusion이다. 업로드된 WebShell의 확장자가 .jpeg 이미지 파일이라도 코드는 Shell 코드 이기 때문에 File Inclusion 취약점을 이용하면 WebShell을 실행시킬 수 있다. File Inclusion을 클릭 후 PHP Wrapper의 파일 시스템(file://)를 이용하여 WebShell의 전체 경로를 입력하면, [그림 6]과 같이 WebShell을 실행 시킬 수 있다.
DVWA : SQL Injection - Low level (0) | 2025.01.05 |
---|---|
DVWA : File Upload - Impossible level (0) | 2025.01.05 |
DVWA : File Upload - Medium level (0) | 2025.01.05 |
DVWA : File Upload - Low level (0) | 2025.01.05 |
DVWA : File Inclusion - Impossible level (0) | 2025.01.04 |