Web Hacking/Study

File Upload 취약점과 대응방안

박연준 2023. 7. 1. 23:06

파일 업로드 취약점(File Upload Vulnerabillity)이란?

파일 업로드 취약점은 웹 애플리케이션에 파일이 업로드되기 전에 유효성 검사가 구현되지 않았거나 안전하지 않은 방식으로 구현된 경우 악성 파일을 업로드할 수 있는 취약점이다. 이런 파일 업로드 기능이 취약하면 공격자는 웹셸과 같은 파일을 업로드하여 시스템 명령을 실행하거나 다른 시스템 공격을 위한 경유지로 악용하는 등의 서버측 공격을 할 수 있다. 또한 XSS 같은 클라이언트측의 공격도 가능하다.

파일 업로드 취약점의 동작 원리

사용자가 파일을 업로드된 파일은 어디가에 저장된다. 이 때 파일이 저장되는 위치는 개발자가 지정한 저장 공간이므로 웹 애플리케이션마다 다를 수 있다. 파일 업로드 취약점은 일반적으로 업로드 파일의 저장 위치가 웹 애플리케이션이 구동되는 서버와 동일한 서버인 경우 발생한다. 이런 경우 파일의 저장 위치는 서버의 웹 루트 디렉토리의 하위 디렉토리에 저장 되는 것이 일반적이다.

다음은 Ubuntu, Apache, PHP 기반 웹 애플리케이션의 간단한 디렉토리 구조이다.

root
 ├─ home/
 ├─ etc/
 │  ...
 ├─ sys/
 └─ var/
     └─ www/
         └── html/                     <== 웹 루트 (www.example.com)
              ├── uploaded/            <== 업로드된 파일의 저장 위치 (www.example.com/uploaded)
              │      ├── image1.jpg    <== 업로드된 이미지 파일 (www.example.com/uploaded/image1.jpg)
              │      └── image2.png
              ├── includes/
              │      ├── style.css
              │      └── script.js
              └── index.php
웹 루트 디렉토리는 도메인(www.example.com)과 대응된다. 따라서 URL을 통해서는 웹 루트 디렉토리와 그 하위 디렉토리로만 접근할 수 있으며 웹 루트 상위의 디렉토리 접근이 불가능합니다. 예로 든 이 구조에서 사용자는 웹 루트(/var/www/html) 디렉토리 하위의 index.php 파일 덕분에 도메인 주소(www.example.com)를 웹 브라우저에 입력하여 웹 애플리케이션을 방문할 수 있다. 또한 사용자가 웹 애플리케이션을 통해 업로드한 파일은 /var/www/html/uploaded 디렉토리에 저장되고 이 디렉토리의 계층 구조가 URL 체계에도 그대로 적용되어 www.example.com/uploaded/image1.jpg 의 URL 형태로 업로드된 파일에 접근할 수 있다.

웹 루트 디렉토리란?

웹 애플리케이션의 최상위 디렉토리로써 도메인 자체가 가리키는 디렉토리를 말한다. Apache, IIS 등 웹 서버마다 기본 위치가 지정되어 있지만 개발자에 의해 다른 디렉토리로 지정될 수 있습니다. 우분투 리눅스 환경의 Apache 웹서버의 경우 웹 루트 디렉토리는 /var/www/html 이며 일반적인 웹 구현 방식에 따르면 업로드되는 파일의 저장 위치는 개발자에 의해 지정된 웹 루트 디렉토리 하위에 존재하는 디렉토리이다. 예를 들면 /var/www/html/uploaded 와 같다.

  • 프로필 사진을 업로드하는 상황이다. 개발자는 업로드된 파일을 웹루트 디렉토리 하위의 profile 디렉토리에 저장되도록 구현했다고 가정한다.
사용자는 자신의 프로필 화면에서 사진 파일(picture.jpeg)을 업로드한다. 사용자가 업로드한 사진 파일은 웹 루트 하위의 profile 디렉토리에 저장되게 된다. 파일이 업로드된 이후 누군가 해당 사용자의 프로필을 조회하게 되면 웹 애플리케이션은 URL을 통해 사진 파일이 저장된 위치에서 파일을 가져와 프로필 조회 화면에 포함시킨다. 위의 그림을 보면 서버의 웹 루트 하위의 profile 디렉토리나 profile 디렉토리에 저장된 picture.jpeg 파일은 도메인(www.example.com)을 기준으로 디렉토리 구조와 동일한 체계로 매칭된다.

업로드 된 파일은 대부분 URL을 통해 접근할 수 있다. 이 뜻은 웹 애플리케이션에 접근이 허용된 누구라도 웹 브라우저를 통해 파일에 접근할 수 있다는 뜻이다. 이 점을 이용해서 파일 업로드 취약점을 악용할 수 있으며 공격자 입장에서는 업로드된 파일의 위치를 반드시 알아야 한다. 파일의 위치는 해당 파일에 커서를 올리고 웹페이지 좌측 하단에 보면 나와있고해당 파일에서 오른쪽 클릭한 후 속성을 보고 확인할 수도 있다.

공격자 입장에서 파일 업로드 취약점을 이용해 할 수 있는 가장 매력적인 공격은 웹셸 업로드이다. 만일 아래 그림과 같이 공격자가 JPEG, PNG와 같은 이미지 파일이 아니라 PHP, ASP와 같은 스크립팅 언어로 작성된 웹셸 파일을 업로드 할 수 있다면 매우 치명적이다.

공격자는 업로드된 파일의 URL 경로를 확인한 후 웹 브라우저를 통해 해당 파일에 접근할 수 있을 것이다. 즉, 공격자는 서버에 저장된 웹셸 파일을 아래의 그림과 같이 웹 브라우저에서 열람하고 임의의 명령(rm과 같은 삭제 명령 등)을 실행하여 시스템을 손상 시키거나 공격에 필요한 시스템 정보들을 알아낼 수 있게 되는 것이다.

파일 업로드 취약점 유형

  • 로컬 파일 업로드 취약점

    웹 애플리케이션 자체내에서 사용자가 직접 악성 파일을 업로드할 수 있는 취약점이다. 공격자는 업로드된 파일을 실행하여 악의적인 행위를 할 수 있게 된다.

  • 원격 파일 업로드 취약점

    웹 애플리케이션 자체에서 사용자가 직접 파일을 업로드할 수는 없으나 인터넷상에 존재하는 악성 파일의 URL을 통해 원격 파일을 요청하게 하여 웹 애플리케이션 서버 내부에 저장할 수 있는 취약점이다.

    파일 업로드 취약점의 영향

    파일 업로드 취약점의 영향은 웹 애플리케이션에 업로드된 악성 파일로 수행할 수 있는 작업이나 파일이 저장된 위치, 웹 애플리케이션을 구동하는 계정의 권한에 따라 다르다. 일반적으로 공격자가 수행할 수 있는 작업은 다음과 같다.

    원격 명령 실행

    웹셸 업로드를 통해 원격 명령 실행이 가능하고 시스템의 민감한 정보를 획득하거나 시스템을 완전히 손상시킬 수 있다.

    보안 우회

    서버 내부의 중요한 파일과 동일한 이름의 파일을 업로드하여 해당 파일을 덮어씀으로써 기존 보안 설정을 무력화하고 다른 공격을 시도할 수 있다.

    피싱 공격

    기존 파일을 피싱 페이지로 덮어쓸 경우 해당 페이지를 방문한 사용자는 피싱 공격에 노출된다.

    서비스 중단

    대용량 파일이 업로드 될 경우 이를 처리하기 위해 서버 자원이 고갈되고 서비스는 의도치 않게 중단될 수 있다.

    클라이언트측 공격

    악성 스크립트가 포함된 파일, 악성 파일 (멀웨어) 등이 업로드될 경우 해당 파일은 사용자의 계정을 탈취하거나 컴퓨터를 감염 또는 손상시킬 수 있다.

    대응방안

    파일 확장자 검증

    안전한 파일 확장자만 업로드를 허용하는 화이트리스트 방식의 필터를 적용한다. 위험한 확장자만 차단하는 식의 블랙 리스트 방식은 공격자가 시도하는 변형된 공격과 우회 시도를 모두 방어할 수 없다. 이 점이 바로 화이트리스트 방식을 사용해야 하는 이유이며 필터는 반드시 서버측에 구현되어야 한다.

    파일 유형 검증

    HTTP를 통해 업로드되는 파일은 Content-Type 헤더와 함께 전송된다. 허용할 MIME TYPE을 정하고 업로드되는 파일의 Content-Type 헤더 값이 허용된 MIME TYPE 목록에 포함되는지 검사를 한다. 허용 목록에 포함될 경우에만 업로드를 허용해야 한다.

    파일 Magic Number 검증

    Magic Number(매직 넘버)는 파일의 형식을 식별하기 위해 파일 첫 부분에 기재된 상수 또는 텍스트입니다. 예를 들어 GIF 파일의 포맷을 보면 Header 부분에 GIF89a 라는 부분이 매직 넘버에 해당된다.

    byte#  hexadecimal  text or
    (hex)               value       Meaning
    0:     47 49 46
           38 39 61     GIF89a      Header
                                    Logical Screen Descriptor
    6:     03 00        3            - logical screen width in pixels
    8:     05 00        5            - logical screen height in pixels
    ...생략...

    [GIF 파일 포맷] (출처: 위키백과)

    파일명 길이 및 파일 용량 제한

    서비스 가용성에 영향을 줄 수 있을만큼의 대용량 파일이 업로드되는 경우 서비스가 중단될 수 있다. 이를 방지하려면 업로드되는 파일명의 길이와 파일 용량의 크기를 제한해야 한다.

    파일명 변경 또는 난독화

    공격자가 파일 업로드 취약점을 악용하려면 업로드된 파일의 위치를 알고 웹 브라우저를 통해 접근할 수 있어야 한다. 파일 업로드 처리 시 파일명을 변경하거나 난독화를 함으로써 공격자가 파일의 위치를 식별하기 어렵게 만들 수 있다. 업로드된 파일을 웹 브라우저에 다시 로드할 때에는 원본 파일명을 사용하지 않고 변경된 파일명을 사용하자.

    웹 루트 상위에 .htaccess 파일 저장

    업로드된 파일이 저장되는 디렉토리에 .htaccess 파일을 저장한다면 이 파일은 공격자에 의해 조작된 파일로 대체될 수 있다. .htaccess 파일은 공격자가 접근할 수 없는 웹 루트 상위 디렉토리에 저장해야 하고, .htaccess 라는 이름의 파일을 업로드할 수 없도록 필터링을 구현해야 한다.

    악성 파일 여부 검사

    파일을 서버에 저장하기 전에 안티바이러스 소프트웨어를 통해 악성 파일 여부를 검사하고 안전한 경우에만 허용한다. 또는 컨텐츠 무해화 기술(CDR)을 사용해 파일에 포함된 악성 코드를 제거하면 좋다.

    업로드 파일 저장 위치의 분리

    업로드된 파일은 웹 애플리케이션의 코드와 별도의 저장 공간에 저장하는 것이 좋다. 웹루트 외부의 디렉토리나 클라우드 기반 저장 장치에 업로드된 파일을 저장할 수 있다. 업로드된 파일을 원격 파일 서버나 별도의 디스크 파티션에 저장하는 것 또한 공격에 의한 피해를 최소화하는데 도움이 된다.

'Web Hacking > Study' 카테고리의 다른 글

정규 표현식  (0) 2023.07.01
File Download 취약점과 대응방안  (0) 2023.07.01
SQL Injection 실습(2)  (0) 2023.07.01
Non-Relational DBMS  (0) 2023.07.01
Relational DBMS  (0) 2023.07.01