Exemplo n.º 1
0
def create_rule_blackhole(flow):
    dst_ip = flow.get('dst_ip') + '/32'
    dst_subnet = get_subnet(flow.get('dst_ip'))
    rule = []
    rule.extend(('route', dst_ip))
    rule.extend(('next-hop', config.get('BLACKHOLE_NEXTHOP')))
    rule.extend(('community', config.get('BLACKHOLE_COMMUNITY')))
    blackhole_rule = ' '.join(rule)
    logger.debug("Generate rule '%s'", blackhole_rule)
    return blackhole_rule
Exemplo n.º 2
0
def create_rule_flow(flow, attack_type):
    dst_ip = flow.get('dst_ip') + '/32'
    dst_subnet = get_subnet(flow.get('dst_ip'))
    rule = []
    rule.extend(('flow', 'route', 'destination', dst_subnet))
    if (attack_type == GRE_FLOOD):
        rule.extend(('protocol', '[ gre ]'))
    elif (attack_type == UDP_FLOOD):
        rule.extend(('protocol', '[ udp ]'))
        rule.extend(('source-port',
                     '[ =' + str(flow.get('src_ports').keys()[0]) + ' ]'))
    elif (attack_type == DNS_FLOOD):
        rule.extend(('protocol', '[ udp ]'))
        rule.extend(('source-port',
                     '[ =' + str(flow.get('src_ports').keys()[0]) + ' ]'))
        rule.extend(('packet-length', '[ >900 ]'))
    elif (attack_type == TCP_SYN_FLOOD):
        rule.extend(('protocol', '[ tcp ]'))
        rule.extend(('destination-port',
                     '[ =' + str(flow.get('dst_ports').keys()[0]) + ' ]'))
        rule.extend(('tcp-flags', '[ syn ]'))
    else:
        return ''
    rule.extend(('community', config.get('FLOW_COMMUNITY')))
    rule.extend(('rate-limit', '0'))
    flowspec_rule = ' '.join(rule)
    logger.debug("Generate rule '%s'", flowspec_rule)
    return flowspec_rule
Exemplo n.º 3
0
def process_ban(ip, rules):
    if not rules:
        return 1
    for (ip, rule, attack_type) in rules:
        logger.info("Process BAN ip:%s with:'%s'", ip, rule)
        if (not config.get('EXABGP_DRYMODE')):
            exabgp.send_command('announce ' + rule)
        store_attack_host(ip, '', attack_type, rule)
    return 0
Exemplo n.º 4
0
def send_command(rule):
    try:
        f = open(config.get('EXABGP_PIPE'), "w")
        f.write(rule + "\n")
        f.close()
        return 0
    except (OSError, IOError) as err:
        logging.error('File error: %s', err)
        return 1
Exemplo n.º 5
0
def process_unban(ip):
    rules = get_attack_host(ip)
    remove_attack_host(ip)
    if not rules:
        return 1
    for (rule, ) in rules:
        rule_count = get_attack_rules_count(rule)
        if (rule_count == 0):
            logger.info("Process UNBAN ip:%s with:'%s'", ip, rule)
            if (not config.get('EXABGP_DRYMODE')):
                exabgp.send_command('withdraw ' + rule)
        else:
            logger.info("There is another BAN rule '%s' for %s network", rule,
                        ip)
    return 0
Exemplo n.º 6
0
__all__ = [
    'init_db', 'store_attack_host', 'remove_attack_host', 'get_attack_host',
    'get_attack_rules_count', 'get_all_bans'
]

import sqlite3
import logging
import my_fastnetmon.config as config

logger = logging.getLogger("log")

conn = sqlite3.connect(config.get('SQLITE_DB'))
c = conn.cursor()


def init_db():
    c.execute(
        " SELECT count(name) FROM sqlite_master WHERE type='table' AND name='host_attacks' "
    )
    if c.fetchone()[0] == 0:
        c.execute(
            " CREATE TABLE 'host_attacks' (ip TEXT, network TEXT, attack_type TEXT, rule TEXT, datetime TEXT)"
        )
    c.execute(
        " SELECT count(name) FROM sqlite_master WHERE type='table' AND name='network_attacks' "
    )
    if c.fetchone()[0] == 0:
        c.execute(
            " CREATE TABLE 'network_attacks' (network TEXT, attack_type TEXT, rule TEXT, datetime TEXT)"
        )
    conn.commit()
Exemplo n.º 7
0
import sys, getopt
import sqlite3

import my_fastnetmon.config as config

from my_fastnetmon.flows import *
from my_fastnetmon.flowspec import *
from my_fastnetmon.flowban import *
from my_fastnetmon.exabgp import *
from my_fastnetmon.database import *

program_name = 'process_attack'
program_version = '1.2'

logger = logging.getLogger("log")
logger.setLevel(config.get('LOG_LEVEL'))
formatter = logging.Formatter(
    "%(asctime)s - [%(process)d]:%(levelname)s:%(filename)s:%(funcName)s:%(lineno)d - %(message)s"
)
handler = logging.FileHandler(config.get('LOG_FILE'))
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.debug("Start")

if __name__ == '__main__':

    init_db()

    if len(sys.argv) < 5:
        sys.exit(2)
Exemplo n.º 8
0
def process_flows(flows):
    rules = []
    for key, flow in flows.items():

        seconds = int(flow.get('end_datetime').strftime('%s')) - int(
            flow.get('start_datetime').strftime('%s'))
        if seconds <= 0:
            seconds = 1
        pps = flow.get('packets') / seconds
        bps = flow.get('octets') / seconds * 8
        #        logger.debug("FLOW packets %d start time %s - end time %s: PPS:%d BPS:%d",flow.get('packets'),flow.get('start_datetime').strftime('%s'),flow.get('end_datetime').strftime('%s'),pps,bps)
        attack_type = ''
        if (pps > config.get('FLOW_BAN_PPS')):
            dst_ip = flow.get('dst_ip')
            # GRE proto (src and dst port == 0)
            if (flow.get('src_ports').get(0) == 1
                    and flow.get('dst_ports').get(0) == 1):
                attack_type = GRE_FLOOD
                logger.info('Detect GRE/UDP flood to %s', dst_ip)
                rules.append(
                    (dst_ip, create_rule_flow(flow, GRE_FLOOD), attack_type))
                rules.append(
                    (dst_ip, create_rule_flow(flow, UDP_FLOOD), attack_type))

            # UDP flood
            elif (flow.get('protocol') == 'udp'
                  and len(flow.get('src_ports')) == 1
                  and pps > config.get('UDP_FLOOD_PPS')):
                # DNS UDP flood set minimum packet len
                attack_type = 'UDP_FLOOD_' + str(
                    flow.get('src_ports').keys()[0])
                if flow.get('src_ports').get(53) == 1:
                    logger.info('Detect UDP DNS flood to %s', dst_ip)
                    rules.append(
                        (dst_ip, create_rule_flow(flow,
                                                  DNS_FLOOD), attack_type))
                else:
                    logger.info('Detect UDP flood from port %d to %s',
                                flow.get('src_ports').keys()[0], dst_ip)
                    rules.append(
                        (dst_ip, create_rule_flow(flow,
                                                  UDP_FLOOD), attack_type))

            # TCP syn flood
            elif (flow.get('protocol') == 'tcp'
                  and flow.get('flags').get('syn') == 1
                  and pps > config.get('TCP_SYN_FLOOD_PPS')):
                attack_type = 'TCP_SYN_FLOOD_' + str(
                    flow.get('dst_ports').keys()[0])
                logger.info('Detect TCP syn flood to %s:%d', dst_ip,
                            flow.get('dst_ports').keys()[0])
                rules.append(
                    (dst_ip, create_rule_flow(flow,
                                              TCP_SYN_FLOOD), attack_type))
            else:
                logger.info('Unknown attack %s:%d %d', dst_ip,
                            flow.get('dst_ports').keys()[0],
                            flow.get('src_ports').keys()[0])
                continue

        if (bps > config.get('FLOW_BAN_BPS') and attack_type):
            logger.info('Detect HUGE traffic flood (%d) to %s. BLACKHOLE it',
                        bps, dst_ip)
            rules.append((dst_ip, create_rule_blackhole(flow), attack_type))
            continue

    return rules