白盒系列之变量追踪引擎(一)
字数 1367 2025-08-15 21:30:59

白盒扫描之变量追踪引擎实现详解

一、白盒扫描概述

白盒扫描通常在软件开发生命周期的三个阶段进行:

  1. 开发阶段:使用IDE插件进行本地扫描(效果最佳但实际应用较少)
  2. 集成阶段:代码提交时进行扫描
  3. 发布阶段:强制卡点扫描(目前最普遍)

理想状态是在开发阶段进行扫描,但由于IDE插件性能限制(可能导致IDE卡死),实际应用效果不佳。

二、变量追踪引擎架构

变量追踪引擎实现包含6个关键节点:

  1. 文件语法结构解析及提取
  2. 解析后语法结构的合理存储
  3. 危险函数(Sink)和污染数据(Source)的定义
  4. 调用流图的构建
  5. 代码的模拟执行
  6. 误报优化

三、语法结构解析

3.1 抽象语法树(AST)的选择

相比直接分析源代码或字节码,AST具有以下特点:

优势

  • 更易分析代码结构(如区分TemplateLiteral、Identifier等)
  • 标准化结构便于自动化处理

劣势

  • 语法结构复杂(简单代码行可能解析为上百行AST)
  • 节点类型繁多(JavaScript约150多种指令集)

3.2 AST解析工具

推荐工具:

  • JavaScript:Babel(支持ES5/ES6、TypeScript、JSX)
  • Java:Eclipse JDT、Soot
  • Python:ast.parse
  • Go:go/parser包

Babel配置示例:

this.config = {
  loc: true,
  strictMode: false,
  sourceType: 'module',
  allowImportExportEverywhere: true,
  allowUndeclaredExports: true,
  errorRecovery: true,
  plugins: [
    'typescript', 
    'classProperties',
    'dynamicImport',
    'decorators-legacy',
    'jsx',
    'optionalChaining',
    'exportDefaultFrom'
  ]
};

3.3 AST节点学习资源

  • ESTree:JavaScript规范定义
  • babel-spec:Babel特定节点扩展定义
  • babel-types:TypeScript/JSX节点参考

四、关键信息提取

4.1 快速定位关键节点

使用Babel的@babel/traverse

const babelTraverse = require('@babel/traverse').default;
babelTraverse(astData, infoCollect(results));

function infoCollect(results) {
  return {
    VariableDeclarator({node}) {
      // 处理变量声明节点
    },
    // 其他节点类型...
  }
}

4.2 单个节点信息解析

采用递归解析方法:

  1. 设定需要解析的关键信息(如CallExpression的callee)
  2. 递归遍历子节点,匹配目标属性(如callee→Identifier→name)
  3. 返回符合条件的节点信息

五、污染源与危险函数定义

5.1 污染源(Source)定义

Web应用中用户可控数据来源:

Express框架

MemberExpression: [
  ['req', 'params'],
  ['req', 'body'],
  ['req', 'cookies'],
  ['req', 'query']
],
CallExpression: [
  ['req', 'get'],
  ['req', 'param']
]

Koa框架

MemberExpression: [
  ['ctx', 'header'],
  ['ctx', 'headers'],
  ['ctx', 'origin'],
  ['ctx', 'href'],
  ['ctx', 'query'],
  ['ctx', 'querystring'],
  ['ctx', 'cookies'],
  ['ctx', 'body'],
  ['ctx', 'params']
],
CallExpression: [
  ['ctx', 'query'],
  ['ctx', 'query', 'get'],
  ['ctx', 'request', 'get'],
  ['ctx', 'cookies', 'get'],
  ['ctx', 'get']
]

5.2 危险函数(Sink)定义

格式:{index: 参数位置, value: 函数路径}

命令执行

CallExpression: [
  {index: 0, value: ['exec']},
  {index: 0, value: ['execSync']},
  {index: 0, value: ['child_process', 'exec']},
  {index: 0, value: ['child_process', 'execSync']},
  {index: 0, value: ['eval']},
  {index: 0, value: ['shell', 'exec']}
]

SQL注入

CallExpression: [
  {index: 0, value: ['connection', 'query']},
  {index: 0, value: ['conn', 'query']},
  {index: 0, value: ['db', 'query']},
  {index: 0, value: ['mysql', 'createConnection', 'query']},
  {index: 0, value: ['sequelize', 'query']},
  {index: 0, value: ['db', 'driver', 'execQuery']}
]

SSRF

CallExpression: [
  {index: 0, value: ['http', 'get']},
  {index: 0, value: ['http', 'request']},
  {index: 0, value: ['axios']},
  {index: 0, value: ['fetch']},
  {index: 0, value: ['request']},
  {index: 0, value: ['request', 'get']},
  {index: 0, value: ['request', 'post']}
]

六、调用链构建

6.1 调用流图选择

全局调用流图

  • 解析所有文件及其引用关系
  • 构建完整调用关系图
  • 耗时长,不适合实时扫描

局部调用流图

  • 以HTTP请求处理方法为起点
  • 按需构建调用关系
  • 速度快,适合实时扫描(小型项目秒级,大型项目1分钟左右)

6.2 调用树构建示例

  1. 以路由处理方法为起点(Source方法)
  2. 递归解析方法内的调用语句
  3. 为每个方法体创建节点,记录:
    • 方法体信息
    • 调用点信息

6.3 调用链路获取

  1. 遍历调用树的所有叶子节点
  2. 识别符合Sink定义的节点
  3. 逆向查找还原完整调用链路

七、核心实现要点总结

  1. 性能优化:局部调用流图显著优于全局调用流图
  2. 准确性:递归解析确保不遗漏关键节点
  3. 可扩展性:通过配置文件定义Source/Sink,便于规则更新
  4. 误报处理:参数位置(index)的精确指定减少误报

八、后续方向

下一篇将深入讲解基于状态机的模拟执行实现,这是变量追踪引擎最核心的部分。

白盒扫描之变量追踪引擎实现详解 一、白盒扫描概述 白盒扫描通常在软件开发生命周期的三个阶段进行: 开发阶段 :使用IDE插件进行本地扫描(效果最佳但实际应用较少) 集成阶段 :代码提交时进行扫描 发布阶段 :强制卡点扫描(目前最普遍) 理想状态是在开发阶段进行扫描,但由于IDE插件性能限制(可能导致IDE卡死),实际应用效果不佳。 二、变量追踪引擎架构 变量追踪引擎实现包含6个关键节点: 文件语法结构解析及提取 解析后语法结构的合理存储 危险函数(Sink)和污染数据(Source)的定义 调用流图的构建 代码的模拟执行 误报优化 三、语法结构解析 3.1 抽象语法树(AST)的选择 相比直接分析源代码或字节码,AST具有以下特点: 优势 : 更易分析代码结构(如区分TemplateLiteral、Identifier等) 标准化结构便于自动化处理 劣势 : 语法结构复杂(简单代码行可能解析为上百行AST) 节点类型繁多(JavaScript约150多种指令集) 3.2 AST解析工具 推荐工具: JavaScript :Babel(支持ES5/ES6、TypeScript、JSX) Java :Eclipse JDT、Soot Python :ast.parse Go :go/parser包 Babel配置示例: 3.3 AST节点学习资源 ESTree :JavaScript规范定义 babel-spec :Babel特定节点扩展定义 babel-types :TypeScript/JSX节点参考 四、关键信息提取 4.1 快速定位关键节点 使用Babel的 @babel/traverse : 4.2 单个节点信息解析 采用 递归解析 方法: 设定需要解析的关键信息(如CallExpression的callee) 递归遍历子节点,匹配目标属性(如callee→Identifier→name) 返回符合条件的节点信息 五、污染源与危险函数定义 5.1 污染源(Source)定义 Web应用中用户可控数据来源: Express框架 : Koa框架 : 5.2 危险函数(Sink)定义 格式: {index: 参数位置, value: 函数路径} 命令执行 : SQL注入 : SSRF : 六、调用链构建 6.1 调用流图选择 全局调用流图 : 解析所有文件及其引用关系 构建完整调用关系图 耗时长,不适合实时扫描 局部调用流图 : 以HTTP请求处理方法为起点 按需构建调用关系 速度快,适合实时扫描(小型项目秒级,大型项目1分钟左右) 6.2 调用树构建示例 以路由处理方法为起点(Source方法) 递归解析方法内的调用语句 为每个方法体创建节点,记录: 方法体信息 调用点信息 6.3 调用链路获取 遍历调用树的所有叶子节点 识别符合Sink定义的节点 逆向查找还原完整调用链路 七、核心实现要点总结 性能优化 :局部调用流图显著优于全局调用流图 准确性 :递归解析确保不遗漏关键节点 可扩展性 :通过配置文件定义Source/Sink,便于规则更新 误报处理 :参数位置(index)的精确指定减少误报 八、后续方向 下一篇将深入讲解基于状态机的模拟执行实现,这是变量追踪引擎最核心的部分。