登录dvwa后,点击左边的"SQL Injection",出现以下界面:
下面做一些学习总结。
第一步:用 "order by n" 获得表中的属性列数,它的意思是用表中的第n个属性列对返回的结果进行排序。我们将n从1开始,然后逐渐递增,直到数据库返回错误,下面是n = 1,2的结果:
当 n = 3 时出现了"Unknown column '3' in 'order clause'"的错误,说明当前的表中没有第3个属性列。至于这个表是什么,我还没有研究过,有待进一步学习,下面我假设这个表是tb。
当注入语句
' order by 1; --
时,在后台被转换成下面的形式:
select * from tb where user_id = '' order by ; -- '
这里要注意几个点:第一,后台在转换SQL语句时,会自动添加一对单引号;第二,'--'是mysql数据库的单行注释符,而且第二个'-'后面一定要有一个空格(下面构造的SQL语句也是如此),这里它把后台添加的单引号注释掉了,所以数据库只执行了分号前面的SQL语句。
第二步:union 查询
现在已经知道了tb中有2个属性列,那么我们可以利用union来获得关于数据库的一些基本信息,比如
(1)查询当前用户和数据库名称
' and 1=2 union select user(),database(); --
结果如下
(2)查询数据库的版本信息和操作系统信息
' and 1=2 union select @@version,@@version_compile_os; --
这里要注意的是,必须保证union左右两边的select语句所查询的属性列数目相同,从前面我们知道,当前表中有2个属性列,所以在右边的select语句中,我们只能选择两个属性来查询,或多或少都会导致查询失败。另外,有几个关于查询的常用函数,分别是:@@version查询mysql的版本信息,user()查询用户名,database()查询数据库名称,@@datadir查询数据库路径,@@version_compile_os查询操作系统版本......可以根据自己感兴趣的信息来选择。
第三步:爆库爆表爆列
当mysql的版本大于5.0时,有个默认的数据库information_schema,里面存放着所有数据库的信息,比如数据库名、表名、列名等。
(1)爆库
' and 1=2 union select 1, schema_name from information_schema.schemata; --
上面的语句返回了information_schema数据库中schemata表的schema_name属性列,即是mysql中所有数据库的名称,结果如下
从结果中可以看到,目前的mysql有6个数据库。
(2)爆表
' and 1=2 union select table_schema,table_name from information_schema.tables; --
上面这条语句返回了各个数据库中的所有表名称,下面是部分截图的结果
现在我们知道了dvwa数据库中有两个表,分别是guestbook和users,下面我们构造SQL语句得到users表中的所有属性列。
(3)爆列
' and 1=2 union select table_name, column_name from information_schema.columns; --
上面的语句返回了各个表中的所有属性列,users表的结果如下:
现在我们知道了users表中的所有属性列名称了,我们可以查询自己感兴趣的东西,比如说用户的user_id和password
(4)爆密码
' and 1=2 union select user_id,password from dvwa.users; --
上面的语句返回了用户ID和其对应的密码,结果如下:
可惜密码被加密了,唉.....
因为我也是刚开始学习SQL注入,所以有错误是在所难免的,欢迎大家指正,谢谢!
2016-09-21