Dvwa之SQL 注入全级别学习笔记

发布于:2022-12-16 ⋅ 阅读:(604) ⋅ 点赞:(0)

SQL注入 

SQL注入指web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询,攻击者可以通过不同的条件产生不同的SQL语句,这是学习dvwa的sql注入的相关笔记。仅供学习。参考的博客

DVWA全级别通关教程_JF_Adm0616的博客-CSDN博客_dvwa

mysql中Illegal mix of collations for operation “UNION”错误的解决方法_wkj001的博客-CSDN博客

Low级别:

系统没有做任何防护,可以直接进行注入

判断注入类型

输入 1正常显示但无法区分注入点类型

f2e73b1cca814799bdc8d72172377fe6.png

输入 2

131f1afd3701488c90f4f8d2600ef70d.png

再输入1+1

无返回结果,因为如果是数字型注入id=1+1,则会显示id为2的信息,字符型就会搜索id=’1+1’的数据。因为这个注入点没有返回数据2的内容,所以为字符型注入漏洞。

807c8280257a4f9b8bd1de48544686d0.png

输入1’ and 1=1提示错误,输入1’ and 1=1#显示正常说明存在单引号,在注入时需要闭合或者注释掉单引号(在语句后面加#)。

fd94c280bc8149f789c6e83b5d87d228.png

查询字段长

1’ order by 1#

023d34c55ad447d696b56bf584f67e10.png

1’ order by 2#

1’ order by 3#.....

当注入1’ order by 3#时报错,而1’ order by 2#时正常,说明存在两个字段。

2b3e7bf55b3a4f5c9880c499869d7c50.png

结合联合查询去对网站进行注入从而获取信息

可以使用两种方式1’ union ....或者-1’ union ....。两者都可以使用,只不过后者的查询结果更简介一些不会去输出id=1的信息。

查询数据库名

-1’ union select 1, database()#

6fa0567d4cdb49f6bbf9c4d7fa912150.png

查询数据表名

-1’ union select 1,table_name from information_schema.tables where table_schema=’dvwa’ #

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

0f7093cb694646d0a0821c45980cc562.png

查询到有数据库guestbook,和user两个数据表。

查询数据列名

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

7cee9b85d83e4e0e84cfd8dcf1fb2990.png

发现users数据表含有

user_id,first_name,last_name,user,password,avatar,last_login,failed_login字段

查询详细信息

得知字段名后就可以肆无忌惮开搞了

查询用户名和用户密码-1’ union select user,password from user #

4b0529a38cb64cb09bfc942d1e10deb9.png

不过密码经过了加密了

Medium级别

刚换完就发现,输入框没了!!!

cd75e6049b62432ba1a0db98f26b8149.png

问题不大咱可以试一试用burpsuite,抓到数据包。

5b4bd679d68f43ebbd3f612d3a09e074.png

将截取到的包发送到重发器中进行注入

fd1f6a711c054a93a4537e6d7c4b59b2.png

与low级别时一样的步骤

先判断字段长

bb7e3197899942b29d611de1141e494e.png

5944d5540af6427a803fc18dba1b15c6.png

发现字段长也为2

查询数据库名

24c85feafa7942f9b35c0bffee5cde15.png

查询数据表名

cb07d04ea19c4d59946037f62a33b3e1.png

查询数据库字段名

 在查询数据库字段名时一直报错

f89fe17d371345589ac4e9509282fe6a.png

在上一个环节还没有产生报错,为什么在这里就报错了呢?

试了一些都是与使用单引号有关。

查看一下源码

9e66b7afc11740c1a04a1e75c5d278d7.png

发现使用了mysqli_real_escape_string函数

fcbbe2030745448fa8d32455b6eb87ee.png

百度发现这个函数过滤了很多SQL注入字符,怎么才能绕过这个函数呢?可以将需要单双引号的数据用16进制代替。

d0b3d42cebc440219fbb7d9e117c8e72.png

成功绕过

查询数据

f63bfe6de5ff4ce39f6de04e09c07684.png

High级别

更换等级发现界面又变了,点击链接进入页面,从这里尝试一下注入

03a7ab7a8a4348579247b0b0e4c3ad78.png

发现是可行的

按步骤一步步来。先是搜数据库名

08c7fec1ebb9463c814e6decaf2466fc.png

再搜数据表名

46bade08249f4495b5f2b4beb6485d9d.png

再搜字段名

ce5ced79427f42bcb0a20ca92b3b139a.png

然后搜索数据。

65d9107d97aa473b84abfbc91073f823.png

做完发现就是需要在那个链接进行注入,和low级别一毛一样,怎么就算high,好想是为了防止sqlmap注入才这样搞的

Impossible

d4f99ce6881d47b6bcb7505513f1bb0c.png

返璞归真,没有了那些花里胡哨的外表。和low级别一样的外观,让我刚进靶场的时候还以为是low级别,注入的好几次都没有反应,才发现是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 )) {
    
            $id = intval ($id);
    
            switch ($_DVWA['SQLI_DB']) {
    
                case MYSQL:
    
                    // 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>";
    
                    }
    
                    break;
    
                case SQLITE:
    
                    global $sqlite_db_connection;
    
    
                    $stmt = $sqlite_db_connection->prepare('SELECT first_name, last_name FROM users WHERE user_id = :id LIMIT 1;' );
    
                    $stmt->bindValue(':id',$id,SQLITE3_INTEGER);
    
                    $result = $stmt->execute();
    
                    $result->finalize();
    
                    if ($result !== false) {
    
                        // There is no way to get the number of rows returned
    
                        // This checks the number of columns (not rows) just
    
                        // as a precaution, but it won't stop someone dumping
    
                        // multiple rows and viewing them one at a time.
    
    
                        $num_columns = $result->numColumns();
    
                        if ($num_columns == 2) {
    
                            $row = $result->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>";
    
                        }
    
                    }
    
    
                    break;
    
            }
    
        }
    
    }
    
    
    // Generate Anti-CSRF token
    
    generateSessionToken();
    
    
    ?>

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

参考内容:DVWA全级别通关教程_JF_Adm0616的博客-CSDN博客_dvwa

遇到的问题

问题1

在进行注入时遇到“Illegal mix of collations for operation 'UNION'”提示,我也搞不明白,然后百度搜了一下发现个解决方法

mysql中Illegal mix of collations for operation “UNION”错误的解决方法_wkj001的博客-CSDN博客

才知道原来是因为是union连接information_schema的字段时的字符规则不一样,因此在写low时我根据博主的步骤修改了相关参数,果然好使了。但要是只是修改了数据库中的last_name、first_name的,建议把SQL注入实验涉及到的字段都修改一下。这样更方便注入。

具体步骤:

打开Navicat for MySQL。查询information数据库中的TABLES表中TABLE_NAME字段的排列规则

98e37f54ef874ad7868396e9f3bffc6d.png

进入到dvwa数据库中的users表中涉及到的字段排列规则都改成和上面搜到的一致,

bc40fc4df1b1454292fb666b3db31414.png

小白一问:可不可用这个方法来做成防御的手段啊?

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到