
Cose divertenti contro l'abuso della recente vulnerabilità CVE-2021-44228 (Log4Shell) utilizzando server web comuni.
Cose divertenti contro l'abuso della recente vulnerabilità CVE-2021-44228 (Log4Shell) utilizzando comuni server web.
Basandomi sul post di @shipilev (https://gist.github.com/shipilev/92e709a868f3d328b6636e1bfc21cf09) ho portato il suo esempio su Apache2. Un collega lo ha fatto per Lighttpd. Ho deciso di rendere pubblici i nostri esempi per comodità.
Ci sono solo poche ragioni per inserire la stringa "jndi:" negli header delle richieste, negli User Agent o altrove. Attualmente, conosco solo una ragione per farlo: lo sfruttamento di CVE-2021-44228. Mentre il mondo è, si spera, impegnato a correggere ogni implementazione delle versioni vulnerabili di Log4j, potrebbe essere ragionevole rallentare il più possibile gli attaccanti. Quindi, cosa ne dici di servirgli qualche gigabyte di sciocchezze mentre cercano di sfruttare i tuoi servizi?
I seguenti frammenti di codice non proteggono i tuoi dispositivi e servizi dalla vulnerabilità 0-Day Log4Shell! Aggiorna il software vulnerabile, usa log4j2.formatMsgNoLookups=true per disabilitare i jndi-Lookups o mettilo offline fino a quando non sarà disponibile una patch! Usa questo solo su server senza servizi che utilizzano Log4j! Maggiori informazioni su come mitigare CVE-2021-44228: https://research.hisolutions.com/log4shell
Questo non coprirà nemmeno chiamate offuscate come ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.} o tutto ciò che cerca di nascondere la parte "jndi:". Poiché non esiste una soluzione semplice per questo, non tratterò tecniche di rilevamento più avanzate al momento. Credo ancora che la maggior parte degli attacchi non le utilizzerà, quindi possiamo comunque infastidire la maggior parte degli script kiddies. :)
Su Linux, crea un file con un messaggio HTML casuale. Per favore non usare il LOL dell'esempio seguente poiché rende più facile per l'attaccante implementare un filtro generico per eluderci. Stiamo usando l'utility pv per mostrare l'avanzamento della creazione del file, potresti doverla installare tramite il tuo gestore pacchetti preferito o semplicemente ometterla.
$ awk 'BEGIN { for(c=0;c<10000000;c++) printf "<p>LOL</p>" }' > 100M.html
$ (for I in `seq 1 100`; do cat 100M.html; done) | pv | gzip -9 > 10G.boomgz
$ rm 100M.html
Supponendo che il tuo server web funzioni come www-data, creiamo una directory di proprietà di www-data in modo da non dover caricare una copia in ogni webroot che il server web potrebbe servire:
mkdir /bombs
mv 10G.boomgz /bombs
chown -R www-data:www-data /bombs
Ora arriva la parte divertente...
Vedi https://gist.github.com/shipilev/92e709a868f3d328b6636e1bfc21cf09
Tutti i crediti vanno a @shipilev
Abilita i moduli richiesti
a2enmod rewrite headers ratelimit
Naviga fino a /etc/apache2/sites-enabled. Apri ogni file di configurazione degli host con il tuo editor preferito e inserisci il seguente frammento di codice appena sopra ogni riga contenente (potrebbe essercene più di una):
RewriteEngine On
RewriteCond %{THE_REQUEST} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{QUERY_STRING} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{REQUEST_URI} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_COOKIE} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_HOST} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{REMOTE_HOST} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{REMOTE_USER} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_USER_AGENT} "^.*(\${jndi|\${\${).*$" [OR]
RewriteCond %{HTTP_REFERER} "^.*(\${jndi|\${\${).*$"
RewriteRule . /bombs/10G_lol.boomgz [L]
<Files ~ "\.boomgz$">
Header Set Expires "Sat, 1 Jan 2000 00:00:00 GMT"
Header Set Content-Encoding "gzip"
Header Set Content-Type "text/html"
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 100
</Files>
<Directory /bombs>
allow from allow
Require all granted
</Directory>
Potresti chiederti perché ci sono molte più variabili rispetto all'esempio iniziale di @shipilev. Ho deciso di cercare di intercettare quante più posizioni possibili. Questo potrebbe interrompere i servizi in alcuni casi molto rari, quindi se vuoi usare il set originale di controlli, commenta o elimina le prime 7 righe dopo l'istruzione RewriteEngine On e rimuovi le parti |\${\${ dalle righe rimanenti.
Puoi anche inserire il codice in un nuovo file, ad esempio /etc/apache2/conf-available/anti-jndi.conf e includerlo in questo modo:
Include /etc/apache2/conf-available/anti-jndi.conf
Ora salva i file e ricarica la configurazione di Apache2:
systemctl reload apache2
Se tutto è andato bene, non dovresti ricevere un messaggio di errore.
Prossimamente
Puoi verificare se hai avuto successo connettendoti al tuo sito web modificato tramite curl (ricorda di sostituire your-hostname con il nome host reale di uno dei servizi che hai appena modificato:
curl -s -L your-hostname -A "\${jndi:testing}" | pv > /dev/null
Dovresti vedere una barra di avanzamento, che mostra una velocità di download di circa 100kb/s. Se non la annulli, dovrebbe terminare dopo alcuni minuti, a seconda di cosa hai usato come stringa nel file HTML iniziale. Per me, ci sono voluti circa 5 minuti. Ora controlla cosa succede lato client:
curl -s --compressed -L your-hostname -A "\${jndi:testing}" | pv > /dev/null
Vedi come non è più 100kb/s? La compressione fa la sua magia, sono alcuni gigabyte lato client. Quindi, dopo aver scaricato un mucchio di sciocchezze per alcuni minuti, l'attaccante ha alcuni gigabyte sparsi in giro, supponendo che i dati siano conservati per l'analisi. Chi lo sa? :)