目录
报错注入
文章内容篇幅较长,请认真研读
回顾之前的文章(sql注入基础),了解到sql注入的分类有
基于正常回显
联合查询 union select
基于错误回显
floor()
extractvalue()
updatexml()
盲注
布尔型盲注
基于时间盲注sleep()
报错注入的前提
页面上没有显示位,但是需要输出SQL语句执行错误信息。比如mysql_error()
优点: 不需要显示位
缺点: 需要输出mysql_error()的报错信息
构造报错注入的步骤
1、构造目标数据查询语句
2、选择报错注入函数
3、构造报错注入语句
4、拼接报错注入语句
floor函数报错注入
利用union select 1,count(*) from information_schema.tables group by concat(0x7e,database(),0x7e,floor(rand(0)*2))导致数据库报错,通过concat函数连接注入语句与floor(rand(0)*2)函数,实现将注入结果与报错信息回显的注入方式。
rand()可以产生一个在0和1之间的随机数,直接使用rand函数每次产生的数值不一样,但当我们提供了一个固定的数字0之后,每次产生的值都是相同的。
提供数字0后
floor (rand(0)*2)函数
floor函数的作用就是返回小于等于括号内该值的最大整数即向下取整。
rand()本身是返回0~1的随机数,但在后面*2就变成了返回0~2之间的随机数。
配合上floor函数就可以产生确定的两个数,即0和1。
并且结合固定的随机数种子0,它每次产生的随机数列都是相同的值。
group by 函数,作用就是分类汇总。
count(*)函数作用为统计结果的记录数。
综合使用产生报错
报错原因分析
通过 floor 报错的方法来爆数据的本质是 group by 语句的报错。group by 语句报错的原因是 floor(rand(0)*2)的不确定性,即可能为 0 也可能为 1,group by key 执行时循环读取数据的每一行,将结果保存于临时表中。读取每一行的 key 时,如果 key 存在于临时表中,则更新临时表中的数据(更新数据时,不再计算 rand 值);如果该 key 不存在于临时表中,则在临时表中插入 key 所在行的数据。(插入数据时,会再计算rand 值)
如果此时临时表只有 key 为 1 的行不存在 key 为 0 的行,那么数据库要将该条记录插入临时表,由于是随机数,插时又要计算一下随机值,此时 floor(rand(0)*2)结果可能为 1,就会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值实际测试中发现,出现报错。
extractvalue()函数报错注入
extractvalue()函数作用:MYSQL对XML文档数据进行查询的XPATH函数。
语法: extractvalue(xml_document, xpath_string)
第一个参数:xml_document是string格式,为xml文档对象的名称
第二个参数:xpath_string (xpath格式的字符串)
extractvalue使用时当xpath_string格式出现错误,mysql则会爆出xpath语法错误
获取所有的数据库名
extractvalue(1,concat(1,(select group_concat(schema_name) from infomation_schema.schemata)))
注:页面没有显示全部的数据库名是因为一次返回最大为32位,当数据库名大于32,需要结合其他方式使用
即可以通过截取字符串的方式获取所有的数据库名(substr 1,29(从第一位开始截取29位))
extractvalue(1,concat(1,(select substr((select group_concat(schema_name) from infomation_schema.schemata),1,29)))) --+
updatexml()函数报错注入
updatexml()函数其实与extractvalue()函数大同小异,都是通过xpath路径错误报错
语法: updatexml(xml_document, xpathstring, new_value)
第一个参数:xml_document,文档名称
第二个参数:xpathstring (xpath格式的字符串),做内容定位。
第三个参数:new_value,string格式,替换查找到的符合条件的值
盲注
盲注:在sql注入过程中,sql语句执行select之后,可能由于网站代码的限制或者apache等解析器配置了不回显数据,造成在select数据之后不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个判断的过程称之为盲注
盲注分类
基于布尔盲注
基于时间盲注
前提条件:页面上没有显示位,也没有输出sql语句执行错误信息,只能通过页面返回正常或者异常来注入
优点:不需要显示位,不需要报错信息
缺点:速度慢,耗费大量时间
盲注时要掌握的几种函数
length()函数 返回字符串的长度
substr()函数 截取字符串
left()函数 得到字符串左部指定个数的字符
mid()函数 截取指定长度的字符串(与substr类似)
if(expr1,expr2,expr3)判断 如果第一个语句正确则执行第二个语句如果错误执行第三个语句
布尔盲注
1、手工注入
a、判断注入点
and 1=1 //正常
and 1=2 //异常
存在sql注入
b、判断列数
order by 2 //正常
order by 3 //异常
总共有两列
c、判断显示位
union select 1,2 //页面返回正常
union select 1,2,3 //页面返回异常
显示位有两位
d、猜解当前数据库字符长度
length((select database()))=6 //异常
length((select database()))=7 //正常
当前数据库字符长度为7
e、猜解数据库名第一个字符
substr((select database()),1,1)='a' --+ //异常
substr((select database()),1,1)='p' --+ //正常
说明数据库名第一个字符为p
f、猜解数据库名第二个字符
substr((select database()),2,1)='p' --+ //正常
页面回显正常,说明第二个字符为i,以此类推 得到数据库名为pikachu
2、burp suite跑盲注
猜解当前数据库名称
使用burp suite拦截模块获取信息
发送到intruder模块
对需要破解的地方添加标记
设置payload值
开始攻击
根据破解后的length可知数据库名第一个字符为p
注:当前采用的破解模式为sniper模式,即一次只使用一个payload位置,使用这种模式破解数据库名时需要一次次修改截取的字符串
获取数据库名的第二个字符
完成之后根据length长度可知第二个字符为i
以此类推得出数据库名称为pikachu
采用cluster bomb模式破解数据库名
设置payload值
开始攻击
根据标红的payload值可知当前数据库名为pikachu
时间盲注
在mysql下,sleep的语法如下:sleep(seconds)即sleep函数代码执行延迟若干秒
sleep()函数执行是有条件的,必须保障sql语句执行结果存在数据记录才会停止指定的秒数,如果sql语句查询结果为空,那么sleep函数不会停止
判断注入点
and 1=1 页面正常
and1=2 页面正常
页面的返回没有变化,有可能是盲注
使用sleep()函数判断是不是时间盲注
页面延时5s,说明是时间盲注
使用if语句和sleep()函数联合猜解数据库名称长度
and if(length((select database()))=6,sleep(5),0)
说明数据库名长度不是6
由时间线可知数据库名称长度为7
获取数据库名的第一个字符
通过截取字符串的方式获取数据库名的第一个字符,让它等于一个字母,根据时间来判断正确与否
可知数据库名第一个字符为p
以此类推得到数据库名为pikachu