官方文档 序列前置知识之高级配置 | Yak Program Language
本文章多以编写yaml模版的视角来解释
规则一览
匹配器
在编写yaml中会使用到这里两个东西
点击添加会在返回包的右下角出现匹配器
上面有三个过滤器模式,官方解释
-
丢弃:丢弃模式会在符合匹配器时下丢弃返回包。
-
保留:保留模式会在符合匹配器时保留返回包,剩余的返回包则直接丢弃。
-
仅匹配:仅匹配模式会在符合匹配器时将对应的返回包染色,而不做其他操作。
也就是匹配器是只会对返回包做匹配,一般是在做fuzz的情况下,将符合预期返回结果做标记或者染色和丢弃
匹配类型的官方介绍
-
关键字:关键字就是在匹配位置中匹配输入的关键字。
-
正则表达式:正则表达式就是在匹配位置中匹配输入的正则表达式。
-
状态码:(忽略匹配位置)状态码就是匹配响应的状态码,我们只需要填写希望匹配到的状态码即可。
-
十六进制:在某些情况下,希望匹配的字符串不是正常可见的ascii码,这时候你就可以使用十六进制这种匹配类型,输入十六进制字符串(例如字符串"302"对应十六进制字符串"333032")。
-
表达式:(忽略匹配位置)表达式可以更加灵活地编写我们所希望的匹配规则,它还能与后续要讲的 高级配置:变量 联动。表达式的语法与nuclei-dsl语法兼容,熟悉nuclei工具的师傅可以尝试在表达式中编写一些复杂的匹配规则。一个匹配响应体中是否存在对应字符串的例子如下:
contains(body,'302 Found')
。附上官方语法手册 https://docs.projectdiscovery.io/templates/reference/helper-functions
使用场景 报错SQL注入
报错注入打印出md5(1)的值,返回的数据包中如果存在0x06d49632c9dc9bcb62aeaef99612ba6b 就代表漏洞存在
直接添加要匹配的值为0x06d49632c9dc9bcb62aeaef99612ba6b 后点击添加匹配内容,在此场景下匹配响应体,只有一个条件的话上面和下面的条件关系无所谓选择都可以,然后调试执行一下,能匹配到就是成功,然后应用此规则,再将将数据包生成为yaml的raw模版
基本达到了yaml中常用的sqli报错的检测要求
当然还可以继续进行多条件的匹配,比如在精确一点,匹配状态码是200
第一个关键字的匹配点击添加条件后就可以进行匹配第二个条件,这里选择状态码,值为200,也可以调试执行一下。
再解释一下,右上角的条件关系为两个不同id对应的匹配的规则的条件,这里是and就代表既要匹配到状态码为200也要匹配到关键字0x06d49632c9dc9bcb62aeaef99612ba6b,而关键字中的条件关系是为了在此匹配条件中多匹配几个
比如我这里修改为or然后 我下面在多添加一个匹配内容为404,意思就是这个条件匹配状态码可以是200也可以是404,都是符合条件的。
好了,此时应用我们的匹配器生成yaml看一下效果
这里在细说一下这里的 matchers-condition: and 意思就是下面两个规则要都为真才匹配到 ,然后就是condition: and 没啥用可以删除了,毕竟这里我们只匹配了一个关键字。
数据提取器
数据提取器顾名思义就是提取数据,比如需要从返回包中提取某个值,提取得到的值再会被用到其他地方,否则提取了数据干嘛是吧
这里有5种提取方式
官方解释
-
正则表达式:正则表达式就是在提取位置中提取输入的正则表达式匹配到的内容。我们知道在正则表达式中可以使用小括号来分组,这时候我们可以在匹配正则分组中选择分组,这样就可以提取到想要的内容了。(在正则表达式中,0分组即为正则表达式匹配到的所有内容)
-
XPath:(提取范围只能是响应体)XPath就是在提取位置中提取输入的XPath匹配到的内容。XPath是一种用于在XML文档中选择节点的语言,我们也可以很轻易地使用浏览器开发工具来复制完整的Xpath。
-
键值对:键值对的提取规则稍微有点复杂。键值对会尝试提取所有可能存在的json的key对应的value,以及所有形似
key=value
中value的值。如果提取位置包含响应头(提取范围为响应头或Raw),则他还会尝试提取响应头中的value值。另外还有两个特殊的键值对,分别为proto
,status_code
,分别对应响应的HTTP协议版本和响应状态码。 -
JQ(*):(提取范围只能是响应体)jq是一种用于在JSON文档中选择节点的工具,其对应的文档教程在此。
-
表达式:(忽略匹配位置)表达式与上面匹配器中的表达式相同,这里不再赘述。
另外提取范围中的raw就是原始响应,可以理解为全部响应的数据包
可以看到官方已近明确的告诉了我们不同的提取类型的提取范围是不同的
正则表达式就不需要我过多了介绍了,只要规则写的好没有匹配不到的
xpath一般用于html之类的返回内容中进行提取,需要先去了解一下xpath的提取规则,写过爬虫的应该都学过
键值对就是key:value的形式,和我们这里的例子刚好相同,这里就演示一下
设置好后可以先调试执行一下
可以看到会将Type的值提取出来
JQ(*) 是专门用来处理json格式的,在此场景也可以使用
他的格式也比较简单,可以去网上简单的学习一下
表达式就不说了,还不是很会,可以去看官方的手册
变量
先解释一下在yakit中的变量是什么,从前面的匹配器我们可以获取到一个值,这个值就是我们能用的变量,当然,不止是提取到的,还有一些其他的变量,比如之前说过的fuzztag。
三个模式的官方解释
-
nuclei:nuclei模式下,其变量值实际上是nuclei的表达式,可以调用绝大部分nuclei-dsl中包含的函数。需要注意的是,当你引用其他变量时,其的值都是string类型,所以可能需要手动进行类型转换。一个简单的例子如下:
{{int(a)+3}}
。 -
fuzztag:fuzzta模式下,其变量值实际上就是fuzztag,在值中使用fuzztag也会使得Web Fuzzer发送多个请求包。一个简单的例子如下:
{{int(1-2)}}
。 -
raw:raw模式下,变量值相当于你输入的字符串,不会被解析。
变量可以在后续变量,Web Fuzzer序列和当前Web Fuzzer中使用。我们可以通过使用fuzztag:{{params(变量名)}}
或{{p(变量名)}}
来使用变量。
比如使用raw
添加一个UA : WindowsOS
在数据包中使用{{p(UA)}}来使用这个变量,实际的传输中发出的是User-Agent: WindowsOS
使用fuzztag
fuzztag函数官方 功能集:fuzztag - 模糊测试标签 | Yak Program Language
比如这里我使用{{int(1-2)}} 意思是生成1和2两个数,可以看到他分别发出了两个包分别是1和2
使用nuclei
nuclei的一些内置函数官方手册 https://docs.projectdiscovery.io/templates/reference/helper-functions
rand_int(1, 10) 随机生成一个数字
同样的方式也可以,右键详情看一下具体的包,随机数是1
如果要写生成yaml模板,这里变量就必须使用nuclei的。
后续的get和post还有其他的就没必要讲了,都是写死的参数可以直接写在数据包中。