파일 업로드 취약점


파일 업로드 기능을 악용하여 시스템 권한을 획득할 수 있는 취약점을 의미한다. 웹쉘을 업로드하여 시스템의 권한을 장악할 수 있게 된다.

웹쉘
웹 사이트의 파일 업로드 기능을 이용하여 인가 받지 않은 파일을 서버에 임의로 업로드 하는 공격이다. 주로 파일의 형식은 .asp, .php, .jsp과 같으며 이를 웹셀이라고 한다. 이러한 악성 스크립트를 올려 실행시킨 후, 웹 서버를 장악하고 피해를 주는 행위이다.


파일 업로드 취약점 진행 과정

  1. 임의의 확장자를 가진 파일 업로드
  2. 확장자 체크가 미흡하고 업로드한 파일 경로가 노출되는지 확인
  3. 악의적인 스크립트 업로드
  4. 파일 업로드 경로에 URL로 접근하여 웹쉘이 실행되는지 확인

예방법

  • 확장자 필터링을 거치도록 해야 한다.
  • 확장자 필터링은 항상 웹 서버측에서 진행되어야 한다. 프록시를 이용한 소스코드 조작으로 악의적인 스크립트 파일을 업로드할 수 있기 때문이다.
    프록시를 이용한 소스코드 조작 예제
  • Document Root 이하에서 직접 접근할 수 있는 경로로 업로드 되지 않도록 구현한다. 실제 링크가 공개되지 않더라도 추측에 의해서 접근할 수 있게 된다.
  • 의미없는 확장자를 부여할 필요가 있다. (아니면 아예 업로드하지 못하도록 제한해야 한다.)
  • 저장 시 중복되지 않을만한 랜덤한 파일명으로 치환하고 클라이언트가 제공한 파일명은 별도로 보관해야 한다.
  • 업로드 되는 파일 사이즈를 체크할 필요가 있다. 그렇지 않으면 저장 장치가 가득 차서 서버가 뻗을 수도 있다.
  • 인가된 사용자에게만 업로드 허용해야 한다.
  • 한 번에 올릴 수 있는 파일 수 제한
  • Permission 제한
  • 주기적으로 업로드한 파일을 대상으로 바이러스 검사를 한다.
  • 헤더 지정
    • Content-disposition 지정 : attachment 헤더를 지정하여 브라우저로 하여금 실행 외의 파일저장이 실행되도록 유도
    • Content-type 지정 : 다운로드 후 의도하지 않는 연결 프로그램이 실행되는 것을 방지



+ 확장자만 검사하는 것이 아닌, Mime-Type 또한 검사하는 과정이 필요하다.

Mime-Type
Mime은 다목적 인터넷 메일 확장이라는 뜻으로 전자우편의 데이터 형식을 정의한 표준 포맷이다. 이는 전자우편에서 사용하기 위해 등장했지만 지금은 HTTP 통신에서 전송 데이터를 표현하기 위해서도 사용하고 있다.


Java의 Mime-Type을 검사하는 라이브러리로 Apache Tika가 있다. 이는 파일의 메타 데이터와 텍스트 등을 탐지하고 추출하는데 사용되는 라이브러리다. Tika 라이브러리는 확장자가 아닌 실제 파일의 내용을 검사하여 Mime-Type을 판단하고, 파일이 존재하지 않으면 FileNotFouneException을 발생시킨다.




+ Spring Boot의 MultipartFile에서는?
Spring Boot의 MuptipartFile 또한 실제 파일의 내용을 검사하여 Mime-Type을 검사하는 것 같다.


아래와 같이 텍스트 파일을 만들고



확장자를 JPG로 바꾸어보았다.



Mime-Type을 추출할 때 file.getContentType(), 파일 확장자를 추출할 때 FilenameUtils.getExtension(file.getOriginalFilename()) 을 사용하고 출력해봤을 때...


Mime-Type 및 파일 확장자를 제대로 추출하는 것을 확인할 수 있었다.






파일 다운로드 취약점

파일 다운로드 시 경로 및 파일 명을 처리하는 경우 이를 제대로 필터링하지 않았을 때 허용되지 않은 파일을 다운받을 수 있고 임의의 위치에 있는 파일을 열람하거나 다운받는 것을 가능하도록 하는 취약점이다.


파일 다운로드를 할 수 있도록 하는

첨부 파일을 사용자에게 제공하는 방식

Dynamic 방식

URL 파라미터에 파일 이름 혹은 파일 번호를 할당하여 데이터를 처리하는 방식
ex) ... /photo?fileName=temp.png
파라미터 변조를 통해 서버의 시스템 파일 혹은 프로그램 소스에 접근할 수 있는 가능성을 가져 보안상 매우 위험하다.

Static 방식

특정 디렉터리에 파일 링크를 걸어 사용자에게 제공하는 방식
ex ) ... /photo/temp.png
파라미터 정보를 가지고 있지 않아 변조할 수 없는 안전한 구조이다.



NULL Byte Injection

NULL Byte 문자열은 문자열의 끝을 의미하기 때문에 특정 확장자를 숨기기 위한 목적으로 사용할 수 있다.


웹 서버에서 파일을 저장할 때 %00가 포함된 뒷 문자열은 null로 인식되는 것을 악용하는 방식이다. 업로드를 허용하는 확장자를 알고 있다면 해당 방식을 사용할 때 허용하는 확장자와 원하는 확장자 사이에 %00을 이용해 업로드를 시도한다.



예방법

  • 다운로드 파일의 이름을 데이터베이스에 저장하고 다운로드 수행 시 요청 파일의 이름이 동일한지를 검증하도록 한다.
  • 홈페이지 상에 다운로드 파일 명 또는 경로에 "..", "/", "\" 값이 입력되지 않도록 조치







Reference
[보안] 파일 업로드 취약점
웹 개발을 위해 꼭 알아야하는 보안 공격
[시큐어 코딩] #5 위험한 형식 파일 업로드
웹 파일 업로드 보안 취약점

profile
Coding Duck

0개의 댓글