Premessa: questo è un post tecnico per chi gestisce un web server, quindi saltalo a piè pari se la roba troppo tecnica non ti interessa.
I CMS sono uno dei principali problemi di sicurezza del web. Sono centinaia i siti basati su WordPress, Joomla e altri CMS che vengono ogni giorno compromessi e utilizzati per diffondere malware.
Personalmente sto passando a Jekyll per siti che non hanno esigenze specifiche, Jekyll infatti funziona un po’ come un semplice CMS ma genera pagine statiche una-tantum. Dateci un occhio, è interessante, ma non è l’argomento di questo articolo.
Per chi è costretto ad usare un classico CMS con i suoi svariati ettogrammi di codice php che viene eseguito ad ogni richiesta, la prima cosa da fare è avere backup quotidiani. La seconda è mantenerlo sempre aggiornato. La terza è avere un sistema per accorgersi immediatamente di una eventuale compromissione. Oggi parliamo di questo.
Per compromissione intendiamo la seguente cosa: l’attaccante riesce, sfruttando una qualche vulnerabilità , a caricare del proprio codice php sul server per poi eseguirlo. Quello che farà questo codice non ci interessa, ci interessa accorgerci velocemente della cosa.
In linea generale quando si parla di sicurezza prediligo soluzioni semplici, anzi semplicissime. La più semplice soluzione possibile per gestire una problematica è quella giusta, ogni complessità aggiuntiva aggiunge superficie d’attacco e potenziali problemi quindi bisogna pesare accuratamente i vantaggi e gli svantaggi prima di decidere se adottarla.
La mia soluzione per la “early detection” di una eventuale compromissione è molto semplice (parliamo di sistemi Unix): cambiare l’owner dei file così che qualunque cosa viene scritta dal CMS abbia un owner diverso da quello da me impostato.
Mi spiego.
In una situazione “tipica” i permessi di un file sono questi:Â -rw-r–r– Â 1 www-data www-data
I file creati dal CMS, o da un hacker che lo ha compromesso, avranno lo stesso owner.
Cambiamo un po’ le cose, e facciamo diventare i permessi così: -rw-rw-r–  1 user  www-data
Nel primo caso l’owner è l’utente www-data e il gruppo www-data. Nel secondo caso l’owner è diverso. Cambiano anche i permessi associati al gruppo che diventano uguali a quelli che aveva l’owner.
Riassumendo, ambiamo cambiato l’owner da www-data (o qualunque altro utente associato al web server) ad un utente diverso (ad esempio il tuo) mantenendo il gruppo, e abbiamo dato al gruppo i permessi che aveva l’owner.
A questo punto se il CMS crea un nuovo file, questo file avrà un owner diverso e sarà facilmente identificabile da uno script che ogni ora “pattuglia” il sito alla ricerca di file che non dovrebbero essere stati scritti. Da questo “pattugliamento” sono da escludere, naturalmente, le cartelle dove il CMS ha tutto il diritto di scrivere file (come le cartelle della cache, dove il CMS può salvare dati ma da qui non può essere eseguito codice – già che ci sei verifica adesso di aver configurato il virtualhost per non eseguire codice in queste cartelle).
A questo punto puoi mettere un cron che controlla se nelle cartelle in cui il codice può essere eseguito, c’è qualcosa che non ha l’owner giusto e avvertirti.
A quel punto saprai cosa è stato scritto e quando e potrai recuperare il backup più recente o fare un confronto per vedere cosa è successo e rimettere ordine.
Naturalmente quando aggiorni il CMS o i plugin, i permessi cambieranno, stavolta legittimamente, quindi devi avere uno script per rimetterli a posto.
Qui c’è un abbozzo di script da usare come guida:
#!/bin/bash BASE="/home/utente/www/sito1 /home/utente/www/sito2" if [ $# -gt 0 ]; then BASE=$1 fi PATHS="." for B in $BASE; do echo echo "Checking site $B ..." for D in $PATHS; do sudo find $B/$D -type d -print0 | while IFS= read -r -d '' f;do if ! ls -ald "$f" | tr -s " " | grep "^.....w[sSx]... .*utente www-data " > /dev/null; then echo "Folder $f"; sudo chown utente.www-data "$f"; sudo chmod g+wx "$f"; fi done sudo find $B/$D -type f -print0 | while IFS= read -r -d '' f;do echo "$f" | grep -v "\(/wp-admin/includes/file.php\|wp-content/cache\)" >/dev/null && if ! ls -al "$f" | tr -s " " | grep "^.....w.... .*utente www-data " > /dev/null; then echo "File $f"; sudo chown utente.www-data "$f"; sudo chmod g+w "$f"; fi done done done
E qui un abbozzo di guida per lo script di monitoring:
#!/bin/bash BASE="/home/utente/www/sito1 /home/utente/www/sito2" PATHS="." chars=0; for B in $BASE; do find -L "$B/$D" -user www-data -print | grep -v "\(wp-content/cache\|/wp-admin/includes/file.php\|wp-content/uploads\|\/cache\/\)" done
Meglio prevenire che curare ma, se dovesse capitare comunque, grazie alla “early detection” e ai backup giornalieri potrai velocemente scoprire il fattaccio, capire cosa esattamente è stato fatto e ripristinare solo i file toccati.