🔥 웹 개발자와 정보보안 입문자가 꼭 알아야 할 웹 해킹 & 시큐어 코딩
위아래 1줄씩 띄우고 중요한 부분은 볼드 효과
📍 파일 다운로드 취약점이란?
👉🏻 File Download Vulnerability: 공격자의 공격으로 사용자가 비정상적인 파일을 다운로드 받음으로써 얻게 되는 취약점
사용자 > 인터넷 구간 > 웹 서버 > 파일 다운로드 기능 > 정상 경로/비정상 경로
정상 경로: /web/root/A/upload
비정상 경로: /etc/
👉🏻 파일 다운로드가 가능한 경로를 특정 경로로 지정해 놓지 않았을 때 공격자가 다운로드 경로를 바꿈으로써 공격 실행함
📍 공격 원리 분석
1) /webroot/A/ --> ../../../etc/passwd
2) download.jsp의 실행
3) 서버의 다운로드 경로 접속
4) 파일 다운로드
http://victim.co.kr/download.jsp?file=../../../etc/passwd
최상위 경로가 정상 경로에서 ../../ 두 번 올라가야 한다 하더라도
공격자가 ../../../ 입력해도 결국 최상위 경로가 되기 때문에 접근 가능하게 됨
👉🏻 파일 다운로드 취약점의 핵심 포인트는 기존 경로를 변조하는 것
📍 공격 방법
1) 파일명만 받는 경우
정상: http://www.victim.co.kr/download.jsp?filename=test.png
비정상: http://www.victim.co.kr/download.jsp?filename=../../../../etc/passwd
경로 이동 문자 삽입
2) 업로드 경로를 분리시킨 경우
정상: http://www.victim.co.kr/download.jsp?path=image&filename=test.png
비정상: http://www.victim.co.kr/download.jsp?path=../../../../etc&filename=passwd
3) 전체 경로를 받는 경우(서버에 풀 경로를 보여 줌으로 대단히 위험!)
정상: http://www.victim.co.kr/download.jsp?path=/jeus/webhome/test_con/app/upload&filename=test.png
비정상: http://www.victim.co.kr/download.jsp?path=/etc&filename=passwd
👉🏻 파일 다운로드 경로 찾는 법
OS: Unix, Linux
구분기호(Separator): /
OS: Windows
구분기호(Separator): /, \(역 슬래시)
👉🏻 운영체제별 경로 구분 기호
📍 대응 방안
케이스별로 다른 대응 방안이 필요함
일부 경로 + 파일명
파일명
키(Key) 값 반환
등의 변경이 필요함
👉🏻 전체 경로 + 파일명 경우
...
String gubun = request.getParameter("gubun");
String filename = request.getParameter("filename");
// \(역슬래시) 문자를 /(슬래시) 문자로 치환
gubun = gubun.replace("\\", "/");
filename = filename.replace("\\", "/");
// gubun, filename 변수에 대해 /, .. 문자 존재 시 경고창 출력 및 어플리케이션 종료
if(gubun.indexOf("\") != -1 || gubun.indexOf("..") != -1 || filename.indexOf("..") != -1) {
out.println(<script>alert('허용되지 않은 문자 포함됨'); history.back(-1);</script>");
return;
}
// 다운로드 로직 진행
...
👉🏻 일부 경로 + 파일명 경우
👉🏻 파일명 경우
...
Integer idx = Integer.parseInt(request.getParameter("idx"));
// 프리 컴파일 이후에 set을 이용하여 바인딩 해 줘야 보안에 취약하지 않을 수 있음!
pstmt = conn.prepareStatement("SELECT * FROM BOARD_FILE WHERE IDX=?");
pstmt.setInt(1, idx);
rs = pstmt.executeQuery();
// 다운로드 로직 진행
...
👉🏻 키(Key) 값(키값을 통해 DB에서 파일 경로를 반환)
출처