标题主要是针对安全人员,如果针对是开发人员的话,应该是 如何快速从众多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安装目录即可。可以有以下三种方式搜索。