漏洞验证框架的构思与实现(二)
字数 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包:
- 构建CEL环境:初始化cel.Env
- 注入类型和方法:实现xray文档中所有变量和方法
- 计算表达式:传入表达式、环境和变量列表
// 示例:处理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支持两种检测链格式:
- Rules:有序rule列表,全部通过才算成功
- 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运行流程
- 获取原始请求并根据规则变形
- 初始化CEL环境(注入变量和方法)
- 初始化CEL变量列表(注入set变量和当前请求)
- 发起变形后的请求并将响应写入变量列表
- 执行表达式判断漏洞是否存在
0x04 扩展xray功能
请求变形分类
新增规则类型字段,根据不同类型执行不同变形逻辑:
- 目录级扫描:更完整的目录定义
- 服务器级扫描:针对独占端口的通用组件
- 内容级扫描:检查每个响应的常见漏洞特征
- 参数级扫描:处理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 总结
本文详细介绍了漏洞验证框架的规则体系实现,包括:
- 多种原始请求构造方式
- 完整兼容xray的CEL表达式规则
- 灵活的检测链控制机制
- 扩展的请求变形分类
- 特殊请求(如multipart)的处理
该框架在保持xray兼容性的同时,提供了更细粒度的漏洞检测能力。