视频教程(Video tutorial)
最基础的 YAML 插件
- 名称: 脚本名称, string 类型
- 脚本部分: 主要逻辑控制部分,控制着脚本的运行过程
- 信息部分: 主要是用来声明该脚本的一些信息,包括输出内容
YAML插件的脚本部分
传输方式(transport)
该字段用于指定发送数据包的协议。transport: string
形如:
- tcp
- udp
- http
- 端口存活探测的结果通常会知道它是 tcp 或者 udp 存活
- 或者从一个明确的 http 请求或者 web 站点开始
YAML插件主体的关键字的意义
-
rules以及单个rule的名称
- rules代表着一个规则集,在这个规则集中,将存放着所有要发送的信息以及要判断的规则
- rule则是一个请求的规则,代表你想要发送什么样的请求。如上述所举的例子中,r0,r1是规则的名称
-
request
该关键词中存在着构建一个请求包所要填写的信息,包括请求使用的方法,请求路径,请求头,请求body,是否跟随302跳转。
cache: bool
:是否使用缓存的请求,如果该选项为 true,那么如果在一次探测中其它脚本对相同目标发送过相同请求,那么便使用之前缓存的响应,而不发新的数据包method: string
:请求方法path: string
:请求的完整 Path,包括 querystring 等 (详情见: HTTP PATH 的使用)- 如果 path 是以
/
开头的, 取 dir 路径拼接 - 如果 path 是以
^
开头的, uri 直接取该路径
- 如果 path 是以
headers: map[string]string
:请求 HTTP 头,Rule 中指定的值会被覆盖到原始数据包的 HTTP 头中body: string
:请求的Body(转译问题见:头疼的转译)follow_redirects: bool
:是否允许跟随300跳转, method为GET或者HEAD时,该选项为true时,其他情况为false。
-
expression
在rule下的
expression
是用来对返回包(response)进行匹配的,你可以编写各种各样的限制来判断返回包中信息,从而确认返回的内容是否符合要求。 正如spring使用SpEL表达式,struts2使用OGNL表达式,xray使用了编译性语言Golang,所以为了实现动态执行一些规则,我们使用了Common Expression Language (CEL)表达式:CEL表达式通熟易懂,非常类似于一个Python表达式。上述表达式的意思是:返回包的status等于200,且body中包含内容“Example Domain”。 expression表达式上下文还包含有一些常用的函数。比如上述bcontains
用来匹配 bytes 是否包含,类似的,如果要匹配 string 的包含,可以使用contains
, 如: 值得注意的是,类似于python,CEL中的字符串可以有转义和前缀,如:(详情见:头疼的转义)'\r\n'
表示换行r'\r\n'
不表示换行,仅仅表示这4个字符。在编写正则时很有意义。b'test'
一个字节流(bytes),在golang中即为[]byte
response.body_string.contains('test')
返回包 body 包含 test,因为 body 是一个 bytes 类型的变量,所以我们需要使用 bcontains 方法,且其参数也是 bytesresponse.body_string.contains(r1 + 'some value' + r2)
r1、r2是 randomLowercase 的变量,这里动态的判断 body 的内容response.content_type.contains('application/octet-stream') && response.body.bcontains(b'\x00\x01\x02')
返回包的 content-type 包含 application/octet-stream,且 body 中包含 0x000102 这段二进制串response.content_type.contains('zip') && r'^PK\x03\x04'.bmatches(response.body)
这个规则用来判断返回的内容是否是zip文件,需要同时满足条件:content-type 包含关键字 “zip”,且 body 匹配上正则r’^PK\x03\x04’(就是zip的文件头)。因为 startsWith 方法只支持字符串的判断,所以这里没有使用。response.status >= 300 && response.status < 400
返回包的 status code 在 300~400 之间(response.status >= 500 && response.status != 502) || "<input value=\"(.+?)\"".matches(response.body_string)
返回包status code大于等于500且不等于502,或者Body包含表单response.headers["location"]=="https://www.example.com"
headers 中Location
等于指定值,如果Location
不存在,该表达式返回 false'docker-distribution-api-version' in response.headers && response.headers['docker-distribution-api-version'].contains('registry/2.0')
headers 中包含docker-distribution-api-version
并且 value 包含指定字符串,如果不判断in
,后续的 contains 会出错。response.body_string.contains(response.url.path)
body 中包含 url 的 path每一个expression表达式都会返回一个bool结果,然后在存在&&
或||
的时候,与其他的expression表达式做运算,最终出一个结果,最终结果如果为true,则代表这个规则命中。
与rules同级的expression的使用
对于脚本层级的 expression,这个结果作为最后脚本是否匹配成功的值,通常脚本层级的 expression 是 rule 结果的一个组合。 比如一个脚本包含r1
, r2
, r3
,r4
4 条规则, 作为脚本层级的 expression,其全局变量将会定义 r1
, r2
, r3
, r4
4 个函数,调用这个 4 个函数即可获得它对应 rule 的结果。
r1
, r2
, r3
,r4
4 条规则
最开始时, V1 版本添加了 rules: []Rule
来定义 rule 及其执行顺序。其逻辑为顺序执行 rule, 且 r1
, r2
, r3
,r4
都为 true 时, 脚本执行成功
group: map[string][]Rule
拓展了一下 ruel 的执行方式。支持了 r1,r2 同时为 true 或者 r3, r4 同时为 true 时, 脚本执行成功
- rule 的执行顺序是按照该逻辑表达式的执行顺序来执行的
短路求值
, 即r1() || r2()
, 如果r1()
的结果为 true 那么 r2 是不会执行的
set关键字的使用
todo:补充高级用法链接 该字段主要是用来定义一些在接下来的规则中会使用到的一些全局变量,比如随机数,反连平台等。set: map[string]interface{}
payload关键词的使用
todo:补充高级用法链接 该字段用于定义多个 payload,来实现发送不同 payload 的效果。 该字段结构如下变量名/函数名 | 类型 | 说明 |
---|---|---|
continue | bool | 命中一个之后是否继续 |
payloads | map[string]Set | 和 set 一样的结构和语法 |
- 只支持罗列
payload
, 目前不考虑支持文件或者复杂排列组合等情况,每个payload
中的key
必须严格一致 - 循环 payload 然后把当前 payload 加在 set 之后,组成新的 set 执行
output与search的组合使用
todo:补充高级用法链接- 获取返回的token
- 获取上传文件后返回的文件路径
- 总结:获取所需要的参数
YAML插件的信息部分
todo:补充高级用法链接 该字段用于定义一些和脚本相关的信息。 目前主要定义了一下几个部分: 注:其中支持变量渲染,形如{{version}}
, 其中变量为 set 或者 rule output 中定义的变量