转载

如何快速找到POC/EXP依赖的jar?

标题主要是针对安全人员,如果针对是开发人员的话,应该是 如何快速从众多jar中找到目标类?

在编写Java相关中间件或者CMS的POC/EXP时一般都会依赖它们的某个jar,但它们的jar往往非常多,并且会分散在各个目录下,那么如何快速找到它们呢?

0x01 之前的方案

以前我的方法是把所有的jar复制到一个目录下,然后把它们导入到IDEA中,最后使用IDEA搜索。例如最近在写的一个Weblogic漏洞的POC,编译时提示找不到 weblogic.work.ExecuteThread ,这时就可以使用该方法搜索到它在 wlthin3client.jar 中,然后将其引入问题解决。

如何快速找到POC/EXP依赖的jar?

不过细想,需要以下步骤:

  1. 新建目录
  2. 复制所有jar到目录下
  3. 打开IDEA
  4. 将所有jar导入IDEA
  5. 在IDEA中搜索目标类

这还是稍微有点繁琐了,那能不能更加轻便快速地找到我们需要的类呢?下面通过编程来优雅地给大家省几秒钟。

0x02 编写代码

我们要实现的是需提供 类名 ,和 jar所在目录 就可搜索的小工具,它支持完整类名搜索,也支持通配符。具体如何实现,请参考我代码中的注释和提供的参考文章链接。

package me.gv7.searchclassinjar;

import java.io.File;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.regex.Pattern;

/**
 * author: c0ny1
 * date: 2019-05-13 23:51:42
 * description: 快速从众多jar中,搜索目标class所在的jar。不区分大小写,支持通配符搜索。
 * reference:
 *  1.https://jdkleo.iteye.com/blog/2392642
 *  2.https://lihong11.iteye.com/blog/1936694
 */


public class SearchClassInJar{
    private String className;
    private String jarDir;
    private Integer totalNum =  0;

    public SearchClassInJar(String className,String jarDir){
        this.className = className;
        this.jarDir = jarDir;
    }

    //将jar中的类文件路径形式改为包路径形式
    protected String getClassName(ZipEntry entry){
        StringBuffer className = new StringBuffer(entry.getName().replace('/','.'));
        return className.toString();
    }

    // 从jar从搜索目标类
    public void searchClass(boolean recurse){
        searchDir(this.jarDir, recurse);
        System.out.println(String.format("[!] Find %s classes",this.totalNum));
    }

    //递归搜索目录和子目录下所有jar和zip文件
    protected void searchDir(String dir,boolean recurse){
        try {
            File d = new File(dir);
            if (!d.isDirectory()) {
                return;
            }
            File[] files = d.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (recurse && files[i].isDirectory()) {
                    searchDir(files[i].getAbsolutePath(), true);
                } else {
                    String filename = files[i].getAbsolutePath();
                    if (filename.endsWith(".jar")||filename.endsWith(".zip")) {
                        ZipFile zip = new ZipFile(filename);
                        Enumeration entries = zip.entries();
                        while (entries.hasMoreElements()) {
                            ZipEntry entry = (ZipEntry) entries.nextElement();
                            String thisClassName = getClassName(entry);
                            if (wildcardEquals(this.className.toLowerCase(),thisClassName.toLowerCase()) || wildcardEquals(this.className.toLowerCase() + ".class",thisClassName.toLowerCase())) {
                                String res = String.format("[+] %s | %s",thisClassName,filename);
                                System.out.println(res);
                                totalNum++;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //通配符匹配
    private boolean wildcardEquals(String wildcard, String str){
        String regRule = WildcardToReg(wildcard);
        return Pattern.compile(regRule).matcher(str).matches();
    }

    //将通配符转换为正则表达式
    private static String WildcardToReg(String path){
        char[] chars = path.toCharArray();
        int len = chars.length;
        StringBuilder sb = new StringBuilder();
        boolean preX = false;
        for(int i=0;i<len;i++){
            if (chars[i] == '*'){
                if (preX){
                    sb.append(".*");
                    preX = false;
                }else if(i+1 == len){
                    sb.append("[^/]*");
                }else{
                    preX = true;
                    continue;
                }
            }else{
                if (preX){
                    sb.append("[^/]*");
                    preX = false;
                }
                if (chars[i] == '?'){
                    sb.append('.');
                }else{
                    sb.append(chars[i]);
                }
            }
        }
        return sb.toString();
    }

    public static void main(String args[]){
        if(args.length < 2){
            System.out.println("SearchClassInJar v0.1");
            System.out.println("Autor:c0ny1<root@gv7.me>");
            System.out.println("Usage:java -jar SearchClassInJar.jar <ClassName> <JarDir>");
            System.out.println("Example:java -jar SearchClassInJar.jar weblogic.work.ExecuteThread C://weblogic");
            return;
        }
        SearchClassInJar scij = new SearchClassInJar(args[0],args[1]);
        scij.searchClass(true);
    }
}

使用方法:

java -jar SearchClassInJar.jar <ClassName> <JarDir>

PS:大家可自行编译,若需要我编译好的,请公众号后台回复 SearchClassInJar 获取下载地址!

0x03 演示效果

我们还是来找Weblogic下 weblogic.work.ExecuteThread 类所在的jar。命令行下运行我们写好的程序,指定要搜索的类名和weblogic安装目录即可。可以有以下三种方式搜索。

如何快速找到POC/EXP依赖的jar?

0x04 参考文章

  • java实现路径通配符 ,* ,?
  • 查找某个类所在jar包
原文  http://gv7.me/articles/2019/quickly-find-jars-that-depend-on-poc-exp/
正文到此结束
Loading...