SQL-堆叠注入(含例题)
了解一下
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1
;DELETE FROM products
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
简单来说就是可以一起执行sql语句,看这个小例子你就明白了
不过在真实网站中,这种情况非常少见,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行一条语句,分号后面的内容将不会被执行,所以并不用担心。但是在一些CTF中会经常作为基础的考察。
适用条件
这里的适用条件更多的是针对CTF提出的
正常sql语句:Select * from users where id=’1’’;
注入sql语句:Select * from users where id=’1’;select
if(length(database())>5,sleep(5),1)%23;
Payload= ‘;select if(length(database())>5,sleep(5),1)%23
Payload= ‘;select if(substr(user(),1,1)=‘r’,sleep(3),1)%23
如此句:从堆叠注入语句中可以看出,
第二条SQL语句(select if(substr(user(),1,1)=‘r’,sleep(3),1)%23
就是时间盲注的语句。
堆叠注入和union的区别在于,union后只能跟select,而堆叠后面可以使用insert,update, create,
delete等常规数据库语句
针对一些强限制,但;
保留的一些情况,特殊闭合等等。
例题(buuctf SUCTF-easysql)
打开后就是这样,输入字母直接消失,扫描目录429拒绝,探测全真语句返回为"nonono"
在输入数字后得到提示:
得到的信息十分有限,并且只要很多东西都返回nonono,布尔也不能形成。
看得出来,许多关键字都被屏蔽了,如果可以堆叠注入,那就可以使用很多其他语句。
尝试一下:1;show databases
果然可以
show tables;
看起来已经离目标很近了。
但是当你输入select * from Flag
时,又回到了nonono。
这里非常考验细节和经验,在一开始为什么输入1及以上的数字,返回出来的值一直是1,但是输入00时,返回的就是0
如果你比较熟悉mysql就知道,如果你使用select 1 from xxx;
,得到的就是一列1
数字不同,返回的值也不同,简单的小例子:
相信你已经明白了,也就是说这里也在不断返回数字,但是只有0,1
这两种,又和输入的00,1
有关,那么很有可能在这里面有&&
或者||
,两个值经过了某种和,与
运算,最后只能落到0,1
上
但是你能够确定的是,这里已经使用了一种select结构,我们可以直接使用*
来接上,然后保持后面的结果为1
,这样就可以直接select * ,1 from xxx;
就相当于:
相信你已经懂了
所以payload为:
*,1
可以大概推测到语句应该是:
select ($query)||flag from Flag;
建议带着这个语句再理解一遍前面的现象。
注:0探测为什么不是0,应该是对0有屏蔽,不让做题者看出来是或
但是你多次试试 00还是能够探测出来