SQL注入--报错和盲注

目录

报错注入

        floor函数报错注入

        extractvalue()函数报错注入

        updatexml()函数报错注入 

盲注

 布尔盲注

 时间盲注


报错注入

文章内容篇幅较长,请认真研读

回顾之前的文章(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


版权声明:本文为qq_57307348原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。