zip 파일 업로드 시 취약점

윤효준·2024년 9월 3일
0

콤퓨타 공부

목록 보기
4/17

소프티어 최종 발표날에 나는 프로젝트에서 사용자(어드민 유저)의 편의를 위해 zip 파일 업로드 시 어떤 오류로 인해 업로드가 실패하는지 알려주는 기능을 추가했다고 발표했다.

그때 질의응답 시간에 주신 질문 중 하나가 어드민에 올리는 zip 파일이 유효한 zip인지 문제를 일으킬만한 친구가 아닌지 확인하는 과정이 있냐는 질문을 해주셨다...!

생각치도 못한 부분이었다. 오늘은 이 부분에 대해서 이야기해보고자 한다!!

1. 주요 취약점

1.1 Zip Slip

개요

Zip Slip은 압축 파일 내부에 포함된 파일이 압축 해제될 때 의도적으로 경로 탐색(../)을 사용하여 파일을 시스템의 다른 경로에 추출하게 만드는 취약점이다. 이를 통해 공격자는 시스템 파일을 덮어쓰거나 악성 파일을 특정 위치에 배치할 수 있다.

Zip Slip 취약점의 작동 방식

공격자는 압축 파일 내부의 파일 이름에 ../와 같은 경로 탐색 문자를 포함시켜 /etc/passwd와 같은 민감한 시스템 파일을 덮어쓰거나 접근할 수 있도록 유도할 수 있다. 이로 인해 시스템 파일이 손상되거나 공격자가 서버에 원격으로 접근할 수 있는 악성코드를 심는 것이 가능하다.

Zip Slip 공격 시나리오

공격자가 아래와 같이 ZIP 파일 내에 파일 경로를 조작한다.

../../../../../../etc/passwd
../../../../../../var/www/html/index.php

공격자는 이 ZIP 파일을 서버에 업로드한다. 서버는 이 파일을 특정 경로(/var/www/uploads/)에 해제하지만 경로 검증이 없기 때문에 파일이 실제로는 /etc/passwd/var/www/html/index.php에 저장된다.

그 결과:

  • 시스템의 사용자 계정 정보가 덮어씌워져 공격자는 시스템에 대한 관리자 권한을 획득할 수 있다.

  • 웹사이트의 메인 페이지(index.php)에 악성코드가 삽입되어, 공격자가 원격 명령을 실행할 수 있는 웹셸을 설치할 수 있다.

웹 셀(Web Shell) 예시

웹 셸은 서버에서 원격으로 명령어를 실행할 수 있는 간단한 스크립트이다. 공격자는 다음과 같은 웹 셸을 업로드할 수 있다

<?php
if(isset($_GET['cmd'])) {
   system($_GET['cmd']);
}
?>

해당 스크립트는 URL에서 cmd라는 매개변수를 받아 서버에서 해당 명령어를 실행한다.
예를 들어 해당 웹 쉘이 example.com/var/www/html/index.php에 업로드되었다면 http://example.com/var/www/html/index.php?cmd=ls과 같은 URL을 사용하여 서버에 접근한다.
ls는 리눅스 명령어로 서버의 파일 및 디렉토리 목록을 출력한다!

이러한 웹 셸은 공격자에게 서버 제어권을 줄 수 있기 때문에 매우 위험하다.

Zip Slip 취약점 방지 방법

이러한 공격을 방지하려면 파일을 추출할 때 경로 탐색을 방지하고 허용된 디렉토리 내에서만 파일이 저장되도록 해야 한다.

  1. 파일 경로 검증: 압축 해제할 파일의 경로를 반드시 검증하여 경로 탐색 문자열(../)을 포함하는 파일이 존재하는지 확인한다. 파일의 절대 경로를 계산하고, 그 경로가 허용된 디렉토리 내에 있는지 확인한다.

  2. 추출할 디렉토리 범위 제한: ZIP 파일의 각 항목에 대해 절대 경로를 계산한 후 그 경로가 허용된 디렉토리 내에 있는지 확인한다. 이를 통해, 압축 파일에 포함된 경로가 지정된 디렉토리를 벗어나지 않도록 해야 한다.

1.2 압축 폭탄(Zip Bomb)

개요

Zip 폭탄은 매우 작은 크기의 압축 파일이지만 이를 풀어내면 비정상적으로 큰 파일이 되어 시스템 자원을 고갈시키는 공격이다.

압축 폭탄의 작동 방식

압축 파일을 해제하는 과정에서 시스템은 파일을 해제할 공간과 메모리를 할당한다. 압축 폭탄은 이를 활용해 두 가지 주요 방식으로 작동한다.

첫 번째는 압축 파일을 여러 번 중첩하여 압축 해제 시 압축 비율이 극도로 높은 데이터를 생성하여 압축 파일을 처리하는 시스템이 CPU, 메모리, 디스크를 지나치게 사용하게 만드는 방식이다.

두 번째는 수백만 개의 작은 파일을 생성하여 시스템이 파일 개수 처리에 자원을 과다하게 사용하게 만드는 방식이다.

이렇게 자원을 과다하게 사용하게 되면 결국 시스템은 멈추거나 느려진다.

압축 폭탄 공격 시나리오

공격자는 다중 압축 기법(압축된 파일을 다시 압축하는 방식)을 사용하거나 매우 효율적으로 압축할 수 있는 데이터 패턴을 활용하여 비정상적으로 큰 데이터를 수백 배 이상 압축한 압축 폭탄 파일을 생성한다.

공격자는 이 압축 폭탄 파일을 웹 어플리케이션이나 이메일 시스템에 업로드한다. 특히 파일을 처리하고 자동으로 압축을 해제하는 서비스가 표적이 된다.

시스템은 압축된 파일을 해제하기 위해 CPU와 메모리를 사용하고 압축 해제된 데이터를 저장할 디스크 공간을 확보해야 한다. 시스템의 자원이 부족해지면 서버가 멈추거나 성능이 극도로 저하되 어 서비스 중단이 발생할 수 있다.

압축 폭탄 방지 방법

  1. 압축 비율 검사: 압축 비율을 검사하여 비정상적으로 높은 압축 비율(예: 1000배 이상)이 나타나는 파일은 차단한다.

  2. 파일 크기 제한: 압축 파일의 크기뿐만 아니라 압축 해제 후 예상되는 파일 크기를 미리 계산하여 허용된 범위를 초과하는 경우 해제를 중단한다.

  3. 압축 파일 내 파일 개수 제한: 압축 파일 내부에 포함된 파일의 개수도 제한한다. 압축 폭탄은 대량의 파일을 생성할 수 있기 때문에 파일 개수가 비정상적으로 많은 ZIP 파일은 해제를 중단한다.

  4. 해제 시 리소스 제한: 파일을 해제할 때 사용할 수 있는 시스템 자원을 제한하여 압축 해제 과정에서 자원이 고갈되지 않도록 한다.

  5. 바이러스 스캐너 및 파일 검사 도구 사용: 압축 파일을 해제하기 전에 압축 폭탄을 탐지할 수 있는 바이러스 스캐너나 파일 검사 도구를 사용한다.

1.3 파일 타입 위장

개요

ZIP 파일 내부의 파일이 정상적인 파일인 것처럼 보이지만 실제로는 악성코드를 포함한 파일일 수 있다.

파일 타입 위장의 작동 방식

파일 타입 위장은 파일의 실제 내용을 변경하지 않고 파일의 확장자나 헤더 정보를 변경함으로써 이루어진다. 이를 통해 시스템이 잘못된 파일 형식으로 인식하게 만들고 보안 검사나 바이러스 스캔을 우회할 수 있다.

위장의 주요 형태

  1. 파일 확장자 위장: 파일의 확장자를 위장하여 악성 파일이 아닌 것처럼 보이게 한다. 예를 들어 .exe 파일을 .zip, .pdf 등으로 확장자를 변경한다.

  2. MIME 타입 위장: MIME 타입은 웹 서버와 클라이언트 간에 파일이 어떤 형식인지 알려주는 정보이다. 공격자는 이 정보를 위장하여 브라우저나 서버가 파일을 잘못 처리하도록 유도할 수 있다. 예를 들어 악성 스크립트 파일을 정상적인 이미지 파일(MIME 타입: image/jpeg)처럼 위장할 수 있다.

  3. 이중 확장자: 파일 이름에 여러 개의 확장자를 사용하여 사용자나 시스템이 잘못된 확장자를 인식하도록 유도한다. 예를 들어 image.zip.exe 파일은 실제로 실행 파일이지만 이를 압축 파일로 오인할 수 있다.

  4. NULL 바이트 삽입: NULL 바이트는 문자열의 끝을 나타내는 종단 문자로, 일부 프로그래밍 언어와 시스템에서 %00 이후의 문자를 무시하게 만듭니다. 예를 들어 malicious.php%00.zip는 서버에서 확장자 검사 시 .zip로 인식되지만, 파일이 실행될 때 %00 이후의 문자는 무시되어 .php로 처리될 수 있습니다. 이는 주로 과거의 시스템에서 발생했으며, 최신 시스템에서는 이러한 공격이 방어된 경우가 많습니다.

파일 타입 위장 공격 시나리오

공격자는 악성코드를 포함한 실행 파일(malicious.exe)의 확장자를 .jpg로 변경하고 이를 ZIP 파일에 포함하여 업로드한다. 서버가 압축을 해제한 후 이 파일을 정상적인 이미지 파일로 착각해 실행할 경우 악성코드가 동작하게 된다.

파일 타입 위장 방지

  1. 파일 확장자 검사: 파일의 magic number(파일 시그니쳐)(파일 형식에 따라 고유한 바이트 서명)를 사용해 파일의 실제 유형을 확인하는 방법이 효과적이다.

  2. MIME 타입 검증: 단순히 클라이언트가 제공한 MIME 타입을 신뢰하지 않고 서버에서 직접 MIME 타입을 판별하는 것이 중요하다.

  3. NULL 바이트 검사: 파일 이름에 NULL 바이트(%00)가 포함되어 있는지 확인하여 이와 관련된 공격 시도를 차단해야 한다.

profile
작은 문제를 하나하나 해결하며, 누군가의 하루에 선물이 되는 코드를 작성해 갑니다.

0개의 댓글