저번 시간에 파일 업로드 취약점에 대해 알아보았습니다.
파일 업로드 취약점은 공격자가 임의의 파일을 업로드할 수 있는 공격입니다.
보통 웹쉘 파일을 업로드하여 서버에 원하는 명령을 내릴 수 있게합니다.
그리고 가장 중요한 것이 서버에서 실행을 할 수 있는 파일이어야 하며 공격자는 파일을 실행하기 위해서 해당 파일의 경로를 알고 있어야합니다.
저번 시간 마지막에 .jpg로 끝나는 파일은 절대 실행시킬 수 없다고 말했었습니다.
그렇기 때문에 webshell.php.jpg 파일을 업로드한다면 절대로 실행시킬 수 없습니다.
하지만 몇가지 특수한 상황에서 jpg 파일을 업로드 시 실행시킬 수 있는 방법이 있습니다.
아마, 인터넷에서 보신 jpg 파일 업로드로 웹쉘을 실행시키는 방법 중 하나일 것입니다.
1. webshell.jpg.php 파일 업로드
일단 당연히 webshell.jpg.php파일은 php파일이기 때문에 업로드만 성공한다면 실행이 가능합니다.
webshell.jpg가 파일이름이 되고 php가 확장자 명이 되는 것입니다.
2. null byte injection
이 방법은 webshell.php%00.jpg의 파일명으로 업로드하는 것인데 이 경우 파일명에 null을 추가하는 것입니다. 검색 시 .jpg로 끝나 정상적인 이미지 파일이라고 판단하여 검증을 통과하며, 파일 저장시 널 이후는 잘려 webshell.php 로 저장되게 됩니다.
업로드시 버프로 요청을 잡아 사진과 같이 webshell.php.jpg 에서 php뒤에 00으로 널바이트를 추가하여 전송합니다.
사진과 같이 업로드된 파일이 .jpg가 사라지고 webshell.php로 업로드된 것을 확인할 수 있습니다.
3. .htaccess 파일 사용
.htaccess 파일 같은 경우 해당 디렉토리에 대해 서버 설정을 정할 수 있습니다. 이 파일을 사용하여 jpg 확장자를 php로 실행하게 만들어서 jpg로 끝나는 파일을 php로 실행시킬 수 있습니다.
.htaccess 파일에 AddType application/x-httpd-php .jpg 라고 적은 다음에 해당 파일을 업로드하면 이제 이 파일이 있는 디렉토리는 jpg확장자를 php로 실행시킬 수 있습니다. 그렇기 때문에 이 경우는 꼭 jpg가 아니라도 어떠한 임의의 확장자도 원하는 방식으로 실행시킬 수 있습니다.
사진과 같이 .httaccess 파일을 업로드하면 .test 확장자는 php로 실행시킬 수 있습니다.
그러면 이렇게 꼭 jpg가 아니더라도 어떠한 확장자든 설정한대로 실행시킬 수 있습니다.
결론은 위의 특수한 경우가 아니라면 jpg 확장자 파일은 절대 실행시킬 수 없다는 것입니다.
그럼 이 파일 업로드 취약점에 대한 대응방안은 무엇일까요??
일단 파일을 실행가능한 서버에 저장하기 때문에 발생합니다. 그렇기 때문에 파일 자체를 데이터베이스에 저장하는 것이 가장 좋습니다.
CLOB / BLOB 타입을 지정하면 파일을 데이터베이스에 저장할 수 있습니다.
다른 파일 저장과 똑같이 해당 타입으로 지정해주고 업로드할 파일을 insert 해주면 저장할 수 있습니다.
아래와 같이 작성해주면 파일을 문자열로 읽어 저장할 수 있습니다.
$fileContent = file_get_contents($_FILES["file"]["tmp_name"]);
가져올 때도 마찬가지로 select 해주면 저장된 문자열 그대로 가져와 파일을 사용할 수 있습니다.
public static function getFile($idx) {
$db_conn = connectDb();
$query = "select file,filename from boards where idx=$idx";
$result = mysqli_query($db_conn, $query);
mysqli_close($db_conn);
return mysqli_fetch_assoc($result);
}
BLOB 타입에 14.8KB 용량으로 저장된 것을 확인할 수 있습니다.
require_once('models/board-model.php');
// 다운로드 파일 경로
$dir_path = "/var/www/html/";
// 파일명
$fileId = $_GET['file'];
$file = Board::getFile($fileId);
$file_name = $file['filename'];
$fileContent = $file['file'];
//file_exists($file_path)
if (isset($file_name)) {
header('Content-Description: File Transfer');
header("Content-Type:application/octet-stream");
header("Content-Disposition:attachment;filename={$file_name}");
header("Content-Transfer-Encoding:binary");
header("Content-Length:".strlen($fileContent));
header("Cache-Control:cache,must-revalidate");
header("Pragma: no-cache");
header("Expires:0");
ob_clean(); //출력 버퍼 제거
flush(); //출력 버퍼를 비우고 즉시 출력. 이를 클라이언트에게 전송. 전송지연최소화.
echo $fileContent;
마지막으로 위와 같이 코드를 작성하면 다운로드도 정상적으로 가능합니다.
이렇게 파일을 실행할 수 없는 다른 곳에 저장하는 것이 좋습니다.
이와 비슷하게 데이터베이스에 파일을 저장하는 방법말고 NAS를 사용하여 해당 언어로 된 파일을 처리할 수 없는 서버를 사용하여 파일을 저장하는 방법도 있습니다.
마지막으로 파일 업로드 취약점과 다른 파일을 사용한 취약점이 있는데 File Include 기능을 이용한 취약점입니다.
이것은 웹 개발시 중복되는 코드들을 include 기능을 사용하여 원하는 곳에 코드를 복사??하는 기능입니다.
여러번 중복되는 코드를 여러번 작성할 필요없이 한 파일에 코드를 저장하면 똑같은 코드를 어느 곳이든 include하면 해당 코드를 사용할 수 있습니다.
이때 사용자에게 입력을 받아 파일을 include할 경우 우리가 원하는 파일(웹쉘 파일)을 포함시켜 웹 쉘을 실행시키는 것입니다.
# 파일 업로드 기능이 없을 경우 log를 사용하여 원하는 코드 실행 가능
이런 공격이 있다는 것만 알고 다음에는 파일 다운로드 취약점을 알아보겠습니다.
'웹 해킹' 카테고리의 다른 글
웹 해킹 공부 일기장 12 - 1 (인증 취약점) (0) | 2024.02.22 |
---|---|
웹 해킹 공부 일기장 11 - 2 (파일 다운로드) (0) | 2024.02.19 |
웹 해킹 공부 일기장 10 - 1 (File Upload 취약점) (0) | 2024.02.08 |
웹 해킹 공부 일기장 9 - 1 (CSRF 정리) (0) | 2024.02.01 |
웹 해킹 공부 일기장 8 - 1 (CSRF) (0) | 2024.01.18 |