[웹 취약점 진단/모의해킹/해킹] 파일 다운로드

목차

     

     

    FD - 파일 다운로드

     

    ■ 점검내용

     

    웹 사이트에서 파일 다운로드 시 허용된 경로 외 다른 경로의 파일 접근이 가능한지 여부 점검

     

    ■ 점검목적

     

    파일 다운로드 시 허용된 경로 외 다른 경로의 파일 접근을 방지하여 공격자가 임의의 위치에 있는 파일을 열람하거나 다운받는 것을 불가능하게 하기 위함

     

    ■ 보안위협

     

    해당 취약점이 존재할 경우 공격자는 파일 다운로드 시 애플리케이션의 파라미터 값을 조작하여 웹 사이트의 중요한 파일(DB 커넥션 파일, 애플리케이션 파일 등) 또는 웹 서버 루트에 있는 중요한 설정 파일(passwd, shadow 등)을 다운받을 수 있음


    cgi, jsp, php 등 파일 다운로드 기능을 제공해주는 애플리케이션에서 입력되는 경로를 검증하지 않는 경우 임의의 문자(../.. 등)나 주요 파일명의 입력을 통해 웹 서버의 홈 디렉터리를 벗어나서 임의의 위치에 있는 파일을 열람하거나 다운받는 것이 가능함

     

    ■ 참고

     

    ※ 소스코드 및 취약점 점검 필요

     

     

    점검대상 및 판단기준

     

    ■ 대상 : 웹 애플리케이션 소스코드, 웹 서버, 웹 방화벽

     

    양호

    다운로드 파일이 저장된 디렉터리 이외에 접근이 불가능한 경우

     

    취약

    다운로드 파일이 저장된 디렉터리 이외에 접근이 가능한 경우

     

    ■ 조치방법

     

    다운로드 시 허용된 경로 이외의 디렉터리와 파일에 접근할 수 없도록 구현

     

     

    점검 및 조치 방법

     

    ■ 점검방법

     

    Step 1) 웹 사이트에 cgi, jsp, php 등의 애플리케이션을 이용하여 파일을 다운받는 페이지가 있는지 조사

     

    Step 2) 웹 사이트에서 파일 다운로드 시 요청(Request) 정보에 파일 경로를 웹 서버(웹 사이트 포함) 중요 파일(winnt\win.ini, /etc/passwd 등)의 상대 경로(../)로 치환한 후 전송했을 때 해당 경로 파일들을 다운로드 가능한지 확인
    ../../../../../../../../../../../../etc/passwd
    ../../../../../../../../../../../../winnt/win.ini
    ../../../../../../../../../../../../boot.ini

     

    Step 3) "Step 2"에서 파일 다운로드가 불가능한 경우 변조한 파일 경로를 아래의 인코딩(또는 치환, 종단문자추가)을 적용하여 재전송 후 다운로드 가능한지 확인


    ※ URL 인코딩: .(%2e), /(%2f), \(%5c)
    ※ 16bit 유니코드 인코딩: .(%u002e), /(%u2215), \(%u2216)
    ※ 더블URL 인코딩: .(%252e), /(%252f), \(%255c)
    ※ 경로 치환: …//, ….\\, ….\/, …./\
    ※ 종단 문자 추가: [파일명]%00.jpg, [파일명]%0a.jpg

     

     

    ■ 보안설정방법


    * 파일 다운로드의 취약성은 주로 파일의 이름을 조작하는 데서 비롯되므로 다운로드 파일 이름을 데이터베이스에 저장하고 다운로드 수행 시 요청 파일 이름과 비교하여 적절한지 확인하여 사용자가 조작할 수 있는 변수를 제거함
    * 다운로드 애플리케이션 소스 파일을 수정하여 파일을 다운받을 수 있는 디렉터리를 특정 디렉터리로 한정하고 이 외의 다른 디렉터리에서는 파일을 다운받을 수 없도록 설정해야 함
    * PHP를 사용하는 경우 php.ini 에서 magic_quotes_gpc를 On으로 설정하여 .\./ 와 같은 역 슬러시 문자 입력 시 치환되도록 설정
    * 파일 다운로드의 절대 경로 설정 및 DocBase의 상위경로 또는 타 드라이브로 설정을 변경함
    * 다운로드 경로 정보를 자바스크립트나 js 소스에서 확인할 수 없게 제한하며, 웹 서버 서블릿 내부 또는 별도의 설정 파일에서 관리
    * 다운로드를 제공하는 페이지의 유효 세션 체크 로직 필수 적용
    * 다운로드 시 사용되는 파라미터 값 대상으로 아래의 특수 문자를 필터링하도록 웹 방화벽 룰셋 적용

    문자 설명
    . Path Traversal 가능성의 확인
    / 특정 Path의 접근 가능성을 확인
    \ 운영환경에 따른 Path 접근 확인
    % UTF 인코딩 파라미터

     

    ※ 웹 애플리케이션 별 상세 설정


    ∎ ASP

    (예) 필터링 처리 (※ 예로 제시하는 것으로, 구현 시 다를 수 있음)

    .....
    file = Request.form(“file”)
    Response.ContentType = “application/unknown”
    Response.AddHeader “Content-Disposition”, “attachment; filename=” & file
    Set objStream = Server.CreateObject(“ADODB.Stream”)
    strFile = Server.MapPath(“./uploadfiles”) & “ \” & file
    strFname = Mid(Fname, InstrRev(file, “ \”) +1)
    if strFile = strFPath Then
    .....

     

    ∎ ASP.net

    (예) ASP.net 예외처리 (※ 예로 제시하는 것으로, 구현 시 다를 수 있음)
    .NET 환경은 자체적으로 Path Traversal을 막고 있으므로, 소스 자체적인 별다른 조치는 필요가 없으나 일부 .NET 버전에 해당 보안 매커니즘을 우회할 수 있는 취약점이 발견된 사례가 있으므로, 최신 패치를 설치할 것을 권고함. 해당 패치가 설치되어 있지 않은 경우 Global.asax에 다음과 같은 내용을 추가하여야 함

    <script language="C#" runat="server">
    void Application_BeginRequest(object source, EventArgs e) {
    if (Request.Path.IndexOf(' \ \') >= 0 ||
    System.IO.Path.GetFullPath(Request.PhysicalPath) != Request.PhysicalPath) {
    throw new HttpException(404, "not found");
    }
    }</script>

     

    ∎ 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;

     

    ∎ JSP
    (예) 필터링 처리 (※ 예로 제시하는 것으로, 구현 시 다를 수 있음)

    String UPLOAD_PATH= "/var/www/upload/";
    String filename= response.getParameter("filename");
    String filepathname = UPLOAD_PATH + filename;
    if(filename.equalsIgnoreCase(".") || 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) {
    // 에러 체크 [파일 존재 유무 등]
    }

     

     

    조치 시 영향 : 일반적인 경우 영향 없음

     

    댓글

    Designed by JB FACTORY