当前位置: 首页 > news >正文

【安全开发】Nuclei源码分析-模板引擎实现(五)

目录

  • Nuclei 模板引擎实现详解
    • 1. 模板引擎概述
    • 2. 核心数据结构
      • 2.1 Template 结构体
      • 2.2 Executer 接口
      • 2.3 Request 接口
    • 3. 模板引擎工作流程
      • 3.1 模板加载
      • 3.2 模板解析
      • 3.3 模板编译
      • 3.4 模板执行
    • 4. 模板引擎特性
      • 4.1 多协议支持
      • 4.2 工作流支持
      • 4.3 变量和表达式
      • 4.4 缓存机制
    • 5. 核心代码位置
    • 6. 总结

Nuclei 模板引擎实现详解

Nuclei 的模板引擎是其核心组件,负责解析、编译和执行 YAML 格式的模板文件。模板引擎使 Nuclei 能够执行各种协议的漏洞扫描任务。本文将详细分析 Nuclei 模板引擎的实现机制。

1. 模板引擎概述

Nuclei 模板引擎主要由以下几个核心组件构成:

  • 模板解析器 - 负责将 YAML 文件解析为内存中的数据结构
  • 模板编译器 - 将解析后的模板编译为可执行的请求
  • 模板执行器 - 执行编译后的模板请求 Executer
  • 模板加载器 - 负责模板的加载、过滤和管理
  • 协议执行器 - 实现各种协议的具体执行逻辑

2. 核心数据结构

2.1 Template 结构体

Template (nuclei\v2\pkg\templates\templates.go#L24-L74) 结构体是模板引擎的核心数据结构,定义在 v2/pkg/templates/templates.go 文件中:

type Template struct {ID              string                 // 模板唯一标识符Info            model.Info          // 模板元数据信息RequestsHTTP    []*http.Request     // HTTP 请求定义RequestsDNS     []*dns.Request      // DNS 请求定义RequestsFile    []*file.Request         // 文件请求定义RequestsNetwork []*network.Request  // 网络请求定义RequestsHeadless []*headless.Request // 无头浏览器请求定义workflows.Workflow        // 内嵌工作流结构CompiledWorkflow *workflows.Workflow    // 编译后的工作流SelfContained bool    // 是否为自包含请求TotalRequests int      // 模板总请求数Executer protocols.Executer     // 模板执行器Path     string      // 模板文件路径
}
type Workflow struct {Workflows []*WorkflowTemplate Options *protocols.ExecuterOptions `yaml:"-"`
}

2.2 Executer 接口

Executer(nuclei\v2\pkg\protocols\protocols.go#L15-L22) 接口定义了模板执行器的行为,位于 v2/pkg/protocols/protocols.go:

type Executer interface {Compile() error  // 编译模板Requests() int   // 返回请求数量Execute(input string) (bool, error)  // 执行模板ExecuteWithResults(input string, callback OutputEventCallback) error
}

2.3 Request 接口

Request (nuclei\v2\pkg\protocols\protocols.go#L47-L62) 接口定义了各种协议请求的行为:

type Request interface {Compile(options *ExecuterOptions) errorRequests() intGetID() stringMatch(data map[string]interface{}, matcher *matchers.Matcher) (bool, []string)Extract(data map[string]interface{}, matcher *extractors.Extractor) map[string]struct{}ExecuteWithResults(input string, dynamicValues, previous output.InternalEvent, callback OutputEventCallback) errorMakeResultEventItem(wrapped *output.InternalWrappedEvent) *output.ResultEventMakeResultEvent(wrapped *output.InternalWrappedEvent) []*output.ResultEventGetCompiledOperators() []*operators.Operators
}

3. 模板引擎工作流程

3.1 模板加载

模板加载过程由 loader.Store (nuclei\v2\pkg\catalog\loader\loader.go#L30-L40) 类负责,主要步骤包括:

  • 路径解析 - 根据用户指定的模板路径查找模板文件
  • 过滤处理 - 根据标签、作者、严重性等条件过滤模板
  • 模板加载 - 使用 LoadTemplates (nuclei\v2\pkg\catalog\loader\loader.go#L162-L187) 方法加载模板
func (store *Store) LoadTemplates(templatesList []string) []*templates.Template {includedTemplates := store.config.Catalog.GetTemplatesPath(templatesList)templatePathMap := store.pathFilter.Match(includedTemplates)loadedTemplates := make([]*templates.Template, 0, len(templatePathMap))for templatePath := range templatePathMap {loaded, err := parsers.LoadTemplate(templatePath, store.tagFilter, nil)if err != nil {gologger.Warning().Msgf("Could not load template %s: %s\n", templatePath, err)}if loaded {parsed, err := templates.Parse(templatePath, store.preprocessor, store.config.ExecutorOptions)if err != nil {gologger.Warning().Msgf("Could not parse template %s: %s\n", templatePath, err)} else if parsed != nil {loadedTemplates = append(loadedTemplates, parsed)}}}return loadedTemplates
}

3.2 模板解析

模板解析由 templates.Parse (nuclei\v2\pkg\templates\compile.go#L33-L141) 函数完成,主要步骤包括:

  • 文件读取 - 读取模板 YAML 文件内容
  • 预处理 - 应用预处理器处理模板内容
  • YAML 解析 - 使用 yaml.Unmarshal 将 YAML 内容解析为 Template 结构体
  • 验证检查 - 验证模板必需字段是否完整
func Parse(filePath string, preprocessor Preprocessor, options protocols.ExecuterOptions) (*Template, error) {// 从缓存中获取或创建新模板template := &Template{}// 读取文件内容f, err := os.Open(filePath)if err != nil {return nil, err}defer f.Close()data, err := ioutil.ReadAll(f)if err != nil {return nil, err}// 预处理data = template.expandPreprocessors(data)if preprocessor != nil {data = preprocessor.Process(data)}// YAML 解析if err := yaml.Unmarshal(data, template); err != nil {return nil, err}// 验证必需字段if utils.IsBlank(template.Info.Name) {return nil, errors.New("no template name field provided")}// ... 其他验证return template, nil
}

3.3 模板编译

模板编译过程在 templates.Parse (fnuclei\v2\pkg\templates\compile.go#L33-L141) 函数中完成,主要包括:

  • 工作流编译 - 如果模板包含工作流定义,则编译工作流
  • 请求编译 - 编译各种协议的请求
  • 执行器创建 - 为模板创建相应的执行器【执行器根据协议而不同,事先定义好的】
// 编译工作流
if len(template.Workflows) > 0 {compiled := &template.WorkflowcompileWorkflow(filePath, preprocessor, &options, compiled, options.WorkflowLoader)template.CompiledWorkflow = compiledtemplate.CompiledWorkflow.Options = &options
}// 编译各种协议请求
if len(template.RequestsHTTP) > 0 {// 创建 HTTP 请求执行器template.Executer = executer.NewExecuter(requests, &options)
}// 编译执行器
if template.Executer != nil {if err := template.Executer.Compile(); err != nil {return nil, errors.Wrap(err, "could not compile request")}template.TotalRequests += template.Executer.Requests()
}

3.4 模板执行

模板执行由 executer.Executer (nuclei\v2\pkg\protocols\common\executer\executer.go#L11-L14) 类负责,主要步骤包括:

  • 请求执行 - 依次执行模板中的所有请求
  • 结果匹配 - 使用匹配器和提取器处理响应
  • 结果输出 - 将匹配结果输出到指定位置
func (e *Executer) Execute(input string) (bool, error) {var results booldynamicValues := make(map[string]interface{})previous := make(map[string]interface{})for _, req := range e.requests {req := reqerr := req.ExecuteWithResults(input, dynamicValues, previous, func(event *output.InternalWrappedEvent) {// 处理请求结果if event.OperatorsResult == nil {return}for _, result := range event.Results {if e.options.IssuesClient != nil {// 发送结果到问题跟踪系统}results = true_ = e.options.Output.Write(result)e.options.Progress.IncrementMatched()}})// 错误处理}return results, nil
}

4. 模板引擎特性

4.1 多协议支持

Nuclei 模板引擎支持多种协议:

  • HTTP/HTTPS - Web 应用漏洞检测
  • DNS - DNS 相关漏洞检测
  • Network - 网络协议漏洞检测
  • File - 文件系统相关检测
  • Headless - 无头浏览器自动化检测

4.2 工作流支持

模板引擎支持复杂的工作流定义,可以编排多个模板的执行顺序和条件:

workflows:- template: technologies/tech-detect.yamlsubtemplates:- template: vulnerabilities/specific-vuln.yaml

4.3 变量和表达式

模板引擎支持丰富的变量系统和 DSL 表达式:

  • 内置变量:{{BaseURL}}、{{Hostname}} 等
  • 自定义变量:通过 -var 参数传递
  • 环境变量:通过 -env-vars 启用

4.4 缓存机制

模板引擎使用缓存来提高性能:

var parsedTemplatesCache *cache.Templates
func init() {parsedTemplatesCache = cache.New()
}

5. 核心代码位置

  • 模板定义:v2/pkg/templates/templates.go
  • 模板解析和编译:v2/pkg/templates/compile.go
  • 执行器实现:v2/pkg/protocols/common/executer/executer.go
  • 协议请求接口:v2/pkg/protocols/protocols.go
  • 模板加载器:v2/pkg/catalog/loader/loader.go
  • 模板解析器:v2/pkg/parsers/parser.go

6. 总结

Nuclei 的模板引擎通过清晰的架构设计和模块化实现,提供了强大而灵活的漏洞扫描能力。其核心特点包括:

  • 模块化设计 - 各组件职责清晰,易于扩展和维护
  • 多协议支持 - 支持多种网络协议的漏洞检测
  • 灵活的模板系统 - 支持复杂的工作流和条件执行
  • 高性能 - 通过缓存和并发执行提高扫描效率
  • 易于使用 - 基于 YAML 的模板格式简单直观

by 久违 2025.10.20

http://www.dtcms.com/a/585309.html

相关文章:

  • 【小技巧】PyCharm建立项目,VScode+CodeX+WindowsPowerShell开发Python pyQT6 (二)
  • 办个人网站租空间餐饮网站建设的模板
  • 国家开发投资集团有限公司广州新站优化
  • MySQL数据类型详解
  • Rust 练习册 :Rail Fence Cipher与栅栏密码
  • 织梦dedecms绿色led照明公司企业网站模板 下载网站如何免费推广
  • 【Svelte】动态加载组件并传递参数的正确姿势,及两种方式比较
  • 【ZeroRange WebRTC】Amazon Kinesis Video Streams C WebRTC SDK 详解与实践指南
  • openEuler边缘计算实践:构建高效边云协同架构
  • 自建国外购物网站公司网站开发外包公司
  • Linux内存管理揭秘:页表递归清理与TLB优化机制
  • 从“医疗大模型”向“医疗智能体”架构与路径分析(白皮书草案-下)
  • Webpack性能优化终极指南:4步实现闪电打包
  • 零基础学JAVA--Day26(枚举类)
  • Kafka概述
  • CTFHub Web进阶-PHP:Bypass_disable_function通关8之PHP FFI
  • 重庆本地网站有哪些world做网站怎么做连接
  • 【028】Dubbo3从0到1系列之序列化机制
  • phpcms模板资源网站快速优化排名
  • 0 基础学前端:100 天拿 offer 实战课(第 18 天)—— JS 事件进阶:冒泡、委托与自定义事件,搞定复杂交互
  • 【C++】STL小总结
  • go基础语法练习
  • 360任意看地图网站网站开发设计需要什么证书
  • 大数据Spark(七十二):Transformation转换算子repartition和coalesce使用案例
  • Android 16 Kotlin协程 第二部分
  • 网站建设公司兴田德润电话新县城乡规划建设局网站
  • Claude Code使用指南
  • 如何进行MSSQL提权?默认库,xp_cmdshell提权
  • 第三章 布局
  • 「数据获取」《中国口岸年鉴》(2001-2024)(2002未出版)