sql注入之floor薛定谔报错注入以及报错原理
之前已经简单介绍了sql注入的基本原理,接下来会按照sql注入的各种类型一一进行梳理,sql注入的常见主要分为回显注入、报错注入、bool盲注、延时注入、堆叠注入、二次注入、宽字节注入、http头注入、DNS LOAD注入。 sql注入的报错注入利用的是页面返回了数据库报错的内容,当回显注入无法使用时使用报错注入,可用的报错函数有很多,我会介绍常用的三种报错注入以及原理。floor报错,updatexml以及extarctvalue 输入单引号发现有sql报错,可以使用报错注入 floor报错注入
payload:and (select 1 from (select count(*),concat((database()),floor(rand(0)*2))x from information_schema.tables group by x)a)
代码括号有些多,我们逐一来理解,首先我们将最外层的括号去掉,不管第二层括号的内容,那么payload就变成 select 1 from ()a ,这句查询语句的意思是在a中查询1,a就是将括号中的内容变为一个整体,这就是一个普通的简单查询语句,然而是什么导致了他报错呢? 我们在来看内层括号的内容
select count(*),concat((database()),floor(rand(0)*2))x from information_schema.tables group by x
我们再将代码简化,不看concat括号内的内容
select count(*),concat()x from information_schema.tables group by x
这样就明了很多了,就是在information_schema.tables表中查询一个内容,并group by, group by 就是按照某种排序来创建一个虚拟表。查询到的内容逐个插入到这个虚拟表中并将这个内容设置为主键,如果出现内容重复,那么前面的count(*)计数器就会+1。 比如一个简单的表图左进行了select name group by name的操作,那么虚拟表就会如右图所示 如果说,右表中出现了两个相同的主键,那么数据库就会进行主键冲突的报错,再看我们之前省略掉的concat括号中的内容
concat((database()),floor(rand(0)*2))
其中floor为向下取整,rand()为随机数在0到1之间,而乘以2后就在0-1或者1-2之前,floor向下取整后这个数就是0或者1,比如database()为security那么括号中的内容就为security0或者security1。然后就按照内容不断插入到gourp by的虚拟表中。 然而当这个操作在进行的过程中,假如第一次随机并插入了security1并设置主键, floor函数有一个特性 第二次随机出的为security0,那么floor发现这个数之前没有出现过,就会在插入表之前迅速地再次随机出一个数,如果说随机出了security1,gourp by不会认为他是security1直接计数器加一,而是以为他还是security0,插入到表并设置主键,然而表中已经有一个security1了,在数据库表中主键是不能重复的,所以就会爆出主键冲突的错误。 但是我们不能保证第二次随机出的一定是0,所以就不会绝对出现报错,这也是floor又叫薛定谔报错的原因。但是我们在rand()中加入基数0变成rand(0),那么随机出的数就会有规律,就会绝对报错。 所以说在这个sql语句中主要是rand、floor、group by、concat这几个函数共同起作用导致的主键冲突报错