Giter Site home page Giter Site logo

frosty's Introduction

frosty

Automated use of an IDS and open source intel

The intention of this project is to automate the use of the IDS (Intrusion Detection System) Suricata by generating emails for alerts that identify potential indicators of compromise in local network traffic.

Setup

Suricata

Debian (Buster)

apt-get install suricata suricata-oinkmaster

# modify /etc/suricata/suricata.yaml 
# the defaults are sufficient but the af-packet.interface must be set correctly
# refer to setup/debian-buster/suricata.yaml.orig and suricata.yaml files for recommended changes
(cd /etc/suricata; cp suricata.yaml suricata.yaml.orig; vi suricata.yaml)
systemctl restart suricata

# the default /etc/suricata/suricata-oinkmaster.conf is sufficient
# however can use an oinkcode for with emerging threats pro: 
(cd /etc/suricata; mv suricata-oinkmaster.conf suricata-oinkmaster.conf.orig; \
    awk '/^url/ {
             print "#"$0;
             print "url = https://rules.emergingthreatspro.com/<oinkcode>/suricata-4.0/etpro.rules.tar.gz";
             next
         }
         { print $0 }
    ' <suricata-oinkmaster.conf.orig >suricata-oinkmaster.conf)
    
# can also optionally specify rules to be ignored:
# refer to /etc/oinkmaster.conf
# to specify files to ignore, add "skipfile <file>"
# to specify rules to ignore, add "disablesid <sid>"

# update emerging threats ruleset (this will be run in a daily cron)
suricata-oinkmaster-updater

MTA (Mail Transfer Agent)

An MTA should be installed by default. Verify mail can be sent using it to a local mail spool:

>>> import smtplib
>>> smtp = smtplib.SMTP('127.0.0.1')
>>> smtp.set_debuglevel(True)
>>> smtp.sendmail('frosty@localhost', 'root@localhost', 'this is a test')
send: 'ehlo [127.0.1.1]\r\n'
reply: b'250-localhost Hello localhost [127.0.0.1]\r\n'
reply: b'250-SIZE 52428800\r\n'
reply: b'250-8BITMIME\r\n'
reply: b'250-PIPELINING\r\n'
reply: b'250-CHUNKING\r\n'
reply: b'250-PRDR\r\n'
reply: b'250 HELP\r\n'
reply: retcode (250); Msg: b'localhost Hello localhost [127.0.0.1]\nSIZE 52428800\n8BITMIME\nPIPELINING\nCHUNKING\nPRDR\nHELP'
send: 'mail FROM:<frosty@localhost> size=14\r\n'
reply: b'250 OK\r\n'
reply: retcode (250); Msg: b'OK'
send: 'rcpt TO:<root@localhost>\r\n'
reply: b'250 Accepted\r\n'
reply: retcode (250); Msg: b'Accepted'
send: 'data\r\n'
reply: b'354 Enter message, ending with "." on a line by itself\r\n'
reply: retcode (354); Msg: b'Enter message, ending with "." on a line by itself'
data: (354, b'Enter message, ending with "." on a line by itself')
send: b'this is a test\r\n.\r\n'
reply: b'250 OK id=1lDM0U-0002wM-1W\r\n'
reply: retcode (250); Msg: b'OK id=1lDM0U-0002wM-1W'
data: (250, b'OK id=1lDM0U-0002wM-1W')
{}

Systemd

# refer to systemd.unit(5) systemd.service(5) systemd.exec(5) ...
cat <<EOF >/etc/systemd/system/frosty.service
[Unit]
Description=frosty
After=suricata.service
Documentation=https://github.com/jo-makar/frosty

[Service]
Type=simple
ExecStart=</path/to/frosty.py> <args>
Restart=on-failure
User=<user> # does not need to be root
WorkingDirectory=</parent/path/of/frosty.py>

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start frosty
systemctl enable frosty

ELK (Elasticsearch, Logstash, Kibana) stack

This is optional but recommended as it provides context when investigating alerts.

Debian

# refer to https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html 

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" >/etc/apt/sources.list.d/elastic-7.x.list
apt-get update && apt-get install elasticsearch logstash kibana

# ensure only 2gb of heap is used
cat <<EOF >/etc/elasticsearch/jvm.options.d/heap.options
-Xms2g
-Xmx2g
EOF

systemctl daemon-reload
systemctl start elasticsearch 
systemctl enable elasticsearch

systemctl start kibana
systemctl enable kibana

# define the config before starting
# refer to https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html
#          https://www.elastic.co/guide/en/logstash/current/plugins-outputs-tcp.html
#          https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html

cat <<EOF >/etc/logstash/config.d/100-frosty.conf
input {
  file {
    path => ["/var/log/suricata/eve.json"]
    codec => "json"
    mode => "tail"
    start_position => "end"
    add_field => { "[@metadata][pipeline]" => "frosty" }
  }
}

output {
  if [@metadata][pipeline] == "frosty" {
    elasticsearch {
      action => "index"
      hosts => ["http://127.0.0.1:9200"]
      index => "suricata-%{+yyyyMMdd}"
      # TODO define a template and specify it here
    }
    
    if [event_type] == "alert" {
      tcp {
        host => "127.0.0.1"
        port => 7834 # arbitrary choice
        mode => "client"
        codec => "json_lines"
      }
    }
  }
}
EOF

# modify /etc/systemd/system/logstash.service 
# change TimeoutStopSec=infinity to something like 300
(cd /etc/systemd/system; cp logstash.service logstash.service.orig; vi logstash.service)

systemctl daemon-reload
systemctl start logstash
systemctl enable logstash

Options

$ ./frosty.py -h
usage: frosty.py [-h] [--debug] (--minimal | --elastic)

optional arguments:
  -h, --help            show this help message and exit
  --debug, -d
  --minimal, --min, -m
  --elastic, --elk, -e

Minimal or elastic mode must be specified. Minimal mode monitors the eve.json output and sends mails to root as alerts are generated. Elastic mode receives alert records from logstash and generates mails with the associated alert in Kibana.

Try it out!

Minimal mode

# grep ^alert /etc/suricata/rules/tor.rules | head -1
alert tcp [101.99.95.201,103.228.53.155,103.234.220.195,103.236.201.88,103.249.28.195,103.253.41.98,103.28.52.93,103.35.74.74,103.75.190.11,104.149.134.118] any -> $HOME_NET any (msg:"ET TOR Known Tor Exit Node Traffic group 1"; reference:url,doc.emergingthreats.net/bin/view/Main/TorRules; threshold: type limit, track by_src, seconds 60, count 1; classtype:misc-attack; flowbits:set,ET.TorIP; sid:2520000; rev:4346; metadata:affected_product Any, attack_target Any, deployment Perimeter, tag TOR, signature_severity Audit, created_at 2008_12_01, updated_at 2021_02_19;)
# nc -w1 -v 101.99.95.201 9001
Connection to 101.99.95.201 9001 port [tcp/*] succeeded!

notification mails are sent in batches every five minutes
after no more than five minutes expect the corresponding mail:

$ mail
"/var/mail/jom": 1 message 1 new
>N   1 frosty@localhost   Sat Feb 20 21:26 123/3095  suricata alerts
? 1
Return-path: <frosty@localhost>
Envelope-to: root@localhost
Delivery-date: Sat, 20 Feb 2021 21:26:02 -0500
Received: from localhost ([127.0.0.1] helo=[127.0.1.1])
        by localhost with esmtp (Exim 4.92)
        (envelope-from <frosty@localhost>)
        id 1lDeRd-0002s4-TZ
        for root@localhost; Sat, 20 Feb 2021 21:26:01 -0500
Subject: suricata alerts
From: frosty@localhost
Message-Id: <E1lDeRd-0002s4-TZ@localhost>
Date: Sat, 20 Feb 2021 21:26:01 -0500

{
    "timestamp": "2021-02-20T21:21:06.695534-0500",
    "flow_id": 1700754495777475,
    "in_iface": "wlp1s0",
    "event_type": "alert",
    "src_ip": "101.99.95.201",
    "src_port": 9001,
    "dest_ip": "192.168.1.65",
    "dest_port": 45548,
    "proto": "TCP",
    "metadata": {
        "flowbits": [
            "ET.TorIP"
        ]
    },
    "alert": {
        "action": "allowed",
        "gid": 1,
        "signature_id": 2520000,
        "rev": 4346,
        "signature": "ET TOR Known Tor Exit Node Traffic group 1",
        "category": "Misc Attack",
        "severity": 2,
        "metadata": {
            "updated_at": [
                "2021_02_19"
            ],
            "created_at": [
                "2008_12_01"
            ],
            "signature_severity": [
                "Audit"
            ],
            "tag": [
                "TOR"
            ],
            "deployment": [
                "Perimeter"
            ],
            "attack_target": [
                "Any"
            ],
            "affected_product": [
                "Any"
            ]
        }
    },
    "flow": {
        "pkts_toserver": 1,
        "pkts_toclient": 1,
        "bytes_toserver": 74,
        "bytes_toclient": 74,
        "start": "2021-02-20T21:21:06.273091-0500"
    }
}
{
    "timestamp": "2021-02-20T21:21:06.695534-0500",
    "flow_id": 1700754495777475,
    "in_iface": "wlp1s0",
    "event_type": "alert",
    "src_ip": "101.99.95.201",
    "src_port": 9001,
    "dest_ip": "192.168.1.65",
    "dest_port": 45548,
    "proto": "TCP",
    "metadata": {
        "flowbits": [
            "ET.TorIP"
        ]
    },
    "flow": {
        "pkts_toserver": 1,
        "pkts_toclient": 1,
        "bytes_toserver": 74,
        "bytes_toclient": 74,
        "start": "2021-02-20T21:21:06.273091-0500"
    },
    "alert": {
        "action": "allowed",
        "gid": 1,
        "signature_id": 2522000,
        "rev": 4346,
        "signature": "ET TOR Known Tor Relay/Router (Not Exit) Node Traffic group 1",
        "category": "Misc Attack",
        "severity": 2,
        "metadata": {
            "updated_at": [
                "2021_02_19"
            ],
            "created_at": [
                "2008_12_01"
            ],
            "signature_severity": [
                "Audit"
            ],
            "tag": [
                "TOR"
            ],
            "deployment": [
                "Perimeter"
            ],
            "attack_target": [
                "Any"
            ],
            "affected_product": [
                "Any"
            ]
        }
    }
}

Elastic mode

# grep ^alert /etc/suricata/rules/tor.rules | head -1
alert tcp [101.99.95.201,103.228.53.155,103.234.220.195,103.236.201.88,103.249.28.195,103.253.41.98,103.28.52.93,103.35.74.74,103.75.190.11,104.149.134.118] any -> $HOME_NET any (msg:"ET TOR Known Tor Exit Node Traffic group 1"; reference:url,doc.emergingthreats.net/bin/view/Main/TorRules; threshold: type limit, track by_src, seconds 60, count 1; classtype:misc-attack; flowbits:set,ET.TorIP; sid:2520000; rev:4346; metadata:affected_product Any, attack_target Any, deployment Perimeter, tag TOR, signature_severity Audit, created_at 2008_12_01, updated_at 2021_02_19;)
# nc -w1 -v 101.99.95.201 9001
Connection to 101.99.95.201 9001 port [tcp/*] succeeded!

notification mails are sent in batches every five minutes
after no more than five minutes expect the corresponding mail:

$ mail
"/var/mail/jom": 1 message 1 new
>N   1 frosty@localhost   Sun Feb 21 19:43 19/1351  suricata alerts
? 1
Return-path: <frosty@localhost>
Envelope-to: root@localhost
Delivery-date: Sun, 21 Feb 2021 19:43:27 -0500
Received: from localhost ([127.0.0.1] helo=[127.0.1.1])
        by localhost with esmtp (Exim 4.92)
        (envelope-from <frosty@localhost>)
        id 1lDzJv-00031B-8j
        for root@localhost; Sun, 21 Feb 2021 19:43:27 -0500
Subject: suricata alerts
From: frosty@localhost
Message-Id: <E1lDzJv-00031B-8j@localhost>
Date: Sun, 21 Feb 2021 19:43:27 -0500

ET TOR Known Tor Exit Node Traffic group 1
http://127.0.0.1:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:'2021-02-21T18:38:30.792578-05:00',to:'2021-02-21T20:38:31.082985-05:00'))&_a=(columns:!(event_type,src_ip,src_port,dest_ip,dest_port,proto,app_proto),filters:!(),index:'0170a7e0-7409-11eb-9879-6bf568a6cc4d',interval:auto,sort:!(),query:(language:kuery,query:'flow_id:1700072559876098'))

ET TOR Known Tor Relay/Router (Not Exit) Node Traffic group 1
http://127.0.0.1:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:'2021-02-21T18:38:30.792578-05:00',to:'2021-02-21T20:38:31.082985-05:00'))&_a=(columns:!(event_type,src_ip,src_port,dest_ip,dest_port,proto,app_proto),filters:!(),index:'0170a7e0-7409-11eb-9879-6bf568a6cc4d',interval:auto,sort:!(),query:(language:kuery,query:'flow_id:1700072559876098'))

The generated Kibana links show the records associated with the alerts:

kibana

Elastic mode crons

TODO

  • Weekly report of unusual traffic (unusual ports to start)
  • Weekly report summarizing alerts
  • Weekly report to identify Suricata performance issues (via stats records, eg kernel_drops)
  • Weekly report showing local network topology

frosty's People

Contributors

jo-makar avatar

Watchers

 avatar  avatar

Forkers

fluxcap1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.