はじめに¶
この記事では、アプリケーション内の信頼できないデータを安全に逆シリアル化するための明確で実用的なガイダンスを提供することに焦点を当てています。
デシリアライゼーションとは¶
シリアライゼーションとは、あるオブジェクトを後で復元できるデータ形式に変換するプロセスです。 人がserialize物のために保存します保存、送信しています。,
逆シリアル化は、そのプロセスの逆であり、何らかの形式から構造化されたデータを取り出し、それをオブジェクトに再構築します。 今日、データをシリアル化するための最も一般的なデータ形式はJSONです。 その前はXMLでした。
しかし、多くのプログラミング言語の提供、ネイティブ機能のための直列化さ。 これらのネイティブ形式は、通常、シリアル化プロセスのカスタマイズ性など、JSONやXMLよりも多くの機能を提供し
残念ながら、これらのネイティブ逆シリアル化メカニズムの機能は、信頼されていないデータに対して操作するときに悪意のある影響のために再, デシリアライザに対する攻撃は、サービス拒否、アクセス制御、およびリモートコード実行(RCE)攻撃を可能にすることがわかっています。
オブジェクトの安全な逆シリアライズに関するガイダンス¶
次の言語固有のガイダンスでは、信頼できないデータを逆シリアライズするための安全な方法論を列挙しようとしています。
PHP¶
ホワイトボックスレビュー¶
unserialize()関数の使用を確認し、外部パラメータがどのように受け入れられるかを確認します。, シリアル化されたデータをユーザーに渡す必要がある場合は、JSONなどの安全で標準的なデータ交換形式(json_decode()
およびjson_encode()
)を使用してください。
Python¶
BlackBox Review¶
トラフィックデータにシンボルドットが含まれている場合.
最後に、データがシリアル化されて送信された可能性が非常に高いです。
WhiteBoxレビュー¶
Pythonの次のAPIはシリアル化攻撃に対して脆弱になります。 以下のパターンのコードを検索します。,
- の使用
pickle/c_pickle/_pickle
とともにload/loads
:
import pickledata = """ cos.system(S'dir')tR. """pickle.loads(data)
- の使用
PyYAML
とともにload
:
import yamldocument = "!!python/object/apply:os.system "print(yaml.load(document))
-
jsonpickle
とencode
またはstore
メソッドを使用します。
Java¶
以下のテクニックはすべて、Javaの直列化可能な形式に対する逆シリアル化に対する攻撃を防止するのに適しています。,
実装アドバイス:
- コードで、
ObjectInputStream#resolveClass()
任意のクラスが逆シリアル化されないようにするメソッドをオーバーライドします。 この安全な動作はSerialKillerのようなライブラリにラップできます。ここで見られるように、一般的なreadObject()
メソッドの安全な置き換えを使用してください。 このアドレス”億笑”タイプの攻撃を確認入力の長さおよびオブジェクトを直列化復元.
WhiteBoxレビュー¶
シリアル化の脆弱性の可能性については、次のJava APIが使用されていることに注意してください。,
XMLdecoder
with external user defined parameters
XStream
with fromXML
method (xstream version <= v1.46 is vulnerable to the serialization issue)
ObjectInputStream
with readObject
4.,rnsは、データがJavaシリアル化ストリームで送信されたことを示唆している可能性があります
-
AC ED 00 05
In Hex -
rO0
In Base64 -
Content-type
HTTP応答のヘッダーapplication/x-java-serialized-object
データ漏洩と信頼できるフィールドのクロバリングを防ぐ¶
デシリアル化中にエンドユーザーによって制御されたり、シリアル化中にユーザーに公開されたりするべきではないオブジェクトのデータメンバーがある場合は、transient
キーワード(セクション機密情報の保護)として宣言する必要があります。,
Serializableとして定義されたクラスの場合、機密情報の変数はprivate transient
として宣言する必要があります。
たとえば、myAccountクラス、変数’profit’および’margin’は、直列化を避けるために一時的として宣言されました。
public class myAccount implements Serializable{ private transient double profit; // declared transient private transient double margin; // declared transient ....
ドメインオブジェクトの逆シリアル化を防ぐ¶
アプリケーションオブジェクトの一部は、階層によってSerializableを実装することを余儀なくされることがあります。, アプリケーションオブジェクトを逆シリアル化できないことを保証するには、readObject()
メソッドを宣言する必要があります(final
修飾子)。
独自のjava.io.ObjectInputStreamを強化します。
java.io.ObjectInputStream
クラスは、オブジェクトを逆シリアル化するために使用されます。 それをサブクラス化することで、その動作を強化することが可能です。, これは次の場合に最適なソリューションです。
- 逆シリアル化を行うコードを変更できます
- 逆シリアル化を期待するクラスを知っています
一般的な考え方は、ObjectInputStream.html#resolveClass()
どのクラスを逆シリアル化できるかを制限するために、オーバーライドすることです。
この呼び出しはreadObject()
が呼び出される前に発生するため、タイプが許可するものでない限り、逆シリアル化アクティビティは発生しません。,
ここに示す簡単な例では、LookAheadObjectInputStream
クラスはBicycle
クラス以外のタイプを逆シリアル化しないことが保証されています。
このアプローチのより完全な実装は、さまざまなコミュニティメンバーによって提案されています。
- NibbleSec-ホワイトリストとブラックリストを許可されているクラスのホワイトリストとブラックリストを許可されているライブラリ。
- NibbleSec-ホワイトリストとブラックリストを許可されているライブラリ。逆シリアル化された
- ibm-最も壊滅的な搾取シナリオが想定される数年前に書かれた独創的な保護。,
- Apache Commons IO classes
すべてのjava.io.ObjectInputStreamの使用をエージェントで強化します¶
前述のように、
java.io.ObjectInputStream
クラスはオブジェクトを逆シリアル化 それをサブクラス化することで、その動作を強化することが可能です。 ただし、コードを所有していない場合、またはパッチを待つことができない場合は、エージェントを使用してjava.io.ObjectInputStream
に強化することが最,グローバルに変更する
ObjectInputStream
既知の悪意のあるタイプをブラックリストに登録する場合にのみ安全です。 幸いなことに、今日、すべての既知の攻撃ベクトルから安全であるためにブラックリストに必要なクラスはごくわずかです。悪用される可能性のあるより多くの”ガジェット”クラスが発見されることは避けられません。 しかし、今日露出される脆弱なソフトウェアの信じられないほどの量があり、修正が必要です。, 場合によっては、この脆弱性を”修正”するには、開発者がシリアル化されたオブジェクトを受け入れないようになるにつれて、メッセージングシステム
これらのエージェントを有効にするには、新しいJVMパラメータを追加するだけです。
-javaagent:name-of-agent.jar
このアプローチを取るエージェントは、さまざまなコミュニティメンバーによってリリースされています。
- rO0By Contrast Security
同様ですが、スケーラブルではないアプローチは、JVMのObjectInputStreamに手動でパッチを適用してブートストラップすることです。 ご案内はこのアプローチが可能です。
。,Net CSharp¶
WhiteBox Review¶
ソースコードで次の用語を検索します。
TypeNameHandling
JavaScriptTypeResolver
タイプがユーザー制御変数によって設定されているシリアライザーを探します。,
BlackBoxレビュー
で始まるbase64エンコードされたコンテンツを検索します。
AAEAAAD/////
次のテキストでコンテンツを検索します。
TypeObject
$type:
一般的な注意事項¶
datastreamで、ストリームが逆シリアル化されるオブジェクトのタイプを定義できません。 可能であれば、たとえば
DataContractSerializer
またはXmlSerializer
を使用することで、これを防ぐことができます。,ここで、
JSON.Net
が使用されていることを確認してくださいTypeNameHandling
のみに設定されていますNone
。TypeNameHandling = TypeNameHandling.None
JavaScriptSerializer
を使用する場合は、JavaScriptTypeResolver
と一緒に使用しないでください。独自の型を定義するデータストリームを逆シリアル化する必要がある場合は、逆シリアル化が許可される型を制限します。 一つはそれにはリスクとして多くのネイティブの.純種類潜在的に危険が大きいです。 例えば,
System.IO.FileInfo
FileInfo
サーバー上の実際にファイルを参照するオブジェクトは、逆シリアル化すると、それらのファイルのプロパティを読み取り専用に変更し、潜在的なサービス拒否攻撃を引き起こす可能性があります。デシリアライズできる型を制限していても、一部の型には危険なプロパティがあることを覚えておいてください。 たとえば、
System.ComponentModel.DataAnnotations.ValidationException
タイプのプロパティValue
Object
があります。, このタイプが逆シリアル化に許可されたタイプの場合、攻撃者はValue
プロパティを選択した任意のオブジェクトタイプに設定できます。攻撃者は、インスタンス化されるタイプを操作することを防ぐ必要があります。 これが可能であれば、
DataContractSerializer
またはXmlSerializer
を破壊することもできます。// Action below is dangerous if the attacker can change the data in the databasevar typename = GetTransactionTypeFromDatabase();var serializer = new DataContractJsonSerializer(Type.GetType(typename));var obj = serializer.ReadObject(ms);
実行は、逆シリアル化中に特定の.Netタイプ内で発生する可能性があります。 以下に示すようなコントロールを作成することは無効です。,
var suspectObject = myBinaryFormatter.Deserialize(untrustedData);//Check below is too late! Execution may have already occurred.if (suspectObject is SomeDangerousObjectType){ //generate warnings and dispose of suspectObject}
BinaryFormatter
およびJSON.Net
カスタムSerializationBinder
を使用して、より安全な形式のホワイトリストコントロールを作成することができます。既知の.net安全でない逆シリアル化ガジェットを最新の状態に保ち、逆シリアル化プロセスによってそのような型が作成される可能性がある場 デシリアライザーは、認識している型のみをインスタンス化できます。
潜在的なガジェットを作成する可能性のあるコードは、インターネット接続を持つコードとは別にしてください。, 例として、WPFアプリケーションで使用される
System.Windows.Data.ObjectDataProvider
は、任意のメソッド呼び出しを可能にする既知のガジェットです。 信頼できないデータを逆シリアル化するRESTサービスプロジェクトで、このアセンブリへの参照をこれにするのは危険です。知られています。,NET RCE Gadgets¶
System.Configuration.Install.AssemblyInstaller
System.Activities.Presentation.WorkflowDesigner
System.Windows.ResourceDictionary
System.Windows.Data.ObjectDataProvider
System.Windows.Forms.BindingSource
Microsoft.Exchange.Management.SystemManager.WinForms.ExchangeSettingsProvider
System.Data.DataViewManager, System.Xml.XmlDocument/XmlDataDocument
System.Management.Automation.PSObject
Language-Agnostic Methods for Deserializing Safely¶
Using Alternative Data Formats¶
A great reduction of risk is achieved by avoiding native (de)serialization formats., JSONやXMLなどの純粋なデータ形式に切り替えることにより、カスタム逆シリアル化ロジックが悪意のある目的に再利用される可能性を減らします。
多くのアプリケーションは、明示的な目的のデータ転送のためにオブジェクトの別のドメインを作成することを含むデータ転送オブジェクトパター もちろ,
署名付きデータのみ逆シリアル化¶
アプリケーションが逆シリアル化の前にどのメッセージを処理する必要があるかを知っている場合、シリアル化プロセスの一部としてそれらに署名することができます。 アプリケーションは、認証された署名を持たないメッセージを逆シリアル化しないことを選択できます。,
緩和ツール/ライブラリ¶
- Java secure deserialization library
- SWAT(Serial Whitelist Application Trainer)
- NotSoSerial
検出ツール¶
- ペンテスターを対象としたJava deserialization cheat sheet
- 安全でないJavaオブジェクトの逆シリアル化を悪用するペイロードを生成するための概念実証ツールです。
- Javaデシリアライゼーションツールキット
- Javaデシリアライゼーションツール
- .,n
- JavaSerialKiller
- Javaデシリアル化スキャナ
- Burp-ysoserial
- SuperSerial
- SuperSerial-Active
References¶
- Java-Deserialization-Cheat-Sheet
- 信頼されていないデータの逆シリアル化
- Javaデシリアル化攻撃———————————————german owasp day2016
- appseccali2015-marshalling Pickles
- foxglove security-vulnerability announcement
- ペンテスターを対象としたjava Deserialization cheat sheet
- 安全でないjavaオブジェクトの逆シリアル化を悪用するペイロードを生成するための概念実証ツール。,
- Java De-serialization toolkits
- Java de-serialization tool
- Burp Suite extension
- Java secure deserialization library
- Serianalyzerは、逆シリアル化のための静的バイトコードアナライザです
- ペイロードジェネレータ
- Android Java Deserialization Vulnerability Tester
- Burp Suite Extension
- JavaSerialKiller
- javaデシリアル化スキャナ
- burp-ysoserial
- superserial
- Superserial-active
- .Net
- Alvaro muñoz:.,NETシリアライゼーション:脆弱なエンドポイントの検出と防御
- James Forshaw-Black Hat USA2012-あなたは私のタイプですか? シリアライゼーションによる.netサンドボックスの破壊
- Jonathan Birch BlueHat v17-危険なコンテンツ-.Net逆シリアル化の保護
- Alvaro Muñoz&Oleksandr Mirosh-Friday the13th:Attacking JSON-AppSecUSA2017