wJa(java闭源项目的自动化白盒+黑盒测试工具)
字数 1380 2025-08-24 23:51:23

wJa Java闭源项目自动化白盒+黑盒测试工具教学文档

1. 工具概述

wJa是一款针对Java闭源项目的自动化安全测试工具,主要功能包括:

  • 反编译Java生成的jar包文件
  • 将代码整理成语法树
  • 根据调用链进行污点分析
  • 通过cheetah脚本语言编写测试脚本
  • 确定可能存在的漏洞调用链
  • 生成测试链接进行fuzzer测试

2. 环境准备

2.1 测试环境要求

  • Java运行环境
  • 待测试的Java靶场/项目(如示例中的shootingRange.jar)
  • wJa工具(wJa.jar)

2.2 靶场启动

java -jar shootingRange.jar

2.3 wJa启动

java -jar wJa.jar

3. wJa分析流程

3.1 界面介绍

  • 左侧部分

    • Decompile:jar包反编译的Java资源管理器
    • cheetahLanguage:脚本管理器(包含支持库介绍和编写好的cheetah脚本)
  • 中间部分

    • Decompile:显示反编译的Java代码
    • cheetahLanguage:编写和运行cheetah脚本代码

3.2 基本分析步骤

  1. 使用wJa打开待分析的jar文件
  2. 从控制层(controller)分析入口点
  3. 手动或自动跟踪调用链
  4. 识别危险函数调用

4. 白盒污点分析

4.1 污点分析模型

污点分析可抽象为三元组〈sources, sinks, sanitizers〉:

  • source:污点源(如Spring接口入口点参数)
  • sink:污点汇聚点(如jdbc的query方法)
  • sanitizer:无害处理(如Integer.valueOf()方法)

4.2 关键函数

  • TrackVarIntoFun:跟踪变量流入函数

    • 参数1: 起始类
    • 参数2: 起始方法
    • 参数3: 起始方法参数下标
    • 参数4: 目标方法的类
    • 参数5: 目标方法
    • 参数6: 目标方法的参数下标
    • 返回值: 执行流node数组
  • GetAllMethodName:获取类中所有方法名

    • 注意跳过<init>(构造方法)和<cinit>(静态代码块)
  • GetJavaSentence:从node中获取对应的Java代码

4.3 SQL注入检测脚本示例

#define filter1=String.valueOf(.*?)
#define filter2=Integer.valueOf(.*?)

function filter(sentence){
    a = StrRe(sentence,filter1);
    if(GetArrayNum(a) != 0){return 0;}
    a = StrRe(sentence,filter2);
    if(GetArrayNum(a) != 0){return 0;}
    return 1;
}

function track(className,methodName){
    array allNode;
    allNode = TrackVarIntoFun(className,methodName,0,"org/springframework/jdbc/core/JdbcTemplate","query",0);
    size = GetArrayNum(allNode);
    if(StrFindStr(GetJavaSentence(allNode[ToInt(size-1)]),".query(",0) != "-1"){
        i = 0;
        print(methodName."参数流动:");
        cc = 7;
        cs = 1;
        while(i < size){
            sentence = GetJavaSentence(allNode[i]);
            if(filter(sentence) == 0){cc = 5;cs = 5;printcolor("想办法绕过此类:",4);}
            if(i == ToInt((size-1))){
                if(cc != 5){cs = 2;cc = 3;}
            }else{}
            if(cc == 5){printcolor("[-]",6);}else{printcolor("[+]",1);}
            printcolor(GetClassName(GetNodeClassName(allNode[i]))."   ",cc);
            printcolor(sentence.StrRN(),cs);
            i = ToInt(i+1);
        }
    }
    return 0;
}

function main(args){
    className = "com/l4yn3/microserviceseclab/controller/IndexController";
    methods = GetAllMethodName(className);
    size = GetArrayNum(methods);
    i = 0;
    while(i < size){
        if(methods[i] != "<init>"){track(className,methods[i]);}
        i = ToInt(i+1);
    }
}

5. 黑盒Fuzzer测试

5.1 SQL注入检测函数

function judgeSQLI(api){
    res = HttpGet(api,"");
    res1 = HttpGet(api."%27%20or%201=1--+","");
    if(GetStrLength(res1[0]) != GetStrLength(res[0])){
        res2 = HttpGet(api."%27%20or%202=1--+","");
        if(GetStrLength(res2[0]) == GetStrLength(res[0])){
            return 1;
        }
    }
    return 0;
}

5.2 注解解析函数

wJa提供以下注解解析方法:

  • GetClassAnnotation:获取类注解
  • GetClassMethodAnnotation:获取方法上的注解
  • GetClassMethodArgAnnotation:获取参数上的注解
  • GetAnnotationArgListValue:获取注解中list数据
  • GetAnnotationArgSingValue:获取注解中的数据

示例注解解析函数:

function getSpringAnnotationValue(an){
    anSize = GetArrayNum(an);
    i = 0;
    while(i < anSize){
        if(GetAnnotationName(an[i]) == "org/springframework/web/bind/annotation/RequestMapping"){
            allValue = GetAnnotationArgListValue(an[i],"value");
            return allValue[0];
        }
        if(GetAnnotationName(an[i]) == "org/springframework/web/bind/annotation/PostMapping"){
            allValue = GetAnnotationArgListValue(an[i],"value");
            return allValue[0];
        }
        if(GetAnnotationName(an[i]) == "org/springframework/web/bind/annotation/RequestParam"){
            allValue = GetAnnotationArgSingValue(an[i],"value");
            return allValue;
        }
        i = ToInt(i + 1);
    }
    return "";
}

6. 白盒+黑盒自动化测试

6.1 完整测试脚本

#define filter1=String.valueOf(.*?)
#define filter2=Integer.valueOf(.*?)

function filter(sentence){
    a = StrRe(sentence,filter1);
    if(GetArrayNum(a) != 0){return 0;}
    a = StrRe(sentence,filter2);
    if(GetArrayNum(a) != 0){return 0;}
    return 1;
}

function judgeSQLI(api){
    res = HttpGet(api,"");
    res1 = HttpGet(api."%27%20or%201=1--+","");
    if(GetStrLength(res1[0]) != GetStrLength(res[0])){
        res2 = HttpGet(api."%27%20or%202=1--+","");
        if(GetStrLength(res2[0]) == GetStrLength(res[0])){
            return 1;
        }
    }
    return 0;
}

function track(className,methodName,url){
    array allNode;
    allNode = TrackVarIntoFun(className,methodName,0,"org/springframework/jdbc/core/JdbcTemplate","query",0);
    size = GetArrayNum(allNode);
    if(StrFindStr(GetJavaSentence(allNode[ToInt(size-1)]),".query(",0) != "-1"){
        i = 0;
        print(methodName."白盒测试调用链跟踪:");
        cc = 7;
        cs = 1;
        while(i < size){
            sentence = GetJavaSentence(allNode[i]);
            noSan = filter(sentence);
            if(noSan == 0){cc = 5;cs = 5;}
            if(i == ToInt((size-1))){
                if(cc != 5){cs = 2;cc = 3;}
            }else{}
            if(noSan == 0){
                printcolor("[-]",6);printcolor("想办法绕过此类:",4);
            }else{
                printcolor("[+]",1);
            }
            printcolor(GetClassName(GetNodeClassName(allNode[i]))."   ",cc);
            printcolor(sentence.StrRN(),cs);
            i = ToInt(i+1);
        }
        if(cc != 5){
            printcolor("白盒测试发现此调用链可能存在漏洞,生成测试链接进行黑盒测试".StrRN(),7);
            an = GetClassMethodAnnotation(className,methodName);
            arg_an = GetClassMethodArgAnnotation(className,methodName,0);
            argName = getSpringAnnotationValue(arg_an);
            if(argName != ""){
                api = url.getSpringAnnotationValue(an)."?".argName."=Wker";
                if(judgeSQLI(api) == 1){
                    printcolor("[+]生成测试链接:".api."   测试存在SQL注入漏洞!".StrRN(),3);
                }else{
                    printcolor("[-]生成测试链接:".api."   测试不存在SQL注入漏洞!请自行测试。".StrRN(),5);
                }
            }else{
                printcolor("测试链接生成失败,error:未找到参数入口!".StrRN(),5);
            }
        }
    }
    return 0;
}

function getSpringAnnotationValue(an){
    anSize = GetArrayNum(an);
    i = 0;
    while(i < anSize){
        if(GetAnnotationName(an[i]) == "org/springframework/web/bind/annotation/RequestMapping"){
            allValue = GetAnnotationArgListValue(an[i],"value");
            return allValue[0];
        }
        if(GetAnnotationName(an[i]) == "org/springframework/web/bind/annotation/PostMapping"){
            allValue = GetAnnotationArgListValue(an[i],"value");
            return allValue[0];
        }
        if(GetAnnotationName(an[i]) == "org/springframework/web/bind/annotation/RequestParam"){
            allValue = GetAnnotationArgSingValue(an[i],"value");
            return allValue;
        }
        i = ToInt(i + 1);
    }
    return "";
}

function main(args){
    className = "com/l4yn3/microserviceseclab/controller/IndexController";
    an = GetClassAnnotation(className);
    classPath = "http://127.0.0.1:8080".getSpringAnnotationValue(an);
    methods = GetAllMethodName(className);
    size = GetArrayNum(methods);
    i = 0;
    while(i < size){
        if(methods[i] != "<init>"){track(className,methods[i],classPath);}
        i = ToInt(i+1);
    }
}

6.2 优化版本(自动扫描所有类)

function SQLTrack(className){
    an = GetClassAnnotation(className);
    classPath = "http://127.0.0.1:8080".getSpringAnnotationValue(an);
    methods = GetAllMethodName(className);
    size = GetArrayNum(methods);
    i = 0;
    while(i < size){
        if(methods[i] != "<init>"){track(className,methods[i],classPath);}
        i = ToInt(i+1);
    }
    return 0;
}

function main(args){
    allClass = GetAllClassName();
    size = GetArrayNum(allClass);
    i = 0;
    while(i < size){
        an = GetClassAnnotation(allClass[i]);
        p = getSpringAnnotationValue(an);
        if(p != ""){
            SQLTrack(allClass[i]);
        }
        i = ToInt(i + 1);
    }
}

7. 复杂调用链分析

wJa能够处理以下复杂情况:

  1. 接口实现分析:自动分析子类对象和实现类是否进入危险函数
  2. 变量转换跟踪:自动追加追踪接受追踪变量的变量
    • 如从name变量追踪到sql变量

8. SSRF漏洞分析

8.1 危险函数识别

url = new URL(data);
con = url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent","Mozilla/5.0");
in = new BufferedReader(new InputStreamReader(con.getInputStream()));

8.2 SSRF检测函数

function judgeSSRF(api){
    res = HttpGet(api."http://www.baidu.com","");
    if(StrFindStr(res[0],"//www.baidu.com/",0) != "-1"){
        return 1;
    }
    return 0;
}

9. 学习资源

  • cheetah语法学习:https://github.com/Wker666/Demo
    • 包含500+渗透测试脚本
    • 详细cheetah语法说明
wJa Java闭源项目自动化白盒+黑盒测试工具教学文档 1. 工具概述 wJa是一款针对Java闭源项目的自动化安全测试工具,主要功能包括: 反编译Java生成的jar包文件 将代码整理成语法树 根据调用链进行污点分析 通过cheetah脚本语言编写测试脚本 确定可能存在的漏洞调用链 生成测试链接进行fuzzer测试 2. 环境准备 2.1 测试环境要求 Java运行环境 待测试的Java靶场/项目(如示例中的shootingRange.jar) wJa工具(wJa.jar) 2.2 靶场启动 2.3 wJa启动 3. wJa分析流程 3.1 界面介绍 左侧部分 : Decompile:jar包反编译的Java资源管理器 cheetahLanguage:脚本管理器(包含支持库介绍和编写好的cheetah脚本) 中间部分 : Decompile:显示反编译的Java代码 cheetahLanguage:编写和运行cheetah脚本代码 3.2 基本分析步骤 使用wJa打开待分析的jar文件 从控制层(controller)分析入口点 手动或自动跟踪调用链 识别危险函数调用 4. 白盒污点分析 4.1 污点分析模型 污点分析可抽象为三元组〈sources, sinks, sanitizers〉: source :污点源(如Spring接口入口点参数) sink :污点汇聚点(如jdbc的query方法) sanitizer :无害处理(如Integer.valueOf()方法) 4.2 关键函数 TrackVarIntoFun :跟踪变量流入函数 参数1: 起始类 参数2: 起始方法 参数3: 起始方法参数下标 参数4: 目标方法的类 参数5: 目标方法 参数6: 目标方法的参数下标 返回值: 执行流node数组 GetAllMethodName :获取类中所有方法名 注意跳过 <init> (构造方法)和 <cinit> (静态代码块) GetJavaSentence :从node中获取对应的Java代码 4.3 SQL注入检测脚本示例 5. 黑盒Fuzzer测试 5.1 SQL注入检测函数 5.2 注解解析函数 wJa提供以下注解解析方法: GetClassAnnotation :获取类注解 GetClassMethodAnnotation :获取方法上的注解 GetClassMethodArgAnnotation :获取参数上的注解 GetAnnotationArgListValue :获取注解中list数据 GetAnnotationArgSingValue :获取注解中的数据 示例注解解析函数: 6. 白盒+黑盒自动化测试 6.1 完整测试脚本 6.2 优化版本(自动扫描所有类) 7. 复杂调用链分析 wJa能够处理以下复杂情况: 接口实现分析 :自动分析子类对象和实现类是否进入危险函数 变量转换跟踪 :自动追加追踪接受追踪变量的变量 如从 name 变量追踪到 sql 变量 8. SSRF漏洞分析 8.1 危险函数识别 8.2 SSRF检测函数 9. 学习资源 cheetah语法学习:https://github.com/Wker666/Demo 包含500+渗透测试脚本 详细cheetah语法说明