最佳实践
本文将展示在不同场景下的最佳编写实践和一些编写规范
相关定义
被动指纹(Passive)
- 不请求: 不写request结构
- / 请求, 无其它额外设置
- icon: 使用 getIconContent 函数
主动指纹(Active)
除被动指纹外的情况都属于主动指纹
编写规范(Prepare a specification)
1. 脚本应该通过 lint 的校验
1. 脚本应该通过 lint 的校验
目前 lint 会检查以下内容
- celcheck:用于校验 cel 语句是否能够运行,类型推到的结果是否正确。
- schemacheck:校验脚本内容是否符合编写的 json schema 格式,用于检测是否有必须填写的字段缺失。
- payloadcheck:检查每一个 payload 分支内声明的变量类型是否是一致的。
- transportcheck:校验 rule 中的请求是否符合规范。
- 相关细节以及对应修复方式请参考YAML插件修复手册
2. 将越常命中的规则放在越靠前的位置
2. 将越常命中的规则放在越靠前的位置
当存在多个‘或’逻辑的时候,系统会按序执行,直到命中一个才会停止,所以,将常命中的规则放在越靠前的位置能够有效的减少不必要的发包
3. 如无特殊需要,不编写主动指纹,避免请求量爆炸
3. 如无特殊需要,不编写主动指纹,避免请求量爆炸
被动指纹指的是只向根路径发包,或者只使用获取icon的函数进行指纹识别的指纹,而除了这两种情况,其他的都属于主动指纹。
4. 在使用关键字进行匹配时,要求使用包含产品特征的关键字,而且尽可能长,避免误报
4. 在使用关键字进行匹配时,要求使用包含产品特征的关键字,而且尽可能长,避免误报
例如匹配discuz的时候,关键词中最好带有该产品的特殊的内容,例如discuz_uid
等。
特别的:部分通用系统存在二次开发修改title的情况,因此title只能作为辅助判断的逻辑,只能算作加强规则,不能作为决定性证据
5. 当有多条被动指纹规则时,尽量使用&&组合两条规则,减少单条规则容易造成的误报
5. 当有多条被动指纹规则时,尽量使用&&组合两条规则,减少单条规则容易造成的误报
一般来讲,符合第四点的情况下,两条规则即可
6. 如无特殊需要,指纹规则中不带攻击特征,避免被 WAF 拦截
6. 如无特殊需要,指纹规则中不带攻击特征,避免被 WAF 拦截
一般有两种情况,一种是spring的访问/env等路径,有些时候会被拦;一种情况是path中带有admin,有些waf会拦截
7. 优先使用 contains、其次 icontains,减少运行过程中不必要的资源消耗
7. 优先使用 contains、其次 icontains,减少运行过程中不必要的资源消耗
icontains在匹配时会忽略匹配字母的大小写,增加资源消耗
8. 在处理所有的 404 页面时统一使用get404Path()函数获取路径
8. 在处理所有的 404 页面时统一使用get404Path()函数获取路径
get404Path函数做了一些特殊处理,这个函数可以保证一个目标将仅拥有一个404path,这样便于使用cache,降低发包,提高效率。
9. 如果能自动获取 icon, 尽量通过 getIconContent 来自动获取图标内容
9. 如果能自动获取 icon, 尽量通过 getIconContent 来自动获取图标内容
getIconContent函数可以在响应中获取icon地址,然后访问这个icon获取其字节流数据。
10. 取特征时,不要在header头Set-Cookie中取
10. 取特征时,不要在header头Set-Cookie中取
11. 尽量使用推荐的规则名称,当有多个同类规则时使用数字隔开
11. 尽量使用推荐的规则名称,当有多个同类规则时使用数字隔开
例如:kw_in_body_01、kw_in_body_02
12. 当存在多个版本匹配的规则的时候,建议使用payloads进行编写,提高插件的可阅读性,必要时可以使用三目运算符做判断
12. 当存在多个版本匹配的规则的时候,建议使用payloads进行编写,提高插件的可阅读性,必要时可以使用三目运算符做判断
详情参考:三目运算符的使用方式
通过 ICON HASH 匹配
favicon_hash
便捷计算icon hash的方式
使用示例:
使用示例:
使用示例:
使用内置函数自动搜索 ICON 路径
自定义 ICON 路径
通过内容MD5匹配
md5_in_[position]
通过 Body 关键字匹配
kw_in_body
基础模版(Basic templates)
匹配的字符串中包含引号(inverted comma)
忽略大小写(ignore capitals)
二进制内容匹配(binary)
通过 Header 关键字匹配
kw_in_header || kw_in_[header_name]