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

漏洞验证框架规则体系设计与实现

1. 规则体系概述

本文档详细介绍了基于xray规则体系扩展的漏洞验证框架核心模块——规则体系的设计与实现。该体系兼容xray的POC规则,同时增加了更细致的请求变形分类,提高了漏洞检测的灵活性和准确性。

2. 原始请求来源处理

框架支持三种原始请求来源方式:

2.1 从URL生成请求

func GenOriginalReq(url string) (*http.Request, error) {
    // 生成原始请求,如果没有协议默认使用http
    if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
        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.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
}

2.3 通过代理监听获取请求

第三种方式是通过代理形式监听获取请求(如xray浏览器代理模式)。

3. xray规则兼容实现

3.1 CEL表达式处理

xray的规则体系基于Common Expression Language (CEL)实现,使用cel-go包处理表达式。

CEL表达式运行流程:

  1. 构建CEL环境(cel.Env)
  2. 向环境中注入类型和方法
  3. 计算表达式

3.1.1 变量和方法注入

需要实现xray规则中所有的变量和方法,包括:

  • UrlType
  • Request
  • Response
  • Reverse
  • 文档未提及的icontains方法

3.1.2 Set变量处理

Set中自定义变量可能引用之前的变量,因此必须有序加载。建议使用yaml.v2包的MapSlice而非原生map保存Set变量。

3.2 请求构造过程

POC运行阶段有两个请求:

  1. 原始请求
  2. 根据规则变形的请求

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

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>")      

请求变形逻辑:

  1. 获取原始请求路径(如/test/)
  2. 将POC中的path(/admin/)拼接到原始路径后(/test/admin/)
  3. 保持原始请求头不变

为提高性能,使用fasthttp替换原生http包:

// 定义fasthttp.Request保存构造的请求
fastReq := controller.Request.Fast
fixedFastReq := fasthttp.AcquireRequest()
fastReq.CopyTo(fixedFastReq)

3.3 检测链控制

xray支持两种检测链格式:

  1. rules:rule组成的有序列表([]rule)

    • 值为true的rule继续执行后续rule
    • 所有rule执行成功则POC结果为true
  2. groups:rules组成的列表(map[string]rules)

    • 任意一组rules执行成功则POC结果为true

执行逻辑:

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
}

3.4 POC运行流程

  1. 获取原始请求,根据规则变形构造新请求
  2. 初始化CEL环境:注入变量和方法
  3. 初始化CEL变量列表:注入Set定义的自定义变量和当前请求
  4. 发起构造后的请求,将响应写入CEL变量列表
  5. 执行表达式判断结果

4. xray规则扩展

在xray基础上增加了更细致的请求变形分类:

4.1 规则类型扩展

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

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 {
    // 情况4 参数级
    case AffectAppendParameter, AffectReplaceParameter:
        for k, v := range rule.Headers {
            fixedFastReq.Header.Set(k, v)
        }
        return util.DoFasthttpRequest(fixedFastReq, rule.FollowRedirects)
        
    // 情况3 content级
    case AffectContent:
        return util.DoFasthttpRequest(fixedFastReq, rule.FollowRedirects)
        
    // 情况1 dir级
    case AffectDirectory:
        // 目录级漏洞检测 判断是否以"/"结尾
        if curPath != "" && strings.HasSuffix(curPath, "/") {
            // 去掉规则中的的"/" 再拼
            curPath = fmt.Sprint(curPath, strings.TrimPrefix(rule.Path, "/"))
        } else {
            curPath = fmt.Sprint(curPath, "/", strings.TrimPrefix(rule.Path, "/"))
        }
        
    // 情况2
    case AffectServer:
        curPath = rule.Path
        
    // url级(直接使用原始请求头,只替换路径和完整post参数)
    case AffectURL:
    //curPath = curPath, strings.TrimPrefix(rule.Path, "/"))
    
    default:
    }
    
    // 兼容xray: 某些POC没有区分path和query
    curPath = strings.ReplaceAll(curPath, " ", "%20")
    curPath = strings.ReplaceAll(curPath, "+", "%20")
    fixedFastReq.URI().DisablePathNormalizing = true
    fixedFastReq.URI().Update(curPath)
    
    for k, v := range rule.Headers {
        fixedFastReq.Header.Set(k, v)
    }
    fixedFastReq.Header.SetMethod(rule.Method)
    
    // 处理multipart
    contentType := string(fixedFastReq.Header.ContentType())
    if strings.HasPrefix(strings.ToLower(contentType), "multipart/form-Data") && 
       strings.Contains(rule.Body, "\n\n") {
        multipartBody, err := util.DealMultipart(contentType, rule.Body)
        if err != nil {
            return nil, err
        }
        fixedFastReq.SetBody([]byte(multipartBody))
    } else {
        fixedFastReq.SetBody([]byte(rule.Body))
    }
    
    return util.DoFasthttpRequest(fixedFastReq, rule.FollowRedirects)
}

4.2 Multipart处理

对于文件上传等需要multipart格式的POC,需要按照RFC规定处理换行符:

func DealMultipart(contentType string, ruleBody string) (result string, err error) {
    errMsg := ""
    // 处理multipart的/n
    re := regexp.MustCompile(`(?m)multipart\/form-Data; boundary=(.*)`)
    match := re.FindStringSubmatch(contentType)
    if len(match) != 2 {
        errMsg = "no boundary in content-type"
        return "", errors.New(errMsg)
    }
    
    boundary := "--" + match[1]
    multiPartContent := ""
    
    // 处理rule
    multiFile := strings.Split(ruleBody, boundary)
    if len(multiFile) == 0 {
        errMsg = "ruleBody.Body multi content format err"
        return multiPartContent, errors.New(errMsg)
    }
    
    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
}

5. 总结

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

  1. 原始请求的多种来源处理
  2. 兼容xray CEL表达式规则体系
  3. 请求变形和检测链控制
  4. 在xray基础上扩展的更细致请求变形分类

该规则体系既保持了与xray POC规则的兼容性,又增加了更灵活的检测方式,提高了漏洞验证的准确性和效率。

漏洞验证框架规则体系设计与实现 1. 规则体系概述 本文档详细介绍了基于xray规则体系扩展的漏洞验证框架核心模块——规则体系的设计与实现。该体系兼容xray的POC规则,同时增加了更细致的请求变形分类,提高了漏洞检测的灵活性和准确性。 2. 原始请求来源处理 框架支持三种原始请求来源方式: 2.1 从URL生成请求 2.2 从HTTP报文文件生成请求 2.3 通过代理监听获取请求 第三种方式是通过代理形式监听获取请求(如xray浏览器代理模式)。 3. xray规则兼容实现 3.1 CEL表达式处理 xray的规则体系基于Common Expression Language (CEL)实现,使用cel-go包处理表达式。 CEL表达式运行流程: 构建CEL环境(cel.Env) 向环境中注入类型和方法 计算表达式 3.1.1 变量和方法注入 需要实现xray规则中所有的变量和方法,包括: UrlType Request Response Reverse 文档未提及的icontains方法 3.1.2 Set变量处理 Set中自定义变量可能引用之前的变量,因此必须有序加载。建议使用yaml.v2包的MapSlice而非原生map保存Set变量。 3.2 请求构造过程 POC运行阶段有两个请求: 原始请求 根据规则变形的请求 以airflow未授权访问漏洞POC为例: 请求变形逻辑: 获取原始请求路径(如/test/) 将POC中的path(/admin/)拼接到原始路径后(/test/admin/) 保持原始请求头不变 为提高性能,使用fasthttp替换原生http包: 3.3 检测链控制 xray支持两种检测链格式: rules :rule组成的有序列表([ ]rule) 值为true的rule继续执行后续rule 所有rule执行成功则POC结果为true groups :rules组成的列表(map[ string ]rules) 任意一组rules执行成功则POC结果为true 执行逻辑: 3.4 POC运行流程 获取原始请求,根据规则变形构造新请求 初始化CEL环境:注入变量和方法 初始化CEL变量列表:注入Set定义的自定义变量和当前请求 发起构造后的请求,将响应写入CEL变量列表 执行表达式判断结果 4. xray规则扩展 在xray基础上增加了更细致的请求变形分类: 4.1 规则类型扩展 新增规则类型字段,根据不同类型执行不同变形逻辑: 4.2 Multipart处理 对于文件上传等需要multipart格式的POC,需要按照RFC规定处理换行符: 5. 总结 本文详细介绍了漏洞验证框架规则体系的设计与实现,包括: 原始请求的多种来源处理 兼容xray CEL表达式规则体系 请求变形和检测链控制 在xray基础上扩展的更细致请求变形分类 该规则体系既保持了与xray POC规则的兼容性,又增加了更灵活的检测方式,提高了漏洞验证的准确性和效率。