背景
在 Web Fuzzer 中,我们实现 BurpSuite Intruder 的代替是使用一种名字叫 Fuzztag 的全新机制,这种机制在以前并没有出现在任何安全工具和产品中,因此它对于绝大多数人来说是 “船新” 的。
实际在使用中,Fuzztag 并没有给大家带来太多麻烦的学习成本,其简单的语法和快速交互解决了各种 “配置” 的过程。
但是因为早期版本 Fuzztag 的技术实现比较简单,纯正则编译+分阶段编码有很多的额外限制,造成了不必要的理解成本,我们在 v1.1.3-sp4以后的版本中,对 Fuzztag 的底层机制进行了完全的重构,使用编译原理的技术实现定制的 Lexer 和 Parser,实现了一套可嵌套递归执行 Fuzztag 表达式模版语言。
Yaklang Fuzztag 是什么?
这是一种可以把字符串进行一定规则渲染变形的模版表达式语言,这种语言标记以{{
开头,}}结尾,中间包含规则的具体名称和参数,执行的结果为 n 个原字符串的变形。
以 Antlr4 Grammar 风格的语法定义:
expr = data '{{' identifier ( '(' expr ')' )? '}}'data
简单来说,如果我们想要生成
payload-1
payload-2
payload-3
payload-4
payload-5
那么,我们仅需要编写的 Fuzztag 表达式为payload-{{int(1-5)}}
从字面意思理解,我们这个表达式以 payload- 开头,遇到 {{int(1-5)}}我们按字面意思理解为,在这儿生成 1-5 这五个整数。因此,他的结果为 [1 2 3 4 5]我们和 payload- 进行组合,可以得到结果为:
payload-1
payload-2
payload-3
payload-4
payload-5
五分钟学会 Fuzztag
1.快速开始:使用 Fuzztag 生成整数列表爆破
最简单的情况,如果我们要进行一个参数位置的 ID 遍历,一般来说,我们比如 url 为
https://www.example.com/order.php?id=1
那么,我们要对 id 进行遍历,需要编写的 tag 为 {{int(1-100)}}即可生成 100 个 url,但是对于用户来说,只编写了:
https://www.example.com/order.php?id={{int(1-100)}}
与此同时,如果这个 ID 带了前缀呢?
简单修改为 https://www.example.com/order.php?id=myPrefix{{int(1-100)}}
可生成一系列的相关 URL:
https://www.example.com/order.php?id=myPrefix1
https://www.example.com/order.php?id=myPrefix2
https://www.example.com/order.php?id=myPrefix3
...
https://www.example.com/order.php?id=myPrefix99
https://www.example.com/order.php?id=myPrefix100
1.1爆破固定位整数:使用 0 左值填充[001, 002, 003...999]
很多时候,爆破的时候,整数位数应该是固定的,那么我们怎么变形生成更完整的 payload 呢?
通过简单的变形,我们在参数后增加一个 |3=>{{int(1-999|3)}} 可以指定要填充的位数。
https://www.example.com/order.php?id=myPrefix{{int(1-999|3)}}。
可以生成如下内容:
https://www.example.com/order.php?id=myPrefix001
https://www.example.com/order.php?id=myPrefix002
https://www.example.com/order.php?id=myPrefix003
...
https://www.example.com/order.php?id=myPrefix998
https://www.example.com/order.php?id=myPrefix999
最基础的整数使用如上,当然,实战情况大家更容易能体会到这样的操作带来的方便。
我们简单地通过一个标签,可以发送批量的请求来进行测试。
2.举一反三:用户名密码爆破
当然,仅仅知道{{int(...)}}标签并不能帮助我们完成所有的工作内容,我们对 Yaklang 支持的 Fuzztag 进行了一些总结,地址我们放在了这里
《https://yaklang.com/docs/newforyak/fuzztag》
一些简单的字面量和编码生成的函数我们在链接中都可以找到,那么我们除了上述的功能之外,我们需要能解决另外一些问题,“使用字典” 或者使用 “文件字典”。
最典型的,如果我们要使用一个文件,把它按行解析,可使用{{file:line(/tmp/dict.txt)}}
当然,如果你是 Yakit 的用户,在上传过字典之后,可以通过{{x(dictname)}}。
所以,如果原文内容是:
https://www.example.com/login.php?username={{file:line(/tmp/user.txt)}}&password={{file:line(/tmp/pass.txt)}}
即可快速生成针对用户名和密码爆破的数据包 URL。
例如,如果字典文件存在的话,执行内容为:
https://www.example.com/login.php?username=admin&password=admin
https://www.example.com/login.php?username=admin&password=admin123
https://www.example.com/login.php?username=admin&password=123456
...
...
https://www.example.com/login.php?username=root&password=admin
https://www.example.com/login.php?username=root&password=admin123
https://www.example.com/login.php?username=root&password=123456
...
...
在实际 Web Fuzzer 使用中,我们可以很容易地做到如下内容:
我们使用了内置的 top10 用户名与 top25 的密码字典,组合了 250 个请求发送出去,对网站进行了批量请求,在 Response 列表中,实现了多种内容的爆破和查看。
3.标签的嵌套:变形 + 编码 + 动态数量
很多时候,仅仅单个标签并不能满足实际需求,例如我们经常需要对一个值进行 base64,以往我们都需要编写脚本来实现这个功能,实际上,我们在 Yaklang.Fuzztag 中将会非常容易处理这个功能,整个过程非常简单。
{{base64({{int(1-10)}})}}
/*
MQ==
Mg==
Mw==
NA==
NQ==
Ng==
Nw==
OA==
OQ==
MTA=
*/
在 Codec 中,我们可以很容易地编写一个 tag 来实现上述功能。
3.1缩进让嵌套更加可读
同时由于 Fuzztag 本质上是通过标签执行来做的,在标签内部,为了方便内容编写,可以在恰当的地方控制锁进,让你的 Fuzztag 看起来更简单优雅,正如下面看到的内容,括号的前后是可以允许任意缩进的。
{{base64
({{int
(1-5)
}})
}}
但是值得注意的是,括号内的内容应该为具体的编码的内容,包含换行等空白符号,所以在括号内(...)换行需要谨慎,不然很容易在编码内容中加入多余的空白符或者换行符。
3.2在 Fuzztag 中使用编码转义:)
一般来说,我们经常要编码特殊的 JSON 字段内容,但是在数据中,很有可能出现特殊字符和 Fuzztag 冲突的情况,这种情况下,我们通过 ) 来转义一下,告诉 Fuzztag 的数据段中,不要闭合数据。
例如,我们想要编码println(123)这个字符串内容,一般来说我们会编写{{base64(println(123))}}希望他输出println(123)的base64编码cHJpbnRsbigxMjMp。
但是实际上,上述标签无法执行成功,因为 ) 和标签参数闭合的时候冲突了!
那我们如何解决这个问题呢?在yaklang-v1.1.3-sp6中,我们实现了针对 ) 的转义功能。可以很容易解决上述提到的问题。
只需要把标签改成{{base64(println(123))}}就大功告成了!
3.3高级嵌套特性
当然标签的嵌套其实是很自然的过程,他理论上可以无限嵌套,但是需要注意的是,嵌套如果发生在标签名中,不保证可以正常工作。
所以说,我们看得到,嵌套是可以实现在任何 “参数段” 的,我们以一个非常有意思的嵌套按理来说:
Union-SQL 注入 Payload 生成
我们在 SQL 注入测试 Union 的时候,很有可能要生成若干个 Union Select ... 来猜测注入表的列数,比如
union select 1,1
union select 1,1,1
union select 1,1,1,1
...
那么,根据结果反推我们应该如何编写 Fuzztag?
union select {{
repeatstr(1,|{{
int(1-10)
}})
}}1
特殊 Fuzztag
Fuzztag 的本质实际上是对一个标签的执行,那么这个过程理论上和执行 “函数” 行为是完全一致的,为了满足更多的特殊需求:
1.热加载场景:配合一段 Yaklang 的代码进行使用 {{yak}} 热加载标签
2.在 Yak 脚本编写中,使用 {{params}} 标签来控制参数执行
3.Yakit 用户可以通过 {{codec}} 调用 Codec 类型插件
小总结
在过去的一年中,Fuzztag 作为 Yakit 一开始就携带的特性,已经陪很多师傅完成了很多工作内容。与此同时,Fuzztag 自身也在不断进化,从一开始只支持少量标签的场景,到后来支持复杂的热加载 Yak 代码编辑系统,再到支持 Web Fuzzer 的自动补全以及无限嵌套。
随着用户增多,场景和稳定性也逐渐增强。
在之后的发展中,Fuzztag 的文档和实战案例将更加丰富,这是一个简单实用且有效的技术,希望能通过这些简单的手段脱离大家对 BurpSuite Intruder 的依赖,更高效地完成工作内容!
往期推荐>>
新功能:史上最好用的反连&JavaHack,安全能力基座强化ing
插件分析|Yaklang SQL Injection 检测启发式算法
你们要的 [Yaklang websocket劫持]教程来了!
原文始发于微信公众号(Yak Project):安全基础设施:用Fuzztag优雅地生成与变形任何Payload
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论