Snort + ELK: utilizzo di Kibana come console

Sebbene snort sia un'ottima soluzione ids trovo sia sempre stato carente dal punto di vista dell'interfaccia per visualizzare gli alert.

Per alcuni anni ho utilizzato snorby come console, un'interfaccia web basata su Ruby on Rails, ma che non sembra piu' molto mantenuta a livello di sviluppo.

Una possibile alternativa (anche se meno completa, secondo il sottoscritto) potrebbe essere l'integrazione di snort con uno stack ELK (ElasticSearch, Logstash e Kibana).

Escludendo l'utilizzo di tool di terze parti per parsare i log unified di snort e generare l'output in formato json e' possibile configurare logstash per leggere i file di log generati da barnyard.
Volendo registrare anche il payload dei pacchetti relativi agli eventi rilevati da snort, e' necessario utilizzare il plugin log_syslog_full di barynard specificando complete come operation mode:

output log_syslog_full: sensor_name snort-home, server 192.168.16.16, log_priority LOG_WARNING, log_facility LOG_LOCAL1, protocol udp, port 514, operation_mode complete

Di seguito, un esempio di evento in questo formato:

Aug 12 17:47:49 192.168.16.15 | [SNORHOST[LOG]: [snort-home] ] || 2016-08-12 17:47:48.896+002 2 [1:2022466:3] ET CURRENT_EVENTS Possible Keitaro TDS Redirect || bad-unknown || 6 46.28.68.3 192.168.16.101 4 20 0 409 58575 2 0 14248 0 || 80 58828 4294113776 1054781659 5 0 24 7504 18093 0 || 423 00000C07AC0100090F090013080045000199E4CF4000400637A82E1C44030A2
7A0A10050E5CCFFF2F9F03EDEB0DB50181D5046AD0000485454502F312E3120
333032204D6F7665642054656D706F726172696C790D0A5365727665723A206
E67696E782F312E31302E300D0A446174653A204672692C2031322041756720
323031362031353A34363A343020474D540D0A436F6E74656E742D547970653
A20746578742F68746D6C3B20636861727365743D7574662D380D0A436F6E74
656E742D4C656E6774683A20300D0A436F6E6E656374696F6E3A206B6565702
D616C6976650D0A582D506F77657265642D42793A205048502F352E342E3435
0D0A457870697265733A205468752C203231204A756C20313937372030373A3
3303A303020474D540D0A43616368652D436F6E74726F6C3A206D61782D6167
653D300D0A507261676D613A206E6F2D63616368650D0A4C6173742D4D6F646
9666965643A204672692C2031322041756720323031362031353A34363A3430
20474D540D0A4C4F434154494F4E3A20687474703A2F2F6164756C7477656263616D2E67612F7765620D0A0D0A ||

Per effettuare il parsing dei log scritti da barnyard modificare come segue il file di configurazione di logstash:

#Input,  log file written by barnyard
Input
{
file
                {
                path => "/var/log/messages"
                type=> "snort"
                }
}


Filter
{
if [type] == "snort"
                {
                #grok filters to identify snort events
                grok
                        {
                        break_on_match => true
                        match => {
                            "message" => [": \[%{GREEDYDATA:sensor}\] \] \|\| %{TIMESTAMP_ISO8601:tstamp} %{INT:PRIORITY} \[%{INT:GENID}:%{INT:SIGID}:%{INT:VER}\] %{GREEDYDATA:Signature} \|\| %{GREEDYDATA:LOGSOURCE              } \|\| %{INT:PROTO} %{IPV4:SRCIP} %{IPV4:DSTIP} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} \|\| %{INT:SRCPORT} %{INT:DSTPORT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} \|\| %{I              NT} %{GREEDYDATA:CAPTURE} \|\|",
                                ": \[%{GREEDYDATA:sensor}\] \] \|\| %{TIMESTAMP_ISO8601:tstamp} %{INT:PRIORITY} \[%{INT:GENID}:%{INT:SIGID}:%{INT:VER}\] %{GREEDYDATA:Signature} \|\| %{GREEDYDATA:LOGSOURCE} \|\|               %{INT:PROTO} %{IPV4:SRCIP} %{IPV4:DSTIP} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} %{INT} \|\| %{INT} %{GREEDYDATA:CAPTURE} \|\|"]
                                }
                        }

                #geoip source ip address for kibana maps
                geoip
                        {
                        database => "/usr/local/etc/logstash/GeoLiteCity.dat"
                        source => "SRCIP"
                        target => "geoip"
                        #add_tag => ["GeoIP"]
                        add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ]
                        add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}"  ]
                        }

                #geoip destination ip address for kibana maps
                geoip
                        {
                        database => "/usr/local/etc/logstash/GeoLiteCity.dat"
                        source => "DSTIP"
                        target => "geoip"
            add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ]
                        add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}"  ]
                        }

                mutate
                        {
                        convert => [ "[geoip][coordinates]", "float" ]
                        convert => [ "SRCPORT", "integer" ]
                        convert => [ "DSTPORT", "integer" ]
                        }

                #convert capture field from hex to ascii string
                ruby
                        {
                        code => "event['CAPTURE'] = [event['CAPTURE']].pack('H*')"
                        }

                }

Date
{
                match => [ "tstamp", "ISO8601" ]
                }
}

#send events to elasticsearch
Output
{
#only logs that matched snortís grok filter
if "_grokparsefailure" not in [tags]
                {
                elasticsearch { }
                }
}

Logstash cosi' configurato non riconosce ancora tutti i campi, ma quelli essenziali dovrebbero essere presenti.

Come si puo' notare dal file logstash.conf l'istanza di elasticsearch gira su localhost, ed e' stato mantenuto il nome di default per gli indici (logstash-%{+YYYY.MM.dd}"). Anche Kibana e' configurato in listening solamente su localhost, tramite la seguente direttiva nel file kybana.yml:

server.host: "127.0.0.1"

Essendo Kibana accessibile solo su localhost, e' necessario configurare un reverse proxy che forwardi le connessioni verso la porta 5601.
Nel caso si utilizzi apache, di seguito un estratto del file httpd.conf contenente la parte relativa alla configurazione come reverse proxy:

#Load mod_proxy modules
LoadModule proxy_module libexec/apache24/mod_proxy.so
LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so
#Don't pass the host header of the incoming request
ProxyPreserveHost off
#Prevent apache to work as forward proxy server!
ProxyRequests Off
#mapping for kibana instance
ProxyPass / http://127.0.0.1:5601/
#adjust url in http response headers sent from kibana
ProxyPassReverse / http://127.0.0.1:5601/

Una volta avviati snort, barynard, elasticsearch, logstash e kibana sara' possibile visualizzare gli eventi via browser puntando all'ip e porta sulla quale e' stato configurato in listening apache.

Questo e' un esempio degli eventi visualizzabili: https://drive.google.com/file/d/0B_K5uRb-eSH7bGtmTGxtVW5JWUE/view

All'interno di Kibana e' possibile personalizzare la propria dashboard per eseguire specifiche ricerche, e visualizzare grafici.
Di seguito gli export di una dashboard di esempio (qui uno screenshot: https://drive.google.com/file/d/0B_K5uRb-eSH7cU9ydWhUMUNYM0U/view) contenente una mappa per la geolocalizzazione degli eventi, un diagramma a torta con le signature piu' utilizzate, gli istogrammi relativi ai top source e destination ip e l'elenco degli eventi relativi ai grafici mostrati:

search.json: https://drive.google.com/file/d/0B_K5uRb-eSH7M0pBUVZ2NnNpVDA/view?usp=sharing

visualization.json: https://drive.google.com/file/d/0B_K5uRb-eSH7Tzh6U2RfZ1ZRcjg/view?usp=sharing

dashboard.json: https://drive.google.com/file/d/0B_K5uRb-eSH7Rm1XT2ZobUlITnc/view?usp=sharing

Privacy Policy