1

Javaでは、ネットワーク上で(暗号化なしで)オブジェクトを送受信するために、次の操作を行うことができます。Man In The Middle攻撃を介してネットワーク経由で送信されるJavaオブジェクトにコードを挿入することは可能ですか?

class Dog { 
    public void bark(){ System.out.println("Woof! Woof!"); } 
} 

Client.java

Dog fido = new Dog(); 
Socket socket = new Socket(new InetSocketAddress("192.168.1.2"), 1234); 
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
oos.writeObject(fido); 
oos.flush(); 
oos.close(); 

Server.java

ServerSocket server = new ServerSocket(1234); 
Socket client = server.accept(); 
ObjectInputStream ois = new ObjectInputStream(client.getInputStream()); 
Dog fido = (Dog)ois.readObject(); 
ois.close(); 

fido.bark(); 

私の質問は、あなたが送信している2つのネットワークデバイス間の遮断点を正常に確立したとしJavaオブジェクトが保護されていないリンク上を行き来していて、そのprotocを知っている彼らのデータを変更することができます、Javaバイトコードをオブジェクトに注入して、その動作を変更することは可能ですか?

私たちの小さな例では、fido「ムー!の代わりに吠えますか?

+1

Java *コードではなく*データ*を送信していますので、 – Andreas

+1

オブジェクトのシリアル化では、値とその値を挿入するクラスのみが記録されることに注意してください。バイトコードはありません。これは、クライアントとサーバーの両方に既に存在している必要があります。したがって、デシリアライズされるクラス(別のもの)とそのデータを変更することができます。 –

+1

しかし、リサーチでは、デシリアライズ時にリモートコードが実行されるオブジェクトグラフを作成する方法が見つかりました。https:// foxglovesecuritycom/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-in-common-this-vulnerability/ –

答えて

1

Javaでオブジェクトをシリアル化すると、このオブジェクトのフィールドのみがシリアル化されます。クライアントとサーバー上のバイトコードは等しい(または少なくとも互換性があります)必要があります。これはserialVersionUIDによって強制されます。

各シリアライズクラスでシリアライズランタイム関連付けバージョン番号は、シリアル化されたオブジェクトの送信者と受信者がに関して互換性のあるそのオブジェクトのクラスをロードしたことを確認するために、逆シリアル化の間に使用されるのserialVersionUIDと呼ばシリアライゼーション。

これを考慮すると、フィールドの値を変更すると、動作を変更できます。 Dogのこの実装を考えると、要求を傍受してサウンドの値を"Moo!"に変更することができます。

public class Dog { 
    private String sound = "Woof! Woof!"; 
    public void bark(){ System.out.println(sound); } 
} 

しかし、あなたのオリジナルの実装で"Woof! Woof!"は、コンパイル時定数であるので、実行時にそれを変更することはできませんので、それは、シリアライズされません。

+0

ありがとうございました。これは、Javaがストリーム間でオブジェクトをシリアル化する方法を理解するのに役立ちました。 – TheRealChx101

+0

@ TheRealChx101よろしくお願いします! – SilverNak

0

あなたのデータストリームが信頼できない/危険にさらされている場合、使用しているシリアライゼーションフレームワークの脆弱性によりJavaコードが実行され、悪意のあるものが実行される可能性があります。

Apache Common Collectionには、このような脆弱性はほとんどありませんでした。非常に簡単に言えば、クラスは予期された名前の代わりにデータストリーム内の名前に基づいてインスタンス化されました。 This would result in an arbitrary class getting instantiated

Java deserialization FAQを見て、確実に動作する方法を理解してください。

関連する問題