今はシリアル化していますが、今はしていません — デシリアライゼーションのエクスプロイトを体系的に探しています

CVE-2019-18211 Exploit - Request news

デシリアライゼーションの脆弱性は、長年にわたって複数の言語やアプリケーションを悩ませてきたバグの一種です。これらには、Exchange ( CVE-2021-42321 )、Zoho ManageEngine ( CVE-2020-10189 )、Jira ( CVE-2020-36239 )、Telerik ( CVE-2019-18935 )、Jenkins ( CVE-2016-9299 ) などが含まれます。 .基本的に、これらのバグは、ユーザー (または攻撃者) が改ざんできるデータをアプリケーションが信頼しすぎた結果です。

攻撃者は何年もの間、これらの脆弱性を利用して、ファイルのアップロード、不正なリソースへのアクセス、標的のサーバーでの悪意のあるコードの実行を行ってきました。過去 2 年間、Mandiant は特に、 APT41が .NET ViewState および Java デシリアライゼーション エクスプロイトを使用して、北米の企業や政府機関を標的にしていることを観察してきました。

これらの脆弱性の蔓延と影響を考慮して、私たちの目標は、悪用の試みを体系的に追跡するプロセスを作成することでした。このブログ投稿では、新しいルール生成ツール ( HeySerial.py ) と検証ツール ( CheckYoself.py ) を共有し、それらの作成に使用した調査プロセスについて説明します。

このブログ記事は主にデシリアライゼーションのエクスプロイトに焦点を当てていますが、ここで紹介するツールとプロセスは、他のタイプのゼロデイのエクスプロイトを探すのに役立ちます。たとえば、HeySerial を使用して、先週リリースされた log4j のゼロデイ JNDI コード インジェクション ( CVE-2021-44228 ) のハンティング ルールを生成できます。詳細については、この投稿の後半にある「CVE-2021-44228 に関する注意事項」セクションを確認してください。

問題を理解する

逆シリアル化の脆弱性とは何ですか?

「シリアル化された」データは、ネットワーク経由などで簡単に転送できるようにエンコードされた単なるオブジェクトまたはデータ構造です。開発者はこれを定期的に行い、アプリケーションのさまざまな部分間、またはクライアントとサーバー間でオブジェクトを渡し、状態を維持します。転送されたら、「逆シリアル化」して、元の機能から離れないように使用できます。

デシリアライゼーションの脆弱性は、ユーザー (または攻撃者) が変更できるデータをアプリケーションが過度に信頼しているために発生します。次の 3 つの条件が満たされると、逆シリアル化が危険になる可能性があります。

  • シリアル化されたオブジェクトは、ユーザーによって提供されるか、ユーザーが変更できます。
  • アプリケーションは、検証なしでオブジェクトをデシリアライズして使用しようとします。
  • オブジェクトは、アプリケーションの一部によって、「クラス パス」にある貴重なライブラリを使用して逆シリアル化されます。

逆シリアル化の問題を悪用するには、無害なオブジェクトまたはデータ構造 (セッション トークンや ViewState など) を、攻撃者にとって悪意のあるものを実行するターゲット言語のコードに置き換えるペイロードを作成する必要があります。

危険なクラスまたはライブラリがインポートされ、アプリケーションの「クラス パス」にアクセスできる場合、攻撃者は有用な関数またはオブジェクト タイプ (「ガジェット」とも呼ばれます) を参照してペイロードを実行できます。アプリケーションの構造上、危険な機能に直接アクセスできない場合があるため、エクスプロイトを成功させるには、多くの場合、複数のガジェットを連鎖させる必要があります。

YSoSerial (Java) や YSoSerial .NET (C#) などのプロジェクトは、一般的なライブラリの成功したガジェット チェーンに関する公開研究を統合し、これらのチェーンの 1 つを使用して誰でも簡単にペイロードを生成できるようにします。これはエンコードされ、逆シリアル化のバグがあるサーバーに渡される可能性があります。これらのガジェットがインポートされたアプリケーションが安全でない方法でペイロードを逆シリアル化すると、チェーンが自動的に呼び出され、影響を受けるサーバーで埋め込みコマンドが実行されます。

エクスプロイトの成功とは?

HTTP サーバーの逆シリアル化の問題は、セッション/状態データ、 Cookie 、HTML フォームの入力など、さまざまな場所で発生する可能性があります。リモートコード実行に。

悪意のあるペイロードを含む HTTP SOAP 要求を図 1に示し、サーバーの応答を図 2に示します。この場合、サーバーは、提供されたオブジェクトを逆シリアル化して実行した後、単純な HTTP 200 OK 応答を返しました。

CVE-2019-18211 Exploit - Request
図 1: CVE-2019-18211 エクスプロイト – リクエスト
CVE-2019-18211 エクスプロイト - 対応
図 2: CVE-2019-18211 エクスプロイト – レスポンス

問題表面積

前述のように、デシリアライゼーションの脆弱性は、さまざまな言語やライブラリに影響を与える可能性があり、その結果、攻撃者にとって非常に大きな領域になります。包括的なハンティング戦略を開発する前に、問題空間を完全に理解する必要があります。

さまざまなプロトコル

このクラスの脆弱性は、Web アプリケーションのコンテキストで最も一般的に議論されますが、影響を受けるアプリケーションはそれだけではありません。

2017 年、 Google Project Zeroは、.NET デシリアライゼーションを使用して、HTTP ではなく Managed DCOM を介してシステムをターゲットにする方法を示しました。特にデシリアライゼーションではありませんが、2016 年に 2 つの異なる Black Hat の講演で、オブジェクト/コマンド インジェクションを通じてJava Messaging Service (JMS) API とJava Naming and Directory Interface (JNDI) API を悪用する方法が概説されました。ちょうど先週、log4j Java ロギング パッケージ ( CVE-2021-44228 ) の JNDI コマンド インジェクション0-デイがリリースされました。

このブログ投稿では、HTTP 経由で発生する攻撃に範囲を限定します。これにより、デシリアライゼーションのエクスプロイト試行の大部分をターゲットにしながら、初期の調査に集中することができます。

言語とオブジェクト

理論的にはどの言語も危険にさらされる可能性がありますが、このクラスの脆弱性で悪用される一般的な言語/オブジェクト タイプの一部は、シリアル化された Java オブジェクト、.NET ViewStates、pickled Python オブジェクト、およびシリアル化された PHP オブジェクトです。次の表は、これらの各オブジェクト タイプのプレフィックスとして使用されるヘッダー値の詳細を示しています。

オブジェクトの種類

ヘッダー (16 進数)

ヘッダー (Base64)

Java シリアライズ

ACED

rO

.NET ビューステート

FF01

/週

パイソンピクルス

80 04 95

gASV

PHP シリアライズ*

4F 3A

ツツ

*PHP のシリアライズされたオブジェクトは、ASCII のO:LENGTH_OF_NAMEで始まります。LENGTH_OF_NAME は整数です。 4F 3A は O: の 16 進エンコードですが、誤検知を避けるためにO:[0-9]+:のような正規表現でさらに調整する必要があります。

オブジェクトは、言語固有のフォーマッターを使用してシリアル化することもできます。たとえば、.NET アプリケーションは、脆弱なガジェットに応じて、BinaryFormatter、LosFormatter、NetDataContractSerializer、Json.NET、または SoapFormatterなどのフォーマッターを使用する場合があります。 YSoSerial.NET は、サポートされているほとんどのフォーマッタに対して UTF-16LE オブジェクトを生成するため、これらのペイロードの多くは 0xFFFE で始まることに注意してください。

エンコーディング

シリアル化されたオブジェクトは raw バイトを使用して転送できますが、ネットワーク転送を簡単にするために何らかの方法でエンコードまたは暗号化されることがよくあります。 Base64 は、言語に依存せず、実装が簡単であるため、非常に一般的です。

エンコード方法も階層化できます。たとえば、オブジェクトを GZIP 圧縮してから Base64 エンコードするなどです。このブログ投稿では、一般的な Base64 エンコーディングに焦点を当てます。

既知のチェーンと未知のチェーン

最後に、この問題空間には多くの未知数が含まれています。デシリアライゼーションの脆弱性は定期的に公開されており、前述のように、アプリケーションのあらゆる部分に影響を与える可能性があります。攻撃者がこれらの脆弱性を兵器化する方法ははるかに限られています。防御者として、攻撃者が最終的なペイロードを実行するために使用する必要があるガジェット チェーンとキーワードを探すことで、新しいエクスプロイトを探す機会があります。

セキュリティ研究者 (および攻撃者) は、共通のライブラリやアプリケーションで新しい危険なガジェット チェーンを常に探しています。この研究を一元化するいくつかの有名なプロジェクトを次の表に示しますが、これは決して包括的なリストではありません。このブログ投稿では、ysoserial Java プロジェクトから始めます。これは、このクラスのバグに対してリリースされた最初の主要なツールおよび調査でした。

プロジェクト名

影響を受ける言語/ソフトウェア

GitHub URL

イソシリアル

ジャワ

https://github.com/frohoff/ysoserial

ysoserial (分岐)

ジャワ

https://github.com/w1t3p1g/ysoserial

ysoserial.net

.NET 3.5

https://github.com/pwntester/ysoserial.net

ysoserial.net v2 ブランチ

.NET 2 (現在、v3.5 のチェーンのみ)

https://github.com/pwntester/ysoserial.net/tree/v2

この研究活動では、既知のガジェット チェーンのルールを生成する方法を特定したいと考えていますが、新しい脆弱性やガジェット チェーンの悪用の試みを積極的に特定できる、より一般化されたアプローチも求めています。ここでの 1 つの方法は、ペイロードと、ペイロードの実行に使用されるチェーンを探すことです。たとえば、DOS ヘッダー、悪意のあるコマンド、疑わしいバイナリを含むシリアル化されたオブジェクトを探すことができます。

溶液表面積

何を探しているかを理解したところで、次はそれをどのように探すかを決定する必要があります。利用可能な検出範囲は、目的と可視性によって異なりますが、通常、ハンティングの機会は次の 3 つのカテゴリに分類されます。

  • 通信網
    • この攻撃方法を検出する最も直接的な方法は、リクエストが作成されたときに悪用の試みを観察することです。
  • エンドポイント – 動的
    • これには、Web サーバーからの異常なプロセス実行または動作の検索が含まれる場合があります。 (たとえば、 cmd.exe /c whoamiを実行している IIS サーバー。)ただし、これにより、成功したエクスプロイト試行のみを観察することが制限され、リモート コード実行 (RCE) のエクスプロイトに偏ることになります。ファイルのアップロードやリモート URL の組み込みなど、他の目的への悪用に対する可視性が制限される場合があります。
  • エンドポイント – 静的 (ログ/ファイル)
    • ネットワーク トラフィックの可視性によっては、YARA ルールを使用してサーバー ログで復号化されたリクエストを調べると、ネットワーク IOC よりも悪用の試みに対して同じ (またはより良い) 可視性が得られる場合があります。ここでの制限の 1 つは、ログに完全なサーバー応答が含まれていない可能性があるため、証拠が不完全になることです。

このブログ記事では、ネットワーク ハンティング (Snort ルールによる) と静的ログ ファイル ハンティング (YARA ルールによる) に焦点を当てます。

メイク・オア・ブレイク

対処したい問題領域を把握したので、ハンティング プランを定義できます。ハンティング ロジックを生成し、疑わしいガジェット チェーンと疑わしいキーワードの両方について、さまざまな検出ルール形式に変換できるアプローチが必要です。また、オブジェクト タイプとエンコーディング方法の変動性も考慮する必要があります。

ツール

これは複雑な種類のバグであるため、ルール生成用の Python ツールであるHeySerialを作成することから始めました。これにより、検出ロジックのプロトタイプを迅速に作成できるようになり、新しい脆弱性が発見されるたびに対応できるようになります。

公開時点で、HeySerial は次のオプションをサポートしています。

国旗

説明

オプション (デフォルトは太字)

フォーマット

-k

キーワード

なし

文字列のスペース区切りリスト

-c

ガジェットチェーン

なし

チェーンのスペース区切りリスト

チェーン形式 – <Name>::<key1>+<key2>…

-t

オブジェクト タイプ

JavaObj、PythonPickle、PHPObj、…

文字列のスペース区切りリスト

完全なリストについては、ヘルプ (-h) を参照してください。

-e

エンコード方法

base64、生、utf8、utf16le

文字列のスペース区切りリスト

単一のメソッドおよび/またはチェーン。

チェーン形式 – <メソッド 1>+<メソッド 2>

-o

ルール出力タイプ

鼻を鳴らすやら

文字列のスペース区切りリスト

-r

レポートの種類

バー、tsv

文字列のスペース区切りリスト

既知の脆弱なチェーンを持つ ViewState オブジェクトのルールを生成するには:

python3 heyserial.py -c 'ExampleChain::mscorlib+ActivitySurrogateSelector' -t NETViewState

疑わしいキーワードを含むすべてのオブジェクト タイプのルールを生成するには:

python3 heyserial.py -k cmd.exe whoami ‘This file cannot be run in DOS mode’

UTF-16LE でエンコードされた Base64 でエンコードされたキーワードを使用して ViewState オブジェクトのルールを生成するには:

python3 heyserial.py -k Process.Start -t NETViewState -e “base64+utf16le”

HeySerial がサポートする初期エンコーディングとオブジェクト タイプの数は限られていますが、拡張できるように設計されています。 HeySerial を拡張し、新しいエンコーディング メソッド、オブジェクト タイプ、ルール形式を追加する方法の詳細については、開発者ガイドをご覧ください。

Ex(ploits) を解く

次のステップは、ルールをテストするためのペイロードを収集 (または作成) することです。前述のように多くの公開プロジェクトがありますが、ここでは ysoserial Java ガジェット チェーンに焦点を当てます。 YSoSerial は README にサポートされているチェーンをリストしていますが、リストは 3 つ以上あるので自動化しましょう!

YSoSerial Java ペイロード オプション
図 3: YSoSerial Java ペイロード オプション

次のコマンドは、CommonsCollections1 チェーンを使用して「calc.exe」を起動するペイロードを生成します。ペイロードの生の 16 進バイトを図 4 に示します。ファイルの内容を直接出力すると、図 5 に示すように、興味深い文字列が他の出力不可能な (非 ASCII) 文字と混在していることがわかります。

java -jar utils/ysoserial.jar CommonsCollections1 calc.exe > commonscollections1.bin

CommonsCollections1 ペイロード
図 4: CommonsCollections1 ペイロード
CommonsCollections1 YSoSerial ペイロードの検査
図 5: CommonsCollections1 YSoSerial ペイロードの検査

簡単な Bash スクリプトを使用して、サポートされているチェーンのリストをループし、それらをファイルに出力できます。一部のチェーンは他のチェーンとは異なるペイロード入力を必要とするため、 generate_payloads.shをチェックして、switch-case ブロックでそれを処理する方法を確認してください。 YSoSerial.NETペイロードの場合は、Windows システムでgenerate_payloads.ps1スクリプトを試してください。

Base64 ルールをテストしたいので、Base64 でエンコードされたペイロードを別のファイルに保存するコマンドをペイロード生成スクリプトに追加することもできます。

base64 -w 0 “$filename.bin” > “$filename.base64”

PCAPs またはそれが起こらなかった

ペイロードが生成されたので、ファイルに対して YARA を実行するだけで、ルールを検証できます。ただし、Snort ルールをテストするには、「悪意のある」Web リクエストを示すペイロードを含む PCAP を生成する必要があります。

そのために、このserver.pyスクリプトを使用して基本的な HTTP サーバーを起動し、別のターミナルで次の Bash コマンドを実行できます。これにより、リクエストの本文に各ペイロードが含まれるプレーンな HTTP POST リクエストがローカル サーバーに送信されます。

for sample in `ls *.bin`; do curl -m 3 --data-binary “@$sample” http://127.0.0.1:12345; done;

for sample in `ls *.base64`; do curl -m 3 --data “@$sample” http://127.0.0.1:12345; done;

テスト目的のため、実際の脆弱性や Web サーバーを悪用する必要はありません。エクスプロイトの試みのように見えるネットワーク トラフィックが必要なだけです。これらのPCAPと既に生成したペイロード ファイルを使用して、Snort と YARA ルールの両方をテストできます。

ゴールデンルール

ペイロードがあり、スクリプトがあります。ついに狩猟ルールを作る時が来ました!各チェーンに含めたいキーワードのリストを識別する方法はたくさんあります。 YSoSerial リポジトリには、ペイロードを構成するクラスと関数の詳細が含まれていますが、これは

  1. 異なるファイルに散らばっている
  2. 最終的なシリアル化されたオブジェクトの内容と完全に一致するとは限りません

インポートされたクラスまたは関数を一括抽出するもう 1 つの簡単な方法は、すべての (生の 16 進) ペイロードをループ処理し、最初の 5 つの文字列を「..*.」で取得することです。パターン。これを実現するには、Bash スクリプトに次の行を追加します。

strings “$filename.bin” | grep -E ‘..*.’ | head -5 > “$filename.strings”

このアプローチでは、文字列を手動でクリーンアップする必要がありますが、完了したら、これらのクラスまたは関数がデフォルトの YSoSerial Java ペイロードに含まれていることを認識してルールを生成できます。

(注意してください、これら (特に YARA) はすべて調査目的のハンティング ルールであり、検出ではありません。環境のテストと調整を行わずに、これらを本番システムに展開しないでください。 )

次のコマンドは、YSoSerial (Java) のいくつかの一般的なペイロードに対して raw および Base64 でエンコードされたチェーンの両方を持つ Snort および YARA ルールを生成します。

python3 heyserial.py -t JavaObj -e base64 raw -o snort yara -c "AspectJWeaver::HashSet+TiedMapEntry+org.apache.commons.collections.functors+ConstantTransformer+org.aspectj.weaver.tools.cache.SimpleCache+StoreableCachingMap" "BeanShell1: :java.util.PriorityQueue+Comparator+java.lang.reflect.Proxy+Hashtable+Vector" "C3P0::com.mchange.v2.c3p0.PoolBackedDataSource+AbstractPoolBackedDataSource+PoolBackedDataSourceBase+com.mchange.v2.naming.ReferenceIndirector+ReferenceSerializedb " "Click1::java.util.PriorityQueue+org.apache.click.control.Column+Column+Table+AbstractControl" "Clojure::HashMap+clojure.inspector.proxy+javax.swing.table.AbstractTableModel+ff19274+EventListenerList +clojure.lang.PersistentArrayMap" "CommonsBeanutils1::java.util.PriorityQueue+org.apache.commons.beanutils+BeanComparator+ComparableComparator+com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl" "CommonsCollections1_3: :sun.reflect.annotation.AnnotationInvocationHandler+Map+Proxy+org.apache.commons.collections.map.LazyMap+org.apache. commons.collections.functors.ChainedTransformer" "CommonsCollections2::java.util.PriorityQueue+org.apache.commons.collections4.comparators.TransformingComparator+ComparableComparator+InvokerTransformer+Object" "CommonsCollections4::java.util.PriorityQueue+org.apache. commons.collections4.comparators.TransformingComparator+ComparableComparator+ChainedTransformer" "CommonsCollections5::javax.management.BadAttributeValueExpException+org.apache.commons.collections.keyvalue.TiedMapEntry+org.apache.commons.collections.map.LazyMap+org.apache. commons.collections.functors.ChainedTransformer+java.lang.Runtime" "CommonsCollections6::java.util.HashSet+org.apache.commons.collections.keyvalue.TiedMapEntry+org.apache.commons.collections.map.LazyMap+ChainedTransformer" "CommonsCollections7::java.util.Hashtable+org.apache.commons.collections.map.LazyMap+ChainedTransformer+ConstantTransformer" "FileUpload1::org.apache.commons.fileupload.disk.DiskFileItem+java.io.File" "Groovy1::sun.reflect.annotation. AnnotationInvocationHandler+Map+Proxy+org.codehaus.groovy.runtime.ConvertedClosure+org.codehaus.groovy.runtime.ConversionHandler" "Hibernate1_2::java.util.HashMap+org.hibernate.engine.spi.TypedValue+org.hibernate. type+ComponentType+AbstractType+org.hibernate.tuple.component.PojoComponentTuplizer" "JavassistWeld1::org.jboss.weld.interceptor.proxy.InterceptorMethodHandler+org.jboss.weld.interceptor.builder.InterceptionModelImpl+LinkedHashSet+HashSet+org. jboss.weld.interceptor.reader.SimpleInterceptorMetadata" "JBossInterceptors1::org.jboss.interceptor.proxy.InterceptorMethodHandler+org.jboss.interceptor.builder.InterceptionModelImpl+LinkedHashSet+HashSet+org.jboss.interceptor.reader.SimpleInterceptorMetadata" "Jdk7u21 ::java.util.LinkedHashSet+HashSet+com.sun.org.apache.xalan.internal.xsltc .trax.TemplatesImpl+javax.xml.transform.Templates+java.lang.reflect.Proxy" "JRMPClient::java.rmi.registry.Registry+java.lang.reflect.Proxy+java.rmi.server.RemoteObjectInvocationHandler" " JRMPListener::sun.rmi.server.ActivationGroupImpl+java.rmi.activation.ActivationGroup+java.rmi.server.UnicastRemoteObject+java.rmi.server.RemoteServer+java.rmi.server.RemoteObject" "Jython1::java.util .PriorityQueue+java.util.Comparator+java.lang.reflect.Proxy+org.python.core.PyFunction+org.python.core.PyObject" "MozillaRhino1::org.mozilla.javascript.NativeError+org.mozilla.javascript" .NativeJavaObject+org.mozilla.javascript.MemberBox" "MozillaRhino2::org.mozilla.javascript.NativeJavaObject+org.mozilla.javascript.tools.shell.Environment+org.mozilla.javascript.ScriptableObject+java.util.Hashtable+org .モジラ。javascript.ClassCache" "Myfaces1_2::java.util.HashMap+org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression+javax.el.MethodExpression+javax.el.Expression+org.apache.el.ValueExpressionImpl" "ROME ::java.util.HashMap+com.sun.syndication.feed.impl.ObjectBean+com.sun.syndication.feed.impl.CloneableBean+java.util.Collections+EmptySet+com.sun.org.apache.xalan. internal.xsltc.trax.TemplatesImpl" "Spring1_2::org.springframework.core.SerializableTypeWrapper+MethodInvokeTypeProvider+TypeProvider+java.lang.reflect.Proxy+sun.reflect.annotation.AnnotationInvocationHandler+java.util.HashMap" "URLDNS:: java.util.HashMap+java.net.URL" "Vaadin1::javax.management.BadAttributeValueExpException+com.vaadin.data.util.PropertysetItem+com.vaadin.data.util.NestedMethodProperty+com.sun.org.apache. xalan.internal.xsltc.trax.TemplatesImpl" "Wicket1::org.apache.wicket.util.upload.DiskFileItem+java.io.File"

テストする

それでは、エキサイティングな部分です。実際にすべてを見ることです。

子供のルール

ファイルに対する YARA ルールのテストは、 YARA がインストールされていれば非常に簡単です。生成したルールをファイルに保存してから、次のコマンドを実行できます。

yara ysoserial_CommonsCollections1.yar ysoserial_CommonsCollection1.bin

うまくいけば、ルール名と一致したファイルを含む行が表示されます。図 6の最後の行は、YARA ルールが一致することを示しています。

YARA ルールのテスト
図 6: YARA ルールのテスト

Snort ルール

Snort のローカル インストールを使用して Snort ルールをテストすることもできます。無効な (または重複した) 署名 ID がある場合、Snort はエラーをスローするため、このコマンドでルールを一括編集できます。 (環境にデプロイする場合は、SID を有効な値に更新してください。)

perl -pe 'BEGIN{$A=100;} s/<REPLACE_SID>/$A++/ge' -i rules/*/*snort

次のコマンドは、テスト PCAP に対して特定のルール ファイルを実行します。

sudo snort -A console -k none -q -r ysoserial_java_rawbase64.pcap -c CommonsCollections1_3.snort

「-k none」オプションは、Snort にチェックサム モードを無効にするように指示します。これは、テスト データがソース/宛先として localhost を使用して生成され、それ以外の場合は Snort によって無視されるためです。 /etc/snort/snort.conf 設定ファイルで「config checksum_mode: all」を「none」に変更することで、これを設定することもできます。図 7 に示すように、Snort ルールは PCAP で一致します。

Snort ルールのテスト
図 7: Snort ルールのテスト

別のツール??

ルールを手動で検証することはできますが、それでは、多数のハンティングと検出のアイデアを迅速にプロトタイピングするという目標を達成することはできません。そのために、Snort および YARA ルールへのファイルまたはディレクトリ パスを受け入れ、指定されたデータ ファイルに対して実行する Python スクリプトであるCheckYoselfを作成しました。デフォルトでは、結果の TSV が画面に出力されますが、これをファイルに保存することもできます。

このコマンドは、生成されたすべての JavaObj ルールを JavaObj ペイロードと PCAP に対して実行します。

python3 utils/checkyoself.py -y rules/javaobj -s rules/javaobj -d payloads/javaobj pcaps/ -o java_all

–misses フラグを追加すると、結果がフィルタリングされ、一致するファイル (YARA の場合) またはルール (Snort の場合) のみが表示されます。

python3 utils/checkyoself.py -y rules/javaobj -s rules/javaobj -d payloads/javaobj pcaps/ -o java_all --misses

ほかに何か?

本日説明した調査プロセスとツールは出発点としては最適ですが、他の検出と同様に、注意すべき制限と機会の両方があります。

Snort ルールの微調整

私たちの Snort ルールの問題の 1 つは、現在の状態では、エクスプロイトの試みが成功したかどうかを知る方法がないことです。つまり、スキャンされたインターネットに面したシステムに対して多くのノイズの多いアラートを受け取る可能性があります。

これを説明するために、Snort フロービットを使用できます。 flowbits:set,heyserial; を追加する。 Snort ルールに、サーバーの応答を探す次のような別のルールをデプロイできます。この例では、301 (リダイレクト) または 404 (見つかりません) ステータス コードの HTTP 応答を除き、以前の HeySerial で生成されたルールからフロービットが設定された HTTP トラフィックを探しています。

alert tcp any any -> any any ( msg:"M.Methodology.HTTP.SerializedObject.[ServerResponse]"; content:"HTTP"; depth:4; content:!"301"; offset:9; depth:3; content:!"404"; offset:9; depth:3;  flowbits:isset,heyserial; threshold:type limit,track by_src,count 1,seconds 1800; sid: <REPLACE_SID>; rev:1; )

実稼働環境では、より忠実な結果を得るために追加のテストと調整が必要になります。エクスプロイトが成功したと見なす条件についてより厳密な条件が整ったら (または、レビューが必要なほど十分に近づいた場合)、ServerResponse ルールを監視するだけで済みます。

探索するチューニングの機会の例としては、次のようなものがあります。

  • 特定の HTTP ステータス コードを無視する
  • 既知のデフォルト ページ (会社のホームページなど) を除外する
  • 言語ごとに個別のフロービットを作成します。これにより、サーバーの応答が要求と一致することを確認できます。たとえば、IIS サーバーからの応答を伴う Java エクスプロイト チェーン リクエストは、エクスプロイトに成功する可能性は低いです。

暗号化

これまでのところ、暗号化されていないオブジェクトでこれらのルールをテストしましたが、暗号化が機能して有効性が低下する可能性がある 2 つのケースがあります。

まず、一部のオブジェクトは暗号化されている可能性があります。複数の広く悪用された CVE は、静的/デフォルトの暗号化キーを使用するか、ユーザーが暗号化キーをブルート フォースできるようにすることで、アプリケーションが .NET ViewState オブジェクトを暗号化した結果発生しました。攻撃者は、公開ツールを使用して、既知のキーを発見またはブルート フォースできる場合、ペイロードを暗号化できます。

次に、ネットワーク トラフィック自体が暗号化される可能性があります。ネットワーク アプライアンスがトラフィックを傍受して解読していない場合は、他の静的またはエンドポイントの検出に頼る必要があります。

チャンスは無限大!

HeySerial は現在、HTTP トラフィックのネットワーク ルールのみをサポートしていますが、影響を受けるプロトコルはこれだけではありません。これらのハンティング ルールを COM などの他のプロトコルに拡張することは、今後の研究にとって有益な領域になる可能性があります。

最後に、言語固有のフォーマッタの中には、Hex または Base64 ルールで検出できる文字列を残すものもありますが、カスタマイズされたエンコーダが必要になるものもあります。

CVE-2021-44228 に関する注意事項

2021 年 12 月 9 日、Java ログ ライブラリである log4j のゼロデイ エクスプロイトがリリースされました。これはJNDI コード インジェクションの例であり、必ずしもデシリアライゼーションではありませんが、このツールと説明した概念はここでも適用されます。 「${jndi:」の JNDI オブジェクト プレフィックスを追加することで、次の HeySerial コマンドを使用して、このタイプのコマンド インジェクションのハンティング ルールを生成できます。

python3 heyserial.py -t JNDIObj -e raw base64 -k dns:/ ldap:/ ldaps:/ rmi:/

これらのルールは、難読化されていない形式 ( ${jndi:ldap://<example>.com/a} )に従うすべてのオブジェクトを探します。ただし、この悪用の初期段階は簡単に難読化できるため、これらの攻撃の第 2 段階と悪用後の段階 (シリアル化された Java クラスのリモート読み込みなど) に検出を集中する方がより堅牢になる可能性があります。

ハンティング ルール、サンプル ペイロード、および難読化されていない POC のテスト PCAP は、テスト用に HeySerial リポジトリで提供されます。これらは本番/ブロッキング対応の検出ではないことに注意してください。

結論

このブログ投稿では、デシリアライゼーションの脆弱性を調査し、実際に悪用される検出のプロトタイプを迅速に作成するためのプロセスとツールを開発しました。このタイプのバグは何年も前から存在していますが、Mandiant は、APT41 のような高度なグループを含む攻撃者が、侵入に公開されたエクスプロイト「チェーン」を使用しているのを観察し続けています。

私たちのツールである HeySerial.py は、追加のオブジェクト タイプ、エンコーディング メソッド、およびルール形式をサポートするために拡張できる拡張可能なフレームワークになることを目的としています。詳細については、開発者ガイドをご覧ください。

Mandiant セキュリティ検証コンテンツ

Mandiant Security Validationには、HeySerial リポジトリで共有されるYSoSerial Java ペイロードのアクションが含まれています。詳細については、 Mandiant Advantageの VID A102-150 から A102-205 のアクションを参照してください。

謝辞

専門知識 (およびエクスプロイト) を共有してくれた James Hovious、レビューしてくれた Ashley Zaya、コード レビューしてくれた Gregory LeBlanc と William Ballenthin に特に感謝します。 Snort の第一人者である Evan Reese に特に感謝します。そうしないと、このブログ投稿にはYARAしか含まれない可能性があります。

以前の作業 / 追加リソース

ツール

脆弱性

トークと記事

参照: https://www.mandiant.com/resources/blog/hunting-deserialization-exploits

Comments

タイトルとURLをコピーしました