从AST到100个某知名OA前台注入
字数 1811 2025-08-15 21:30:49

基于AST的Java代码审计技术详解

一、背景与概述

本文详细介绍了如何通过分析Java抽象语法树(AST)来自动化挖掘某知名OA系统中的SQL注入漏洞。该方法参考了Cobra工具的PHP解析器实现思路,通过遍历Java AST进行漏洞挖掘,成功筛选出160个前台注入点,并手工编写了约50个前台注入EXP。

二、预备知识

1. 目标系统介绍

  • 某知名OA系统使用Java编写,代码相对古老
  • SQL查询语句多采用拼接方式,缺乏参数化处理
  • 过滤机制通过统一的Filter实现,存在绕过可能
  • 主要功能通过JSP实现,可编译为Java Servlet

2. 编译原理基础

  • 词法分析:将源代码分解为标记(token)
  • 语法分析:根据语法规则构建AST
  • AST包含程序源文件的所有结构化信息

3. 数据流分析关键概念

  • Sink(污点函数):敏感函数如executeSqlRuntime.exec()
  • Source(输入来源):用户可控输入如request.getParameter()
  • Repair/Sanitizer(修复函数):过滤函数如null2intgetIntValue
  • DataFlow(数据流):变量在代码中的传递路径

三、环境准备

1. 搭建测试环境

  • 下载并安装某知名OA 8 (Ecology8.100.0531)
  • 默认配置安装即可

2. 获取JSP文件路径

import os

def get_files(path=r"D:\WEAVER\ecology\"):
    g = os.walk(path)
    result = []
    for path, d, file_list in g:
        for filename in file_list:
            full_path = os.path.join(path, filename)
            result.append([full_path, filename])
    return result

3. 获取可访问JSP列表

  • 使用Burp Intruder或Python脚本遍历JSP文件
  • 筛选HTTP响应码为200的JSP文件

4. 获取Servlet.java文件

  • D:\WEAVER\ecology\WEB-INF\work\_jsp目录复制生成的Servlet文件

四、技术实现

1. Java AST解析器选择

  • 使用Python的javalang库解析Java代码为AST
  • 安装:pip install javalang

2. PHP与Java AST节点对照表

PHP节点 Java节点 描述
php.Variable MemberReference 变量引用
php.FunctionCall MethodInvocation 函数调用
php.BinaryOp BinaryOperation 二元操作
php.ArrayOffset ArraySelector 数组操作
php.Block BlockStatement 语句块
php.Assignment Assignment 赋值语句

3. 核心组件实现

(1) 主分析函数analysis

def analysis(self, nodes, vul_function, back_node, vul_lineo, function_params=None):
    for node in nodes:
        if isinstance(node, MethodInvocation):
            self.anlysis_function(node, back_node, vul_function, function_params, vul_lineo)
        elif isinstance(node, StatementExpression):
            if isinstance(node.expression, MethodInvocation):
                self.anlysis_function(node.expression, back_node, vul_function, function_params, vul_lineo)
        # 其他节点类型处理...

(2) 污点回溯parameters_back

def parameters_back(self, param, nodes, function_params=None, node_lineno=-1):
    is_co, cp = self.is_controllable(param)
    if len(nodes) != 0 and is_co == -1:
        node = nodes[len(nodes) - 1]
        if isinstance(node, LocalVariableDeclaration):
            # 处理变量声明和赋值
            # 递归查找变量来源
            _is_co, _cp, expr_lineno = self.parameters_back(param, nodes[:-1], function_params, node_lineno)
    return is_co, cp, expr_lineno

(3) 敏感函数检测is_controllable

def is_controllable(self, expr):
    controlled_params = ['getParameter']
    if expr in controlled_params:
        return 1, expr
    return -1, None

4. 完整工作流程

  1. 定义sink函数列表(如executeSql)
  2. 定义修复函数列表(如null2int)
  3. 解析Java代码生成AST
  4. 遍历AST查找sink函数调用
  5. 对每个sink函数的参数进行污点回溯
  6. 判断参数是否来自用户可控输入(source)
  7. 判断传递过程中是否经过修复函数处理
  8. 输出漏洞结果

五、测试与结果

1. 测试代码示例

// _workflowcentertreedata__jsp.java片段
String scope = Util.null2String(request.getParameter("scope"));
String formids = Util.null2String(request.getParameter("formids"));
rs.executeSql("select * from mobileconfig where mc_type=5 and mc_scope=" + scope + "...");

2. 分析结果输出

executeSql in java_src/_workflowcentertreedata__jsp.java:66
[{'code': 1, 'source': 'getParameter', 'source_lineno': 62, 
'sink': 'executeSql', 'sink_param:': 'scope', 'sink_lineno': 66}]

注入参数: 62 | String scope = Util.null2String(request.getParameter("scope"))
注入点: 66 | rs.executeSql("select * from mobileconfig where mc_type=5 and mc_scope=" + scope + "...")

3. 总体分析结果

  • 结合前台可访问的JSP文件列表
  • 过滤后共发现160处注入点
  • 手工验证48个有效EXP

六、优缺点分析

优点

  1. 相比正则匹配,AST分析能获取代码上下文关系,定位更准确
  2. 操作AST语法树更灵活,便于扩展其他分析手段
  3. 结构化分析可发现深层漏洞

缺点

  1. 性能消耗较大
  2. 目前仅支持单文件分析
  3. 未覆盖所有Java Token类型
  4. AST信息维度有限,编写复杂分析逻辑难度大

七、改进方向

  1. 实现跨文件分析能力
  2. 完善Java Token覆盖范围
  3. 结合控制流分析(CFG)提高准确性
  4. 引入中间表示(IR)使分析更通用
  5. 结合机器学习技术提升分析能力

八、总结

本文详细介绍了一种基于AST的Java代码静态分析方法,通过构建AST并分析数据流,有效发现了某知名OA系统中的SQL注入漏洞。该方法相比传统正则匹配更具准确性和扩展性,但仍存在性能和分析深度方面的局限。未来可结合更多静态分析技术进一步提升效果。

基于AST的Java代码审计技术详解 一、背景与概述 本文详细介绍了如何通过分析Java抽象语法树(AST)来自动化挖掘某知名OA系统中的SQL注入漏洞。该方法参考了Cobra工具的PHP解析器实现思路,通过遍历Java AST进行漏洞挖掘,成功筛选出160个前台注入点,并手工编写了约50个前台注入EXP。 二、预备知识 1. 目标系统介绍 某知名OA系统使用Java编写,代码相对古老 SQL查询语句多采用拼接方式,缺乏参数化处理 过滤机制通过统一的Filter实现,存在绕过可能 主要功能通过JSP实现,可编译为Java Servlet 2. 编译原理基础 词法分析:将源代码分解为标记(token) 语法分析:根据语法规则构建AST AST包含程序源文件的所有结构化信息 3. 数据流分析关键概念 Sink(污点函数) :敏感函数如 executeSql 、 Runtime.exec() Source(输入来源) :用户可控输入如 request.getParameter() Repair/Sanitizer(修复函数) :过滤函数如 null2int 、 getIntValue DataFlow(数据流) :变量在代码中的传递路径 三、环境准备 1. 搭建测试环境 下载并安装某知名OA 8 (Ecology8.100.0531) 默认配置安装即可 2. 获取JSP文件路径 3. 获取可访问JSP列表 使用Burp Intruder或Python脚本遍历JSP文件 筛选HTTP响应码为200的JSP文件 4. 获取Servlet.java文件 从 D:\WEAVER\ecology\WEB-INF\work\_jsp 目录复制生成的Servlet文件 四、技术实现 1. Java AST解析器选择 使用Python的 javalang 库解析Java代码为AST 安装: pip install javalang 2. PHP与Java AST节点对照表 | PHP节点 | Java节点 | 描述 | |---------|----------|------| | php.Variable | MemberReference | 变量引用 | | php.FunctionCall | MethodInvocation | 函数调用 | | php.BinaryOp | BinaryOperation | 二元操作 | | php.ArrayOffset | ArraySelector | 数组操作 | | php.Block | BlockStatement | 语句块 | | php.Assignment | Assignment | 赋值语句 | 3. 核心组件实现 (1) 主分析函数 analysis (2) 污点回溯 parameters_back (3) 敏感函数检测 is_controllable 4. 完整工作流程 定义sink函数列表(如 executeSql ) 定义修复函数列表(如 null2int ) 解析Java代码生成AST 遍历AST查找sink函数调用 对每个sink函数的参数进行污点回溯 判断参数是否来自用户可控输入(source) 判断传递过程中是否经过修复函数处理 输出漏洞结果 五、测试与结果 1. 测试代码示例 2. 分析结果输出 3. 总体分析结果 结合前台可访问的JSP文件列表 过滤后共发现160处注入点 手工验证48个有效EXP 六、优缺点分析 优点 相比正则匹配,AST分析能获取代码上下文关系,定位更准确 操作AST语法树更灵活,便于扩展其他分析手段 结构化分析可发现深层漏洞 缺点 性能消耗较大 目前仅支持单文件分析 未覆盖所有Java Token类型 AST信息维度有限,编写复杂分析逻辑难度大 七、改进方向 实现跨文件分析能力 完善Java Token覆盖范围 结合控制流分析(CFG)提高准确性 引入中间表示(IR)使分析更通用 结合机器学习技术提升分析能力 八、总结 本文详细介绍了一种基于AST的Java代码静态分析方法,通过构建AST并分析数据流,有效发现了某知名OA系统中的SQL注入漏洞。该方法相比传统正则匹配更具准确性和扩展性,但仍存在性能和分析深度方面的局限。未来可结合更多静态分析技术进一步提升效果。