漏洞验证框架的构思与实现(二)
字数 909 2025-08-05 08:19:29

漏洞验证框架的构思与实现(二)——规则体系详解

0x01 前言

本文是漏洞验证框架系列的第二篇,重点介绍框架的核心模块:规则体系。该框架在兼容xray规则的基础上进行了扩展,实现了更灵活的漏洞检测机制。

0x02 原始请求来源

框架支持三种原始请求构造方式:

1. 基于URL构造请求

func GenOriginalReq(url string) (*http.Request, error) {
    // 生成原始请求,如果没有协议默认使用http
    if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
    } else {
        url = "http://" + url
    }
    originalReq, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Error("util/requests.go:GenOriginalReq original request gen error", url, err)
        return nil, err
    }
    originalReq.Header.Set("Host", originalReq.Host)
    originalReq.Header.Set("Accept-Encoding", "gzip, deflate")
    originalReq.Header.Set("Accept","*/*")
    originalReq.Header.Set("User-Agent", conf.GlobalConfig.HttpConfig.Headers.UserAgent)
    originalReq.Header.Set("Accept-Language","en")
    originalReq.Header.Set("Connection","close")

    return originalReq, nil
}

2. 基于原始HTTP报文文件构造请求

func GenOriginalReqFromRaw(filePath string) (*http.Request, error)  {
    raw, err := ioutil.ReadFile(filePath)
    if err != nil {
        c.JSON(msg.ErrResp("请求报文文件解析失败"))
        return nil, err
    }

    oreq, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(raw)))
    if err != nil {
        return nil, err
    }
    if !oreq.URL.IsAbs() {
        scheme := "http"
        oreq.URL.Scheme = scheme
        oreq.URL.Host = oreq.Host
    }
    return oreq, nil
}

3. 通过代理监听获取请求

类似于xray的浏览器代理模式

0x03 兼容xray规则体系

CEL表达式实现

xray的规则体系基于Common Expression Language (CEL)实现,使用cel-go包:

  1. 构建CEL环境:初始化cel.Env
  2. 注入类型和方法:实现xray文档中所有变量和方法
  3. 计算表达式:传入表达式、环境和变量列表
// 示例:处理Set中的自定义变量
// 使用MapSlice保存有序的Set
type MapSlice yaml.MapSlice

请求构造示例

以airflow未授权访问漏洞为例:

name: poc-yaml-airflow-unauth
rules:
  - method: GET
    path: /admin/
    expression: |
            response.status == 200 && response.body.bcontains(b"<title>Airflow - DAGs</title>") && response.body.bcontains(b"<h2>DAGs</h2>")

检测链控制

xray支持两种检测链格式:

  1. Rules:有序rule列表,全部通过才算成功
  2. Groups:多组rules,任意一组通过就算成功

核心逻辑:

func ExecExpressionHandle(ctx controllerContext){
    var result bool
    var err error

    poc := ctx.GetPoc()
    if poc == nil {
        log.Error("[rule/handle.go:ExecExpressionHandle error] ", "poc is nil")
        return
    }
    if poc.Groups != nil {
        result, err = ctx.Groups(ctx.IsDebug())
    } else {
        result, err = ctx.Rules(poc.Rules,ctx.IsDebug())
    }
    if err != nil {
        log.Error("[rule/handle.go:ExecExpressionHandle error] ", err)
        return
    }
    if result {
        ctx.Abort()
    }
    return
}

POC运行流程

  1. 获取原始请求并根据规则变形
  2. 初始化CEL环境(注入变量和方法)
  3. 初始化CEL变量列表(注入set变量和当前请求)
  4. 发起变形后的请求并将响应写入变量列表
  5. 执行表达式判断漏洞是否存在

0x04 扩展xray功能

请求变形分类

新增规则类型字段,根据不同类型执行不同变形逻辑:

  1. 目录级扫描:更完整的目录定义
  2. 服务器级扫描:针对独占端口的通用组件
  3. 内容级扫描:检查每个响应的常见漏洞特征
  4. 参数级扫描:处理SSRF/XSS等参数型漏洞

核心实现:

func (controller *PocController) DoSingleRuleRequest(rule *Rule) (*proto.Response, error) {
    fastReq := controller.Request.Fast
    fixedFastReq := fasthttp.AcquireRequest()
    fastReq.CopyTo(fixedFastReq)
    curPath := string(fixedFastReq.URI().Path())

    affects := controller.Plugin.Affects

    switch affects {
    case AffectAppendParameter, AffectReplaceParameter:
        // 参数级处理
    case AffectContent:
        // 内容级处理
    case AffectDirectory:
        // 目录级处理
    case AffectServer:
        // 服务器级处理
    case AffectURL:
        // URL级处理
    default:
    }
    // 其他处理逻辑...
}

Multipart处理

对于文件上传等multipart请求的特殊处理:

func DealMultipart(contentType string, ruleBody string) (result string, err error) {
    // 提取boundary
    re := regexp.MustCompile(`(?m)multipart\/form-Data; boundary=(.*)`)
    match := re.FindStringSubmatch(contentType)
    if len(match) != 2 {
        return "", errors.New("no boundary in content-type")
    }
    boundary := "--" + match[1]
    
    // 处理multipart内容
    multiFile := strings.Split(ruleBody, boundary)
    for _, singleFile := range multiFile {
        spliteTmp := strings.Split(singleFile,"\n\n")
        if len(spliteTmp) == 2 {
            fileHeader := spliteTmp[0]
            fileBody := spliteTmp[1]
            fileHeader = strings.Replace(fileHeader,"\n","\r\n",-1)
            multiPartContent += boundary + fileHeader + "\r\n\r\n" + strings.TrimRight(fileBody ,"\n") + "\r\n"
        }
    }
    multiPartContent += boundary + "--" + "\r\n"
    return multiPartContent, nil
}

0x05 总结

本文详细介绍了漏洞验证框架的规则体系实现,包括:

  1. 多种原始请求构造方式
  2. 完整兼容xray的CEL表达式规则
  3. 灵活的检测链控制机制
  4. 扩展的请求变形分类
  5. 特殊请求(如multipart)的处理

该框架在保持xray兼容性的同时,提供了更细粒度的漏洞检测能力。

0x06 参考

  1. xray官方文档
  2. xray POC仓库
  3. CEL官方文档
  4. gopoc项目
  5. pocassist开发文档
漏洞验证框架的构思与实现(二)——规则体系详解 0x01 前言 本文是漏洞验证框架系列的第二篇,重点介绍框架的核心模块:规则体系。该框架在兼容xray规则的基础上进行了扩展,实现了更灵活的漏洞检测机制。 0x02 原始请求来源 框架支持三种原始请求构造方式: 1. 基于URL构造请求 2. 基于原始HTTP报文文件构造请求 3. 通过代理监听获取请求 类似于xray的浏览器代理模式 0x03 兼容xray规则体系 CEL表达式实现 xray的规则体系基于Common Expression Language (CEL)实现,使用cel-go包: 构建CEL环境 :初始化cel.Env 注入类型和方法 :实现xray文档中所有变量和方法 计算表达式 :传入表达式、环境和变量列表 请求构造示例 以airflow未授权访问漏洞为例: 检测链控制 xray支持两种检测链格式: Rules :有序rule列表,全部通过才算成功 Groups :多组rules,任意一组通过就算成功 核心逻辑: POC运行流程 获取原始请求并根据规则变形 初始化CEL环境(注入变量和方法) 初始化CEL变量列表(注入set变量和当前请求) 发起变形后的请求并将响应写入变量列表 执行表达式判断漏洞是否存在 0x04 扩展xray功能 请求变形分类 新增规则类型字段,根据不同类型执行不同变形逻辑: 目录级扫描 :更完整的目录定义 服务器级扫描 :针对独占端口的通用组件 内容级扫描 :检查每个响应的常见漏洞特征 参数级扫描 :处理SSRF/XSS等参数型漏洞 核心实现: Multipart处理 对于文件上传等multipart请求的特殊处理: 0x05 总结 本文详细介绍了漏洞验证框架的规则体系实现,包括: 多种原始请求构造方式 完整兼容xray的CEL表达式规则 灵活的检测链控制机制 扩展的请求变形分类 特殊请求(如multipart)的处理 该框架在保持xray兼容性的同时,提供了更细粒度的漏洞检测能力。 0x06 参考 xray官方文档 xray POC仓库 CEL官方文档 gopoc项目 pocassist开发文档