Indice
Vulnerabilità Elementor Pro 3.11.6
Elementor Pro, il popolare page builder per WordPress, ha rilasciato un aggiornamento per coprire una grave vulnerabilità di sicurezza che affligge le versioni inferiori o uguali alla 3.11.6. che permette di compromettere un intero sito WP.
In sintesi questa vulnerabilità permette a qualunque malintenzionato di creare un account admin facendo escalation dei privilegi e permettendogli di modificare qualsiasi cosa all’interno del sito. Questo si converte il più delle volte in direct verso siti malevoli e modifica dei dati dell’account admin principale per bloccarlo.
Tutti i servizi di VHosting (Cloud Hosting, Cloud VPS, Server dedicati) hanno già implementati i workaround descritti nel seguente articolo tramite la tecnologia proprietaria “WP Security” ed il sistema di firewall centralizzato.
E’ necessario aggiornare il plugin in oggetto per sanare definitivamente la vulnerabilità.
La vulnerabilità ha il seguente punteggio: 8.8 (High)
Il problema si presenta quando sul sito sono installati e attivi Elementor PRO (la versione FREE non è affetta dal problema) e WooCommerce. La vulnerabilità sfrutta il modulo elementor-pro/modules/woocommerce/module.php che aggiunge ed attiva 2 azioni AJAX
/** * Register Ajax Actions. * * Registers ajax action used by the Editor js. * * @since 3.5.0 * * @param Ajax $ajax */ public function register_ajax_actions( Ajax $ajax ) { // `woocommerce_update_page_option` is called in the editor save-show-modal.js. $ajax->register_ajax_action( 'pro_woocommerce_update_page_option', [ $this, 'update_page_option' ] ); $ajax->register_ajax_action( 'pro_woocommerce_mock_notices', [ $this, 'woocommerce_mock_notices' ] ); }
Una di queste è pro_woocommerce_update_page_option che utilizza l’editor del builder di Elementor. Questo richiama la funzione update_option che modifica due opzioni nel database di WordPress con due inserimenti come se fossero inviati da un utente. Per la precisione questo:
/** * Update Page Option. * * Ajax action can be used to update any WooCommerce option. * * @since 3.5.0 * * @param array $data */ public function update_page_option( $data ) { update_option( $data['option_name'], $data['editor_post_id'] ); }
Con questa funzione, l’amministratore dello shop, effettua l’aggiornamento di opzioni specifiche di WooCommerce ma l’input utente non viene convalidato e la funzione, non disponendo di un check per verificare i privilegi dell’utente, viene bypassato. Elementor, per bypassare il problema, sfrutta il proprio gestore AJAX tramite le sue 2 funzioni pro_woocommerce_update_page_option e elementor_ajax . Il gestore viene richiamato dal file elementor/core/common/modules/ajax/module.php che appartiene ad Elementor (versione FREE) ma necessario per l’esecuzione di Elementor PRO. Il gestore (o handler) è il seguente:
/** * Handle ajax request. * * Verify ajax nonce, and run all the registered actions for this request. * * Fired by `wp_ajax_elementor_ajax` action. * * @since 2.0.0 * @access public */ public function handle_ajax_request() { if ( ! $this->verify_request_nonce() ) { $this->add_response_data( false, esc_html__( 'Token Expired.', 'elementor' ) ) ->send_error( Exceptions::UNAUTHORIZED ); } ...
Come si può vedere viene fatto un check per prevenire azioni errate o exploit tuttavia una volta che tutto il codice JS è caricato tramite l’admin_enqueue_scripts nel file elementor/core/common/app.php
add_action( 'admin_enqueue_scripts', [ $this, 'register_scripts' ] );
viene bypassato tutto. Ad esempio scrivendo in console (tramite la console del browser) questo
alert( elementorCommon.ajax.getSettings("nonce") );
viene eseguito del codice come si può visionare dal seguente esempio:
Quindi chiunque voglia può creare un utente amministratore abilitando sia la registrazione tramite users_can_register che aumentando il livello ad amministratore tramite il default_role cambiando anche la mail dell’admin tramite la nella tabella admin_email. Con queste modifiche si può fare un redirect tutto il traffico verso siti esterni malevoli modificando il siteurl tra le varie opzioni.
Ecco il risultato dell’injection causata dal builder
MariaDB [example]> SELECT * FROM `wp_options` WHERE `option_name`='siteurl'; +-----------+-------------+------------------+----------+ | option_id | option_name | option_value | autoload | +-----------+-------------+------------------+----------+ | 1 | siteurl | https://XXXX.com | yes | +-----------+-------------+------------------+----------+ 1 row in set (0.001 sec)
Questa vulnerabilità si presenta perchè sfrutta la possibilità di WooCommerce di creare account clienti senza farli autenticare.
Identificare un tentativo di attacco
Un tentativo di attacco si presenta in questo modo (nell’esempio è stato bloccato dai nostri sistemi):
193.169.194.63 - - [30/Mar/2023:14:40:48 +0200] "GET / HTTP/2" 403 1229 "http://www.hidden.it" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:49 +0200] "POST //wp-admin/admin-post.php HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:49 +0200] "GET //wp-content/plugins/elementor-pro/changelog.txt HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:49 +0200] "GET / HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:49 +0200] "GET //wp-login.php?action=register HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:49 +0200] "GET //my-account HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:49 +0200] "GET //register HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:50 +0200] "GET //registration HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:50 +0200] "GET //wp-signup.php HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:50 +0200] "GET //signup HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:50 +0200] "GET / HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:50 +0200] "POST / HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:50 +0200] "POST //my-account/?action=register HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:51 +0200] "POST //my-account HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:51 +0200] "POST //account HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:51 +0200] "POST //wp-login.php?action=register HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:51 +0200] "POST //wp-login.php?action=register HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:51 +0200] "POST / HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:51 +0200] "POST //shop HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:52 +0200] "POST //?post_type=product HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" 193.169.194.63 - - [30/Mar/2023:14:40:52 +0200] "GET //wp-json/wc/store/products HTTP/2" 403 1229 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
Se si dovesse notare una comportamento uguale o simile, è buona prassi verificare che il proprio sito sia correttamente aggiornato.
E’ possibile effettuare rapide ricerche all’interno dei log dei server, tramite i seguenti comandi BASH (Terminale SSH):
cPanel
grep -i "elementor-pro/changelog.txt" /var/log/apache2/domlogs/*-ssl_log
grep -E "193.169.(194|195)." /var/log/apache2/domlogs/*-ssl_log grep "45.135.1." /var/log/apache2/domlogs/*-ssl_log
Plesk
grep -i "elementor-pro/changelog.txt" /var/www/vhosts/*/logs/*_log
grep -E "193.169.(194|195)." /var/www/vhosts/*/logs/*_log grep "45.135.1." /var/www/vhosts/*/logs/*_log
Statistiche
Da alcune indagini interne, i siti potenzialmente affetti dal problema (Elementor Pro non aggiornato) sono 1 su 5.
E’ possibile analizzare rapidamente i siti affetti dal problema tramite il seguente script BASH (Terminale SSH):
#!/bin/bash for T_SITE in $(locate elementor-pro | grep -e 'wp-content/plugins/elementor-pro$'); do if [[ ! $(grep '3.11.7' $T_SITE/changelog.txt) ]]; then echo "Sito potenzialmente vulnerabile"; head -3 $T_SITE/changelog.txt | tail -1; else echo "Sito con Elementor Pro aggiornato"; head -3 $T_SITE/changelog.txt | tail -1; fi done
Soluzioni e Workaround
L’aggiornamento di Elementor Pro è l’unica soluzione disponibile per risolvere la vulnerabilià.
Tuttavia, per chi non fosse in grado di eseguire l’azione correttiva nell’immediato, è possibile bloccare alcuni indirizzi IP tramite htaccess, in particolare le seguenti classi IP:
193.169.194.0/23 45.135.1.0/24
Successivamente è possibile bloccare il file changelog.txt con la finalità di mascherare la presenza del plugin.
La seguente porzione di codice è valida per web server Apache o LiteSpeed:
RewriteRule /wp-content/plugins/elementor-pro/changelog.txt - [L,R=404]
Mentre la seguente è valida per web server Nginx:
location = /wp-content/plugins/elementor-pro/changelog.txt { return 404; }
Riferimenti
– https://www.facebook.com/groups/wpitalia/posts/5932266600195612/
– https://blog.nintechnet.com/high-severity-vulnerability-fixed-in-wordpress-elementor-pro-plugin/
– https://stackoverflow.com/questions/75886751/my-wordpress-site-got-hacked-i-think-its-redirecting-when-i-open-the-site/75886850