안녕하세요? 허니입니다. 중요 정보 파일 다운로드 취약점에 대해서 알아보고 대응 방법에 대해 알아보도록 하겠습니다. 사이버 해킹에 대해 공부하시는 학생이나 연구원 분이 계시면 도움이 될 것이라 생각합니다. 


웹 페이지에서 파일의 경로가 노출되어 있고, 파일의 위치에 대한 보안적 조치가 없을 경우, 파일 다운로드 경로를 변경하여 웹 서버 내의 중요 파일들을 다운로드 할 수 있는 취약점입니다. 게시판 등에 저장된 자료에 대해 다운로드 스크립트를 이용하여 다운로드 기능을 제공하면서, 대상 자료파일의 위치 지정에 제한조건을 부여하지 않았을 경우에 URL 다운로드 스크립트의 인수값에 ‘../’문자열 등을 입력하여 상위 경로로 이동하여 시스템의 중요파일 (예:/etc/passwd)과 같은 비공개 자료들을 유출될 위험이 존재하며 특히, 리눅스 및 유닉스 계열의 웹 서버에 각별한 주의가 필요합니다.

 

 일반적 대응방법 
첨부파일이 저장되어 있는 특정 디렉토리에 있는 파일만을 다운 받을 수 있도록 합니다.
(다운받기 위한 파일 이름에 “..”, “/”, “\”와 같은 문자열이 존재하면 모두 필터링 해야함.)

 

 개발 언어별 대응방법
- 보안코딩(ASP)

<%
file = Request.Form ("file")'파일 이름

Response.ContentType = "application/unknown"'ContentType 선언
Response.AddHeader "Content-Disposition","attachment; filename=" & file
Set objStream = Server.CreateObject("ADODB.Stream")'Stream 이용
strFile = Server.MapPath("./upfiles/") & "\" & file '서버 절대경로
strFname=Mid(Fname,InstrRev(file,"\")+1) '파일 이름 추출, ..\ 등의 하위 경로 탐색은 제거 됨
strFPath = Server.MapPath("./upfiles/") & "\" & strFname '웹서버의 파일 다운로드 절대 경로
If strFile = strFPath Then'사용자가 다운 받는 파일과 웹 서버의 파일 다운로드 경로가 맞는지 비교
objStream.Open
objStream.Type = 1
objStream.LoadFromFile strFile
download = objStream.Read
Response.BinaryWrite download
End If
Set objstream = nothing'객체 초기화
%>


- 보안코딩(PHP)

if (preg_match("/[^a-z0-9_-]/i",$up_dir))
print "디렉토리에 특수문자 체크";
exit;

if (preg_match("/[^\xA1-\xFEa-z0-9._-]|\.\./i",urldecode($dn_file_name)))
print "파일이름에 특수문자 체크";
exit;
$dn_path = "/var/www/data/$up_dir/$dn_file_name";
if (!file_exists($dn_path))
print "파일이 존재여부 체크";
exit;
//파일 전송 루틴
header("Content-Type: doesn/matter");
header("Content-Length: ".filesize("$dn_path"));
header("Content-Disposition: filename=".$dn_file_name]);
header("Content-Transfer-Encoding: binary\r\n");
header("Pragma: no-cache");
header("Expires: 0");


- 보안코딩(JSP)

String UPLOAD_PATH= "/var/www/upload/";
String filename= response.getParameter("filename");
String filepathname = UPLOAD_PATH + filename;

if(filename.equalsIgnoreCase("..") || filename.equalsIgnoreCase("/"))
// 파일 이름 체크
return 0;
// 파일 전송 루틴
response.setContentType("application/unknown; charset=euc-kr");
response.setHeader("Content-Disposition","attachment;filename=" + filename + ";");
response.setHeader("Content-Transfer-Encoding:" , "base64");
try
BufferedInputStream in = new BufferedInputStream(new FileInputStream(filepathname));
.........
catch(Exception e)
// 에러 체크 [파일 존재 유무등]


 

+ Recent posts