Oh! JUN

SQL Injection을 통한 파일 다운로드 취약점 공격 실습 본문

웹 해킹/SQL Injection

SQL Injection을 통한 파일 다운로드 취약점 공격 실습

Kwon Oh! JUN 2022. 10. 2. 16:50

※실습환경

#디렉터리 구조

htdocs

          ㄴsqli_down
                              ㄴ upload 
                                             ㄴcaf98268abd13bb8ed384da0313e2dd6.jpg
                              ㄴ download.php
                              ㄴ index.php
#index.php
<h3>Download page</h3>
<hr>
<li><a href="download.php?idx=1">[Donwload]</a><li>
#download.php
<?
    header("Content-Type: text/html; charset=UTF-8");
    $db_conn = new mysqli("127.0.0.1", "root", "dh06802468", "board");
    $idx = $_GET["idx"];

    if(empty($idx)){
        echo "<script>alert('정상적인 접근이 아닙니다.');history.back(-1)</script>";
        exit;
    }

    $query = "select org_filename, real_filename from file_list where idx={$idx}";
    $tmp = $db_conn->query($query);
    $cnt = $tmp->num_rows;

    if($cnt == 0){
        echo "<script>alert('파일이 존재하지 않습니다1.');history.back(-1)</script>";
        exit;
    }

    $file = $tmp->fetch_assoc();
    $filepath = "upload/{$file['real_filename']}";

    if(is_file($filepath)){
        header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename={$file['org_filename']}");
        readfile($filepath);
    } else{
        echo "<script>alert('파일이 존재하지 않습니다.');history.back(-1)</script>";
        exit;
    }
?>

 

#caf98268abd13bb8ed384da0313e2dd6.jpg
#jpg 이미지 파일 아무거나 다운 받아서 upload/위치에 넣으면 됨
#mysql 데이터 삽입

use board;
create table file_list(idx int, org_filename varchar(30), real_filename varchar(50));
insert into file_list values(1, 'dog.jpg', 'caf98268abd13bb8ed384da0313e2dd6.jpg');

C:/file_download/SUCCESS.txt

★TIP

org_filename : 원래 파일명

real_filename : 실제 서버에 업로드 되는 파일명

 

파일 다운로드 할때 사용자 할때 보이는 파일이 org_filename이고 서버 DB에 저장되는 파일이 real_filename이다.

이렇게 구분하는 이유는 org_filename이 한글, 영어, 등일경우 인코딩 때문에 깨질 수 있어서 real_filename으로 통일시켜서 다운 받는것이다.


SQL Injection으로 파일 다운로드 공격을 할 수 있다.


 

UNION-BASED 방식을 사용할거라서

먼저, 컬럼 개수를 확인해본다.

컬럼개수는 2개


select null, null 정상적으로 파일 다운로드 되는거 확인


테이블 만들때

create table file_list(idx int, org_filename varchar(30), real_filename varchar(50));

이렇게 했으니까 첫번째 컬럼에 org_filename, 두번째 컬럼에 real_filename

idx=1 union all select org_filename, real_filename

 

'aaa.txt'는 org_filename으로 사용자한테 보이는 파일 이름이니까 아무렇게 설정해줘도 상관없다.

'../../../../../../file_download/SUCCESS.txt'는 real_filename으로 서버에서 실질적인 파일 이름이니까

org_filename에서 아무렇게 설정해도 real_filename을 찾아서 다운로드 하게된다.

 

그리고 위에 burp에서 Response보면 filename=aaa.txt 사용자가 다운받은 파일의 이름이 조회되는걸 확인할 수 있다.

이걸 활용해서 데이터 조회 공격이 가능하다.

 

다음 글에 포함

 

★★

idx=1에서 idx=3으로 바꾼이유는 idx=1은 파일이 있으니까 1로 그대로 놓고 돌리면 idx=1파일이 다운로드 되어서 뒤에 쿼리 값을 확인할 수 없다.(그래서 이전에 순차적 레코드를 배운거고)

그래서 idx를 거짓으로 넣고 union하면 idx는 거짓이니까 select 안되고 뒤에 쿼리가 실행된다.