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


웹 어플리케이션 서버 환경에서 악성 코드로 작성된 실행 가능한 확장자(*.php, *.asp, *.aspx, *.jsp등) 업로드 시 악성 코드가 실행되는 취약점이며, 이를 통해 서버 조작, DB정보 탈취, Backdoor 설치, 악성파일 업로드 등 다양한 공격을 수행할 수 있습니다.

 

 일반적인 대응방법
업로드 파일을 위한 디렉터리에는 실행 권한을 제거 해야 하며 업로드 된 파일 이름을 임의로 변경하여 저장해야 합니다. 업로드 된 파일의 절대경로를 노출 시키지 않아야 합니다. 첨부되는 파일의 확장자를 필터링 해야 하며, 웹 사이트에서 허용하는 파일 확장자를 제외한 나머지 모든 확장자에 대해서 차단해야 합니다. 첨부파일에 대한 검사는 반드시 Server side Script 에서 구현해야 합니다.

 

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

<%
Set Up = Server.CreateObject("SiteGalaxyUpload.Form")
Path1 = server.mappath(".") & "\upload\"

Fname = Up("file1")

if Fname <> "" then  // 파일 첨부가 되었으면
if Up("file1").Size > 10240 then  // 용량 제한
Response.Write "용량 초과"
Response.End
end if

if Up("file1").MimeType <> "image" then  // 이미지만 업로드 허용
Response.Write "이미지 파일이 아닙니다."
Response.End
end if

Filename=Mid(Fname,InstrRev(Fname,"\")+1)  // 파일이름부분 추출

// 파일이름에서 세미콜론(;)이 존재하는지 검사한다
if NOT(InStr(Filename,”;”) Then
response.write "<script>alert(‘업로드 금지 파일 입니다’);history.back()</script>"
response.End
End if

// 중복 시에 파일이름 부분을 변경하기 위해 분리를 한다
Farry=split(Filename,".")  // .을 기준으로 분리
preFname=Farry(0)  // 파일이름 앞부분
extFname=Farry(UBound(Farry))  // 파일이름의 마지막 확장자

// 파일이름의 마지막 확장자를 검사한다
if (NOT(extFname <> "jpg") or (extFname <> "hwp") or (extFname <> "pdf")) then
response.write " 업로드 금지 파일 입니다 "
response.End
End If

// 저장할 전체 path를 만든다, 파일이름을 만든다
Path2 = Path1 & Filename
saveFname=preFname & "." & extFname

Set fso = CreateObject("Scripting.FileSystemObject")
countNo = 0  // 파일 중복될경우 셋팅 값
fExist=0  // 같은 이름의 파일 존재 체크
Do until fExist = 1
If(fso.FileExists(Path2)) Then
countNo = countNo + 1
Path2 = Path1 & preFname & countNo & "." & extFname
saveFname=preFname & countNo & "." & extFname
else
fExist=1
End If
Loop

Up("file1").SaveAs(Path2)
response.write(saveFname & " 저장완료")
else
response.write("Error")
end if

Set Up = nothing
%>

 

- 보안코딩(PHP)

<?php
$uploaddir = ‘/var/www/uploads/”;

// 파일 사이즈가 0byte 보다 작거나 최대 업로드 사이즈보다 크면 업로드를 금지 시킨다.
If($_FILES[‘userfile’][‘name’])
If($_FILES[‘userfile’][‘size’] <= 0)  // 최대 업로드 사이즈 체크 삽입
print “파일 업로드 에러”;
exit;

// 파일 이름의 특수문자가 있을 경우 업로드를 금지 시킨다.
If (eregi(“[^a-z0-9\._\-]”, $_FILES[‘userfile’][‘name’]))
print “파일 이름의 특수문자 체크”;
exit;

// 파일명 중 “.”으로 구분되어 있는 문자열 모두 검사하여 허용되지 않는 문자열 변환
// Apache mod_mime Module취약점 보완
$filename = preg_replace('/\.(php|phtm|htm|cgi|pl|exe|jsp|asp|inc)/i','$0-x',
$_FILES[‘userfile’][‘name’]);

// 파일 확장자 중 제일 끝에 존재하는 확장자를 기준으로 재검사
$full_filename = explode(“.”, $filename);
$extension = $full_filename[sizeof($full_filename)-1];
$extension = strtolower($extension);
If (!( ereg($extension”,”hwp”) || ereg($extension”,”pdf”) || ereg($extension”,”jpg”)) )
print “업로드 금지 파일 입니다”;
exit;

$uploadfile = $uploaddir. $_FILES[‘userfile’][‘name’];
If (move_uploaded_file($_FILES[‘userfile’][‘tmp_name’], $uploadfile))
print “파일이 존재하고, 성공적으로 업로드 되었습니다.”;
print_r($_FILES);
Else
Print “파일 업로드 공격의 가능성이 있습니다! 디버깅 정보입니다:\n”;
print_r($_FILES);
?>

 

- 보안코딩(JSP)

<%@ page contentType=”text/html;charset=euc-kr” %>
<%@ page import=”com.oreilly.servlet.MultipartRequest,com.oreilly.servlet.multipart.DefaultFileRenamePolicy
, java.util.*”%>
<%
String savePath=”/var/www/uploads”;  // 업로드 디렉터리
Int sizeLimit = 5*1024*1024;  // 업로드 파일 사이즈 제한

try
MultipartRequest multi=new MultipartRequest(request, savePath, sizeLimit, “euc-kr”, new
DefaultFileRenamePolicy());
Enumeration formNames=multi.getFileNames();  // 폼의 이름 반환
String formName=(String)formNames.nextElement();
String fileName=multi.getFilesystemName(formName);  // 파일의 이름 얻기

String file_ext = fileName.substring(fileName.lastIndexOf(‘.’) + 1);
If(!( file_ext.equalsIgnoreCase(“hwp”) || file_ext.equalsIgnoreCase(“pdf”) || file_ext.equalsIgnoreCase(“jpg”)))
out.print(“업로드 금지 파일”);

If(fileName == null)
out.print(“파일 업로드 실패”);
else
fileName=new String(fileName.getBytes(“8859_1”), “euc-kr”);  // 한글인코딩
out.print(“File Name : “ + fileName);

catche(Exception e)


 

+ Recent posts