DVWA SQL Injection(SQL注入)

SQL Injection,即SQL注入,是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。SQL注入漏洞的危害是巨大的,常常会导致整个数据库被“脱裤”,尽管如此,SQL注入仍是现在最常见的Web漏洞之一。
DVWA  SQL Injection(SQL注入)

 

 Low

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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"]);
}
 
?>

  可以看出,Low级别代码对来自客户端的参数id没有进行任何的检查与过滤

漏洞利用


在看不到源码的前提下,我们需要自己手工注入来进行判断

1.判断是否存在注入点,数字型还是字符型。

①我们分别输入 1 and 1=1  以及 1 and 1=2  (先1 and 1=11 and 1=2来判断页面是否有变化,如果有变化那么肯定就是数字型注入)

如果 1 and 1=2 时数据消失了,就是字符型注入。

DVWA  SQL Injection(SQL注入)

 

 

 DVWA  SQL Injection(SQL注入)

 

 如图判断得不是数字型注入。

②输入 1’ 查询失败 1’ # 查询成功 所以ID是被两个单引号包裹,字符型注入。

1’

DVWA  SQL Injection(SQL注入)

 

 1’#

DVWA  SQL Injection(SQL注入)

 

③判断回显位置

 DVWA  SQL Injection(SQL注入)

 

 ④查询数据库名

DVWA  SQL Injection(SQL注入)

 

 

⑤查询数据库中的表

DVWA  SQL Injection(SQL注入)

 

 

⑥查询表中字段名(不演示中间部分了,老生常谈的东西)

⑦查询字段值

DVWA  SQL Injection(SQL注入)

 

 通过 www.cmd5.com 解码

DVWA  SQL Injection(SQL注入)

 

 我们将抓到的数据包发送至Repeater模块进行操作更加方便,这里给出最后一步,因为都是重复的。

DVWA  SQL Injection(SQL注入)

 

 

Medium

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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"], $queryor 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"]);
?>

  可以看到,Medium级别的代码利用mysql_real_escape_string函数对特殊符号\x00,\n,\r,,’,”,\x1a进行转义,同时前端页面设置了下拉选择表单,希望以此来控制用户的输入。

DVWA  SQL Injection(SQL注入)

 

 漏洞利用

虽然前端使用了下拉选择菜单,但我们依然可以通过抓包改参数,提交恶意构造的查询参数。
大部分步骤和低级一样,只是需要将页面在Burpsuite中发送到Repeater模块,不停的改提交的参数即可,注意的只有一点,由于将’和“符号转义了,所以不可以直接写库名和表名了,需要将库名和表名换为十六进制。
DVWA  SQL Injection(SQL注入)

 

 

DVWA  SQL Injection(SQL注入)

 

 

High

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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);       
}
 
?>

  

可以看到,与Medium级别的代码相比,High级别的只是在SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。需要特别提到的是,High级别的查询提交页面与查询结果显示页面不是同一个,也没有执行302跳转,这样做的目的是为了防止一般的sqlmap注入(sqlmap也是可以绕过的),因为sqlmap在注入过程中,无法在查询提交页面上获取查询的结果,没有了反馈,也就没办法进一步注入。
DVWA  SQL Injection(SQL注入)

 

 

Impossible

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?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();
 
?>

  可以看到,Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,同时只有返回的查询结果数量为一时,才会成功输出,这样就有效预防了“脱裤”,Anti-CSRFtoken机制的加入了进一步提高了安全性。

DVWA SQL Injection(SQL注入)

上一篇:mongoDB常用命令


下一篇:【转】Everything中文绿色版在Win7/8用不了?