先说手法,借助rand(exp()),即可通过是否报错就行判断,然后通过ord(mid(version()from(1)for(1)))获取信息
简单说一下注入情况,排序注入,参数有两种(其实也可以说是一种)descs和ascs,可以输入多个以,分割的字段进行排序,而根据参数名,会自动在字段后面加上DESC或者ASC,举个例子看一下就清楚了(一波厚码)

再记一下过滤情况,先说特殊字符。首先由于上面说的参数的特性,直接就被过滤了,然后是*、%0a、%09、%a0、%0B, %0C,%0D、%20、"、'全部被过滤,除了,其他的过滤是用的删除该特殊字符的方式进行过滤


再说说关键字,过滤得不算多,目前发现select,exp,sleep用不了,但是由于不能使用**,**所以很多函数其实用不了,比如locate,if,在由于不能使用空格,导致case when也用不了,关键字这块,如果检测到关键字,直接给返回正常响应。
常规的东西也处理了

bypass方法
rand(exp(1)),而exp(710)会报错,虽然exp()被过滤,但是rand(exp())没有过滤,当exp()里的数字大于710时,会报错“Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: DOUBLE value is out of range in ‘exp(710)’\n; Data truncation: DOUBLE value is out of range in ‘exp(710)’”

其实这里还有一个报错,exp(43),exp(44),,43的时候正常响应,44会报错“BIGINT value is out of range in ‘exp(44)’\n; Data truncation: BIGINT value is out of range in ‘exp(44)’”
报错原因也是因为BIGINT,但是具体原因我还不清楚

更新一下,这个是版本原因导致的,docker起了一个接近的版本8.4.6,测试了一下发现确实报错,而5的版本就不会

现在有了触发点,可以通过控制exp内的数字来进行报错注入,接下来需要爆一个version出来验证一下危害。
由于先使用length找一下长度,
- 1,rand(exp(44/length(version())))

控制分母的大小,让他除以version的长度,即可作为爆数据的口子
通过简单计算,找到218和219,然后得到version()长度为5



这块逻辑有点乱,后面想了一下,直接用44 x m /n就好了,因为44的时候会报错,所以选择44的倍数作为分母,报错的那个倍数就是目标数字,比如在爆破长度的时候,176是44的4倍,220是5倍,220的时候报错,176/5=35.2 220/5=44。所以version的长度就是5

接下来是获取version的具体字符
因为需要处理字符串,而由于,无法使用,所以这里我用的mid和from to
- ord(mid(version()from(1)for(1)))
然后写了一个脚本,如下
1 | import requests,json |

得到版本为8.4.4
另外附一张acsii表

参考资料
https://wooyun.js.org/drops/MySQL%E6%B3%A8%E5%85%A5%E6%8A%80%E5%B7%A7.html