type
status
date
slug
summary
tags
category
icon
password

盲注

  • 再SQL注入过程中,SQL语句执行后,选择的数据不能回显到前端页面,此时需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
  • 再盲注中,攻击者根据其返回页面的不同来判断信息(可能是页面内容的不同,也可以是相应时间不同)。一般情况下,盲注可分为两类:
    • 基于布尔的盲注(Boolean based)
    • 基于时间的盲注(Time based)

基于布尔的盲注

  • 某些场合下,页面返回的结果只有两种(正常或错误)。通过构造SQL判断语句,查看页面的返回结果(True or False)来判断哪些SQL判断条件成立,通过此来获取数据库中的数据。

基于时间的盲注

  • 又称延时注入,即使用具有延时功能的函数sleep,benchmark等,通过判断这些函数是否正常执行来获取数据库中的数据。

SQL盲注常用函数

条件语句

数据库服务器
查询
Microsoft SQL Server
IF(’a’=’a’) SELECT 1 ELSE SELECT 2
MySQL
SELECT IF(’a’,1,2)
Oracle
SELECT CASE WHEN ‘a’=’a’ THEN 1 ELSE 2 END FROM DUAL SELECT decode(substr(user,1,1),’A’,1,2) FROM DUAL
PostgreSQL
SELECT CASE WHEN (1=1) THEN ‘a’ else ‘b’ END
notion image
if()
功能:条件判断
语法格式:if(expr1,expr2,expr3):expr1 为true则返回expr2,expr1为false则返回expr3
注:仅MySQL支持if(expr1,expr2,expr3)
notion image
left()
功能:截取具有指定长度的字符串的左边部分
语法格式:left(str,length),如果str或length参数为NULL,则返回NULL值
参数说明
  • str:要提取子串的字符串
  • length:正整数,指定将从左边返回的字符数。length为0或为负,则LEFT返回一个空字符串,length大于str字符串的长度,则left()返回整个str字符串。
notion image
length()
功能:返回字符串的长度,以字节为单位
语法格式:length(str)
notion image
substr(),substring()
功能:从指定的位置开始,截取字符串指定长度的子串
语法格式:substr(str,pos)或substr(str,pos,len),substring(str,pos)或substring(str,pos,len)
参数说明
  • str:要提取子串的字符串
  • pos:提取子串的开始位置
  • len:指定要提取的子串
notion image
ascii(),ord()
功能:返回字符串最左边字符的ASCII码值
语法格式:ascii(str), ord(str)
notion image
cast(),convert()
功能:获取一个类型的值,并产生另一个类型的值
语法格式:cast(value as type),convert(value,type)
可转换的值类型
  • 二进制,同带binary前缀的效果:BINARY
  • 字符型,可带参数:CHAR()
  • 日期:DATE
  • 时间:TIME
  • 日期时间型:DATETIME
  • 浮点数:DECIMAL
  • 整数:SIGNED
  • 无符号整数:UNSIGNED
notion image
 
延时函数sleep()
功能:让语句延迟执行一段时间,执行成功后返回0
语法格式:sleep(N),即延迟执行N秒
notion image
延时函数benchmark()
功能:让某语句执行一定的次数,执行成功后返回0
语法格式:benchmark(count,expr),即让expr执行count次
注:仅MySQL支持该函数
notion image

基于布尔的盲注实例

给定一个?id=1的参数,此时页面显示信息为You are in…,显示状态为True
notion image
给定一个?id=-1的参数,此时页面显示信息为空,显示状态为False
notion image
 
寻找注入点
分别使用以下3条payload寻找注入点及判断注入点的类型:
notion image
notion image
以上可判断存在字符型注入点
 
盲猜网站当前所在数据库的库名长度
假设当前所在数据库的库名长度为N,尝试使用判断语句length(database())=M,不断变化M的值去猜测,如果M不等于N,页面应该显示为False;如果M等于N,页面应该显示为True。
notion image
notion image
显示结果为True,说明网站当前所在数据库的库名长度为8个字符
 
盲猜网站当前所在数据库的库名字符串
通过逐个字母盲猜的方式进行
假设库名字符串的第1个字母为a,那么条件判断语句 substr(库名字符串,1,1)=‘a’ 以及 ascii(substr(库名字符串,1,1))=97 返回的结果均应为True(小写字母a的ASCII码为97);
假设库名字符串的第2个字母为b,那么条件判断语句 substr(库名字符串,2,1))=‘b’ 以及 ascii(substr(库名字符串,2,1))=98 返回的结果均应为True(小写字母b的ASCII码为98);
库名的第1个字母为s
notion image
库名的第2个字母为e
notion image
以此类推,最终得到的字符串结果为security
 
盲猜数据库security的全部表名
猜测第1张表的表名的第1个字符:
第1张表的表名的第1个字符为e
notion image
猜测第1张表的表名的第2个字符:
第1张表的表名的第2个字符为m
notion image
以此类推,得到security库中的第1张表的名字为emails
 
猜测第2张表的表名
猜测第2张表的表名的第1个字符:
第2张表的表名的第1个字符为r
notion image
猜测第2张表的表名的第2个字符:
 
第2张表的表名的第2个字符为e
以此类推,得到security库中的第2张表的名字为referers。
依据上述方法,通过不断变换limit和substr()函数中的参数,可以最终得到security库中所有表的表名:emails、referers、uagents和users。其中,第4张表users当中可能存放着网站用户的基本信息。
 
盲猜users表的全部字段名
猜测第1个字段名
猜测第1个字段名的第1个字符:
第1个字段名的第1个字符为i
notion image
猜测第1个字段名的第2个字符:
第1个字段名的第2个字符为d
notion image
以此类推,得到users表中的第1个字段名为id。
依据上述方法,通过不断变换limit和substr()函数中的参数,可以最终得到users表中所有字段名:id、username和password。
 
盲猜users表username和password字段的全部值
猜测第1组数据
猜测第1组数据的第1个字符:
第1组数据的第1个字符为D
notion image
猜测第1组数据的第2个字符:
第1组数据的第2个字符为u
notion image
以此类推,得到第1组数据为“Dump,Dump”
注意:字符串中的逗号(,)也是需要进行猜测比对的!例如第1组数据的第5个字符:
notion image
猜测第2组数据
猜测第2组数据的第1个字符:
第2组数据的第1个字符为A
notion image
猜测第2组数据的第2个字符:
第2组数据的第2个字符为n
notion image
以此类推,得到第2组数据为“Angelina,I-kill-you”。
依据上述方法,通过不断变换limit和substr()函数中的参数,可以最终得到users表中username和password字段的全部值。
 
SQL注入总结报错注入
Loading...