标题主要是针对安全人员,如果针对是开发人员的话,应该是 如何快速从众多jar中找到目标类?
在编写Java相关中间件或者CMS的POC/EXP时一般都会依赖它们的某个jar,但它们的jar往往非常多,并且会分散在各个目录下,那么如何快速找到它们呢?
以前我的方法是把所有的jar复制到一个目录下,然后把它们导入到IDEA中,最后使用IDEA搜索。例如最近在写的一个Weblogic漏洞的POC,编译时提示找不到 weblogic.work.ExecuteThread
,这时就可以使用该方法搜索到它在 wlthin3client.jar
中,然后将其引入问题解决。
不过细想,需要以下步骤:
这还是稍微有点繁琐了,那能不能更加轻便快速地找到我们需要的类呢?下面通过编程来优雅地给大家省几秒钟。
我们要实现的是需提供 类名
,和 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
获取下载地址!
我们还是来找Weblogic下 weblogic.work.ExecuteThread
类所在的jar。命令行下运行我们写好的程序,指定要搜索的类名和weblogic安装目录即可。可以有以下三种方式搜索。