⬆️File Upload Vulnerability (with 대응 방안)

DATE : 2024/2/15

File Upload Vulnerability

파일 업로드 취약점이란!

공격자가 원하는 임의의 파일을 업로드할 수 있는 취약점을 말한다.

대게 파일 업로드 공격이라 하면 web shell을 의미하는 경우가 많아서

서버 측에서 실행 가능한 파일을 업로드할 수 있는 취약점이라 표현할 수도 있다.

Web Shell은 말 그대로 웹 상에서 서버에 명령을 내릴 수 있도록 해주는 인터페이스와 같은 역할인데

이 Web Shell을 활용하기 위해서는 결과적으로 파일이 업로드 된 경로를 알아야 한다는 조건이 따른다.

예를 들어, 아래와 같은 shell.php 파일을 업로드 했다고 가정해보자.

<?php system($_GET['cmd'])?>

우리는 Web Shell로 사용하기 위해 위의 코드를 서버에 업로드한 것이고

이 코드를 실제로 실행하기 위해서는 해당 파일을 요청할 때 cmd parameter로 명령어를 전달할 것이다.

그렇다는 건, 이 파일이 웹 상에 위치한 경로를 알고 있어야 한다는 의미가 된다.

만약 정확한 경로를 알지 못한다면 파일을 업로드 했더라도

~~~~~~/shell.php?cmd=pwd

명령을 내릴 수 없기 때문에 무용지물이라 할 수 있다..!

이런 부분을 고려해 파일 업로드 공격을 막기 위한 대응책 중 하나로

"파일 이름을 난독화 하자!"는 아이디어를 제시할 수 있을 것이다.

"파일 경로를 정확히 모르면 어차피 실행을 못하잖아!" 라는 취지에서

shell.php -> dlrjsdkanehahffmfvkdlfdlfma.php

사용자가 업로드 하는 파일의 이름을 요상-하게 만들어서 부여하자는 것이다.

자! 이러면 문제 해결! 끗! 이라 하면 안 된다. 😏

파일 이름을 난독화 하는 방법은 사용자가 업로드 한 파일 이름을 사용자가 모르기 때문에

요청을 못 하게 만드는 효과가 있을지는 몰라도

각 파일이 어떤 이름을 부여 받았는지 알고 있는 DB를 공격할 수 있든지(sql injection)

혹은 파일 경로가 노출될 수 있는 다른 취약점이 존재한다면 업로드 한 파일을 실행시킬 수 있기 때문에

이는 조건부 대응 방안이라 할 수 있다.

이와 비슷하게 아래와 같은 경우에는 생각보다 쉽게 대응책이 우회 당할 수 있다..! 🙀

(1) Content-type header로 필터링 하는 경우

: 허용되는 파일 값으로 변조하게 packet을 전달하면 우회 가능

(2) File Signature를 확인하는 경우

: file 맨 첫 부분에 허용되는 파일의 signature를 넣어주면 우회 가능

(3) File extension을 확인하는 경우

: double extension으로 우회 (ex. shell.jpg.php)

: NULL Byte Injection으로 우회 (ex. shell.php%00.jpg)

: 대소문자를 섞어 사용해서 우회 (ex. php -> pHp, phP)

: alternative extension 사용해서 우회 (ex. jsp -> jspx, jpw)

그렇다 보니 최후의 방법으로 이미지 파일 안에 PHP code를 넣고 PHP 확장자로

파일을 업로드하는 경우가 있는데, 이때 중요한 건 확장자가 PHP 라는 것이다.

우리는 파일을 업로드해서 서버가 실행하도록 만들어야 하기 때문에 확장자가 이미지 유형이라면

의미가 없다.

"흠... 아닌데요? 저 jpg 파일로 web shell 실행하는 거 봤는데요?" 라고 말하는 사람을 위해 더 설명하자면

shell.php.jpg

위의 파일을 업로드해서 web shell을 실행했다고 한다면 이는 php.jpg 자체를 php로 인식해서 처리하도록

서버에 설정을 해둔 게 아닌 이상 불가능하다.

예시와 같이 Double extension을 사용해서 우회할 수 있는 건,

개발한 사람이 " . "을 기준으로 분리했을 때 처음에 위치한 값으로 확장자 필터링을 하는 경우이다.

또한 이 경우에도 shell.php.jpg가 아닌 shell.jpg.php 이어야 우회가 될 것이다.

아니면 NULL Byte를 중간에 끼워 넣어서 업로드 하기 위해 검사하는 과정에서는

shell.php%00.jpg => shell.php

jpg로 인식하고 업로드할 때는 NULL Byte 앞에서 끊겨서 php 파일로 올라가는 경우면 가능할 지 몰라도

그냥 마냥 "jpg 파일로 Web Shell 실행하는 데욥." 이라 하는 건 말이 안 된다.

이렇게 단호하게 말함에도 불구하고 "아닌데요 아닌데요 jpg로 진짜 파일 업로드 공격한다니까요" 라고!

말하고 싶다면 지금 당장 Web Shell 3여기로 가보시길. 😏


File Upload 대응 방안

앞서 나열해본 (1) ~ (3)번의 경우, 우회 방법이 존재하는데..

어떻게 해야 File Upload 공격에 대응할 수 있다는 말인가!!

File Upload 공격을 막기 위한 첫 번째 방법은 "파일을 DB에 저장"하는 것이다.

파일 업로드 공격이 가능한 원천적인 이유를 생각해보면 파일을 서버에 업로드해서 실행되기 때문!

그러니까 실행될 여지가 없도록 DB에 파일을 넣자는 것이다.

(BLOB / CLOB 파일 형식을 이용하면 DB에 파일을 저장할 수 있다.)

File Upload 공격을 막기 위한 두 번째 방법은 "NAS라는 파일 저장 서버를 따로 이용"하는 것이다.

동적 페이지를 처리할 때 WEB server에 연결된 WAS가 동작하는 거 처럼

WEB - WAS - DB

WEB - NAS

NAS server를 연결해 파일을 관리하는 친구를 따로 두자는 얘기이다.

이때 중요한 건, NAS에는 WAS server처럼 서버 측 코드를 실행할 수 있는 환경이 구축되면 안 된다.

파일이 실행되지 않도록 따로 관리하고자 하는 게 목적인데

코드를 실행할 수 있는 환경이 만들어져 버리면 NAS를 사용하는 의미가 없어진다!!

이렇게 크게 두 가지 방법을 통해 우리는 File Upload 공격에 대응할 수 있다.

File Upload는 서버에서 실행될 수 있는 파일을 실행되지 못하도록 만드는 게 대응 방안이 될 수 있기 때문에

파일이 실행되지 못하는 환경(DB & NAS)을 활용함으로써 공격을 예방할 수 있다는 말씀 되시겠다! 😆

Last updated