본문 바로가기
Security/보안기초

웹 보안 기초(03)

by 계영수 2023. 11. 15.
728x90

 

 

 

 

 

 

 

위의 경우에는 id에는 aa 패스워드에는 

1'or'1'='1

 

▶ Blind SQL Injection

 

 

 

쿼리의 조건이 참, 그렇다면 조건을 거짓으로 만들면

 

 

 

쿼리 결과의 Hello 문구와 login failed 문구를 통해 우리가 알 수 있는 것은, 조건이 참인지 거짓인지는 구분할수 있다는 것이다. 비록 유출하고자 하는 정보를 한 번에 화면에 노출시키지는 못하지만 참과 거짓 구분이 가능하다면 Blind SQL Injection을 통해 정보를 빼낼 수 있다.

 

 

위의 쿼리는 length 함수를 이용하여 패스워드가 10자보다 짧은 계정이 있는지를 확인하려 하는 것이다.

쿼리의 결과가 참으로 나왔기 때무네 패스워드가 10자보다 짧은 계정이 존재한다는 것을 알 수 있다.

Length 함수가 10자보다 작음을 확인했으니 그 범위를 부등호를 이용해 조금씩 줄여나가다 보면 아래 그림과 같이 guest의 패스워드가 8자임을 확인할 수 있다.  이처럼 눈에 단번에 보이지는 않지만 참, 거짓 구분만을 통해 정보를 알아내는 기술이 바로 Blind SQL Injection 이다.

 

 

다만 이렇게 공격하는 경우에는 데이터가 여러 개 조회될 수 있다. 조건이 성립하는 계정이 여러개 일수 있기 때문에 정확하게 하나의 정보를 빼내는데 어려움이 있을 수 있다.

 

만약 admin의 패스워드 길이를 알고 싶다면 legnth(pw) < 10 and id='admin' 이런 식으로 and 구문을 활용하면 id가 admin 일 경우에만 조건이 참이 되기 때문에, admin의 패스워드 길이 정보를 알아낼 수 있다.

a' or length(pw) =8 and id='admin' --

 

 

이제, 빼내고자 하는 정보의 길이를 알아냈다면 이제는 실제로 빼내야 한다. 다만 우리가 참 또는 거짓밖에 구별하지 못하는 상황이라면, 한 글자씩 쪼개서 맞추는 것이 빠를까 아니면 한번에 맞추는 것이 빠를까? 당연히 한 글자씩 맞추는 것이 경우의 수에 의거하여 훨씬 빠를 것이다.

 

이때 필요한 것이 substring 이라는 함수이다. 쉽게 말하면 문자열을 조각내는 함수이다. 총 3개의 데이터를 필요로 하는데, 첫번째는 자르고자 하는 대상, 두번째는 몇 번째부터 자를 것인지, 마지막은 몇 글자를 자를 것인지이다.

Payload : a' or substring(pw,1,1) ='a' and id = 'admin' --[공백]

 

 

 

위 쿼리의 결과 admin 의 패스워드 첫번째 글자가 a라는 것을 알 수 있다.

 

login_safe.php

<?php
$id = $_GET['id_param'];
$pw = $_GET['pw_param'];

$db_conn = mysqli_connect("127.0.0.1", "webhacking_db", "webhacking", "login");
if($db_conn == false){
    echo mysqli_connect_error();
}
else {
    $query = "select * from user where id=? and pw=?";
    $stmt = mysqli_prepare($db_conn, $query);
    if($stmt == false) {
        echo mysqli_error($db_conn);
        exit();
    }
    $bind = mysqli_stmt_bind_param($stmt, "ss", $id, $pw);
    if($bind == false) {
        echo mysqli_error($db_conn);
        exit();
    }
     $exec = mysqli_stmt_execute($stmt);
    if($exec == false) {
        echo mysqli_error($db_conn);
        exit();
    }
     $result = mysqli_stmt_get_result($stmt);
     if($result == false) {
         echo mysqli_error($db_conn);
     }
     else {
         $row = mysqli_fetch_array($result);
         if($row) {
             echo "Hello {$row['id']}, login success!";
         }
         else {
             echo "login failed";
         }
     }
     mysqli_close($db_conn);
}
?>
728x90

'Security > 보안기초' 카테고리의 다른 글

ARP Spoofing  (0) 2023.11.17
통합 보안  (0) 2023.11.17
웹 보안 기초(02)  (0) 2023.11.15
웹보안 기초(01)  (0) 2023.11.15
Memory Theory(02)  (0) 2023.11.14