본문 바로가기

Webhacking

[T0M4TO] Heavy Query Time based SQL Injection

728x90
반응형

※ Query는 Mysql을 기반으로 작성했다.

0. 개요

Time based SQL Injection은 말 그대로 시간을 기반으로 한 SQL Injection이다.
SQL Injection이 가능한것 같으나 Error 내용이 눈에 띄지도 않고, Response 데이터를 통해 참 거짓을 판별할 수 없는경우 주로 사용하게 되는데, 주로 Sleep과 Benchmark를 사용하는 것이 대부분이다.

하지만 Sleep과 Benchmark는 너무 유명하다보니 waf에서 막힌다거나, 키워드로 필터링 당할때도 있다.
또 sleep과 benchmark는 조건문을 이용해야 데이터를 추출해내기 용이한데, 조건문인 if문이나 case when문도 역시나 너무 유명해서 같이 필터링 당하는 경우가 많다.
마지막으로 이건 뇌피셜이지만 또 워게임이나 CTF에서도 잘 나오지 느낌이다.

그래서 이번에 새로운건 아니지만 덜 알려진 Heavy Query Time base SQL Injection을 이용한 공격방법을 공유하려 한다.

1. 내용

Heavy Query는 말그대로 무거운 쿼리이다. 
무거운 쿼리라 함은 실행하는데 있어 오래 걸리게 하는 쿼리를 의미한다. 
sleep과 benchmark는 임의의 시간동안 실행을 멈춘다던가, 어떤 함수를 몇번 반복함으로써 시간을 Delay 시키는 것인데, Heavy Query를 이용한 공격은 조회되는 구문의 양을 많게 하여 시간을 Delay 시키는 방법이다.

Heavy Query의 예시는 다음과 같다.

위 예시는 information_schema Database의 columns Table 3개를 Cross join한 것이다. 
예제 Query에서는 join 명령어가 생략되었는데, 요러한 경우 Cross join이 된다.
(Cross join을 생략하지 않았을때와의 차이는 on을 통한 조건을 안넣어도 된다는 것이 있다.)

가뜩이나 information_schema의 columns Table은 컬럼수도 많고 데이터도 많은데 이걸 3번 Cross join했으니, 이를 조회하는데 걸리는 시간이 46초나 걸린것이다.

상황에 맞게 예제를 응용하여 공격을 하면 된다.
이에 크게 2가지 상황에 맞는 공격방법을 소개하고자 한다.

  • IF와 같은 전형적인 조건문을 사용할 수 있는 경우
  • IF와 같은 전형적인 조건문을 사용할 수 없는 경우 

1-1. 전형적인 조건문을 사용할 수 있는 경우

전형적인 조건문인 IF를 사용하여 공격을 시도한다면 이렇게 할 수 있다.

select count(*) from [테이블명] where a=123 or if([찾아내고자 하는 데이터를 비교하는 조건], (select count(*) from information_schema.columns A, information_schema.columns B, information_schema.columns C), 1);

찾아내고자 하는 데이터를 Blind SQL Injeciton으로 찾아내기 위해 비교조건을 넣고, 참 거짓을 Heavy Query를 이용하여 Time based로 알아내는 것이다.

if문만 사용가능하다면 위에 있는 예제를 그대로 사용할 수 있어 굉장히 쉽다.

1-2. 전형적인 조건문을 사용할 수 없는 경우

전형적인 조건문인 IF를 사용하지 않을 경우, join 구문에서 사용하는 on을 사용하여 조건 성립 여부를 확인하는 방법이 있다.

select count(*) from [테이블명] cross join information_schema.columns A cross join information_schema.columns B cross join informationi_schema.columns C on [찾아내고자 하는 데이터를 비교하는 조건];

on을 사용하는 만큼 where절에서 사용하는 방법이 아니며, on 구문 특성상 조건이 참일 경우에만 cross join이 진행되기 때문에, 쿼리 실행시간이 오래걸리면 참, 아니면 거짓임을 Time based로 알아낼 수 있다.
(on을 사용하기 위해 join 명령어를 직접 입력해주어야 한다.)

[조건이 참인 경우]
[조건이 거짓인 경우]

위 스크린샷을 보면 조건이 참인 경우 무려 50초에 가까운 시간이 걸렸지만, 거짓인 경우에는 0.1초도 걸리지 않은 시간에 Query가 실행됨을 알 수 있다.

2. 결론

Heavy Query의 경우 최근 CTF에서도 나와, 생각난김에 정리해보았다.
주로 공부할때 sleep을 공부하고 sleep 을 우회하기 위해 benchmark를 공부하는데 Heavy Query가 그 다음단계라고 생각한다.

왜냐하면 sleep이나 benchmark와 같은 DBMS에 종속적인 함수들은 DBMS 변경시 사용이 어렵고 새로운 함수를 찾아내야 하기 때문이다. 대표적으로 Oracle에서는 dbms_lock.sleep 이런 형태로 사용해야한다. 하지만 Heavy Query는 그 원리만 이해하면 쿼리를 만들어내는데 큰 어려움이 없어 범용적으로 좋다고 생각한다.

CTF에도 나오고 있는만큼 알아둬서 나쁠건 없다.


728x90
반응형

'Webhacking' 카테고리의 다른 글

[T0M4TO] OWASP Top 10 - 2021 한글 리뷰  (1) 2021.10.10