예제 #1
0
파일: plugin.py 프로젝트: satta/threatbus
def run(
    config: DynaBox,
    logging: DynaBox,
    inq: JoinableQueue,
    subscribe_callback: Callable,
    unsubscribe_callback: Callable,
):
    global logger, workers
    logger = threatbus.logger.setup(logging, __name__)
    assert plugin_name in config, f"Cannot find configuration for {plugin_name} plugin"
    config = config[plugin_name]

    cif = None
    try:
        cif = Client(remote=config.api.host,
                     token=config.api.token,
                     verify_ssl=config.api.ssl)
        cif.ping()
    except Exception as err:
        logger.error(
            f"Cannot connect to CIFv3 at {config.api.host}, using SSL: {config.api.ssl}. Exiting plugin. {err}"
        )
        return

    indicator_q = JoinableQueue()
    topic = "stix2/indicator"
    subscribe_callback(topic, indicator_q)

    workers.append(CIFPublisher(indicator_q, cif, config))
    for w in workers:
        w.start()

    logger.info("CIF3 plugin started")
예제 #2
0
def submit_to_cif(data, host, ssl, token, cache):
    logging.debug('Initializing Client instance to host={}, with ssl={}'.format(host, ssl))
    cli = Client(token=token,
                 remote=host,
                 verify_ssl=ssl)
    logging.info('Submitting indicator: {0}'.format(data))
    try:
        r = cli.indicators_create(json.dumps(data))
        cache.setcache(data['indicator'])
        logging.debug('Indicator submitted with id {}'.format(r))
        return True
    except Exception as e:
        logging.error('Error submitting indicator: {0}'.format(repr(e)))
        return False
 def get_feed(self):
     cli = Client(token=self.token,
                  remote=self.remote,
                  verify_ssl=self.verify)
     logger.debug('Getting feed with filters: {}'.format(self.filters))
     try:
         logger.debug('Getting feed with filter set: {}'.format(
             self.filters))
         f = cli.feed(filters=self.filters)
         return f
     except Exception as e:
         logger.warning('Exception during get_feed: {}'.format(e))
         logger.debug('CLI: {}, Filters: {}'.format(cli, self.filters))
         backoff = randint(30, 120)
         logger.warning(
             'Backing off {} seconds after failure'.format(backoff))
         time.sleep(backoff)
         sys.exit(1)
예제 #4
0
    def search_cif(self, indicator):
        '''
        :param indicator: one of domain, fqdn, or hash
        :return: dictionary of results
        '''

        results = []
        for cif_host in self.cif_hosts:
            cli = Client(token=cif_host['token'],
                         remote=cif_host['remote'],
                         verify_ssl=self.verify)
            filters = {
                'indicator': indicator,
                'limit': self.limit,
                'nolog': '1'
            }
            results += cli.indicators_search(filters=filters)

        return results
예제 #5
0
def submit_to_cif(data, host, ssl, token, cache):
    logging.debug(
        'Initializing Client instance to host={}, with ssl={}'.format(
            host, ssl))
    cli = Client(token=token, remote=host, verify_ssl=ssl)
    logging.info('Submitting indicator: {0}'.format(data))
    try:
        r = cli.indicators_create(json.dumps(data))
        cache.setcache(data['indicator'])
        logging.debug('Indicator submitted with id {}'.format(r))
        return True
    except (SubmissionFailed, Exception) as e:
        if isinstance(e, SubmissionFailed):
            logging.error(
                'Submission failed due to authorization error; please correct your host/key, remove this container, and try again'
            )
            return False
        else:
            logging.error('Error submitting indicator: {} {}'.format(
                type(e).__name__, e.args))
            return False
예제 #6
0
파일: plugin.py 프로젝트: tenzir/threatbus
def run(
    config: Subview,
    logging: Subview,
    inq: JoinableQueue,
    subscribe_callback: Callable,
    unsubscribe_callback: Callable,
):
    global logger, workers
    logger = threatbus.logger.setup(logging, __name__)
    config = config[plugin_name]
    try:
        validate_config(config)
    except Exception as e:
        logger.fatal("Invalid config for plugin {}: {}".format(
            plugin_name, str(e)))

    remote, token, ssl = (
        config["api"]["host"].get(),
        config["api"]["token"].get(),
        config["api"]["ssl"].get(),
    )
    cif = None
    try:
        cif = Client(remote=remote, token=token, verify_ssl=ssl)
        cif.ping()
    except Exception as err:
        logger.error(
            f"Cannot connect to CIFv3 at {remote}, using SSL: {ssl}. Exiting plugin. {err}"
        )
        return

    indicator_q = JoinableQueue()
    topic = "stix2/indicator"
    subscribe_callback(topic, indicator_q)

    workers.append(CIFPublisher(indicator_q, cif, config))
    for w in workers:
        w.start()

    logger.info("CIF3 plugin started")
    def submit_safelist(self, l):
        cli = Client(token=self.token,
                     remote=self.remote,
                     verify_ssl=self.verify)

        filters = [f for f in self._list_to_filters(l)]
        try:
            i = 1
            for data in self._chunks(filters, 500):
                ret = cli.indicators_create(json.dumps(data))
                logger.debug('Submitted chunk {} with return status {}'.format(
                    i, ret))
                i += 1
        except Exception as e:
            logger.warning('Exception during get_feed: {}'.format(e))
            logger.debug('CLI: {}, Filters: {}'.format(cli, data))
            backoff = randint(30, 120)
            logger.warning(
                'Backing off {} seconds after failure'.format(backoff))
            time.sleep(backoff)
            sys.exit(1)
        logger.info('Complete submission of safelist with size {}'.format(
            str(len(l))))
예제 #8
0
def main():
    p = get_argument_parser()
    p = ArgumentParser(description=textwrap.dedent('''\
        example usage:
            $ cif-tokens --name [email protected] --create --admin
        '''),
                       formatter_class=RawDescriptionHelpFormatter,
                       prog='cif',
                       parents=[p])

    p.add_argument('--token',
                   help='specify api token [default %(default)s]',
                   default=TOKEN)
    p.add_argument('--remote',
                   help='specify API remote [default %(default)s]',
                   default=REMOTE_ADDR)

    p.add_argument('--create',
                   help='create token (requires admin token',
                   action='store_true')
    p.add_argument('--delete',
                   help='delete token (requires admin token)',
                   action='store_true')
    p.add_argument('--delete-token', help='specify the token to delete')

    p.add_argument('--username', help='specify username')
    p.add_argument('--name', help='specify username')

    p.add_argument('--admin', action='store_true')
    p.add_argument('--expires', help='set a token expiration timestamp')
    p.add_argument('--read',
                   help='set the token read flag',
                   action='store_true')
    p.add_argument('--write',
                   help='set the token write flag',
                   action='store_true')
    p.add_argument('--revoked',
                   help='set the token revoked flag',
                   action='store_true')
    p.add_argument(
        '--groups',
        help=
        'specify token groups (eg: everyone,group1,group2) [default %(default)s]',
        default='everyone')
    p.add_argument('--no-everyone',
                   help="do not create key in the 'everyone' group",
                   action='store_true')
    p.add_argument('--acl',
                   help='set the token itype acls (eg: ipv4,ipv6)',
                   default='')

    p.add_argument(
        '--columns',
        help='specify columns to print when searching [default %(default)s]',
        default=','.join(COLS))

    p.add_argument('--config-generate', help='generate configuration file')
    p.add_argument('--config',
                   help='specify configuration file [default %(default)s]',
                   default=CONFIG_PATH)
    p.add_argument('--no-verify-ssl',
                   help='Turn OFF TLS verification',
                   action='store_true')

    p.add_argument('--update', help='update a token')

    args = p.parse_args()

    setup_logging(args)
    logger = logging.getLogger(__name__)

    o = {}
    if os.path.isfile(args.config):
        o = read_config(args)
    options = vars(args)

    if not options.get('token'):
        raise RuntimeError('missing --token')

    verify_ssl = True
    if o.get('no_verify_ssl') or options.get('no_verify_ssl'):
        verify_ssl = False

    options = vars(args)

    from cifsdk.client.http import HTTP as HTTPClient
    cli = HTTPClient(args.remote, args.token, verify_ssl=verify_ssl)

    if options.get('name'):
        options['username'] = options['name']

    rv = False
    if options.get('create'):
        if not options.get('username'):
            raise RuntimeError('missing --username')

        if not (options.get('read') or options.get('write')):
            logger.info('assuming --read token')
            options['read'] = True

        groups = set(options.get('groups').split(','))
        if not options.get('no_everyone'):
            if 'everyone' not in groups:
                groups.add('everyone')

        acl = options.get('acl').split(',')

        try:
            rv = cli.tokens_create({
                'username': options.get('username'),
                'admin': options.get('admin'),
                'expires': options.get('expires'),
                'read': options.get('read'),
                'revoked': options.get('revoked'),
                'write': options.get('write'),
                'groups': list(groups),
                'acl': acl
            })

        except AuthError as e:
            logger.error(e)

        except Exception as e:
            logger.error('token create failed: {}'.format(e))
        else:
            if options.get('config_generate'):
                data = {
                    'remote': options['remote'],
                    'token': str(rv['token']),
                }
                with open(options['config_generate'], 'w') as f:
                    f.write(yaml.dump(data, default_flow_style=False))

            t = PrettyTable(args.columns.split(','))
            l = []
            for c in args.columns.split(','):
                if c == 'last_activity_at' and rv.get(c):
                    rv[c] = arrow.get(rv[c]).format('YYYY-MM-DDTHH:MM:ss')
                    rv[c] = '{}Z'.format(rv[c])

                if c == 'expires' and rv.get(c):
                    rv[c] = arrow.get(rv[c]).format('YYYY-MM-DDTHH:MM:ss')
                    rv[c] = '{}Z'.format(rv[c])

                if rv.get(c):
                    if type(rv[c]) == list:
                        l.append(','.join(rv[c]))
                    else:
                        l.append(str(rv[c]))
                else:
                    l.append(None)
            t.add_row(l)
            print(t)

    elif options.get('delete_token'):
        try:
            rv = cli.tokens_delete({
                'token': options.get('delete_token'),
                'username': options.get('username')
            })
            if rv:
                logger.info('deleted: {} tokens successfully'.format(rv))
            else:
                logger.error('no tokens deleted')
        except Exception as e:
            logger.error('token delete failed: %s' % e)

    elif options.get('delete'):
        if not (options.get('delete_token') or options.get('username')):
            raise RuntimeError(
                '--delete requires --delete-token or --username')
        try:
            rv = cli.tokens_delete({
                'token': options.get('delete_token'),
                'username': options.get('username')
            })
            if rv:
                logger.info('deleted: {} tokens successfully'.format(rv))
            else:
                logger.error('no tokens deleted')
        except Exception as e:
            logger.error('token delete failed: %s' % e)

    elif options.get('update'):
        if not options.get('groups'):
            raise RuntimeError('requires --groups')

        groups = options['groups'].split(',')

        rv = cli.tokens_edit({'token': options['update'], 'groups': groups})

        if rv:
            logger.info('token updated successfully')
            rv = cli.tokens_search({'token': options['update']})
            t = PrettyTable(args.columns.split(','))
            for r in rv:
                l = []
                for c in args.columns.split(','):
                    if c == 'last_activity_at' and r[c] is not None:
                        r[c] = arrow.get(r[c]).format('YYYY-MM-DDTHH:MM:ss')
                        r[c] = '{}Z'.format(r[c])
                    if c == 'expires' and r[c] is not None:
                        r[c] = arrow.get(r[c]).format('YYYY-MM-DDTHH:MM:ss')
                        r[c] = '{}Z'.format(r[c])
                    l.append(r[c])
                t.add_row(l)
            print(t)
        else:
            logger.error(rv)

    else:
        filters = {}
        if options.get('username'):
            filters['username'] = options.get('username')
        try:
            rv = cli.tokens_search(filters)
        except AuthError:
            logger.error('unauthorized')
        except Exception as e:
            import traceback
            traceback.print_exc()
            print("\ntoken search failed: %s" % e)
        else:
            t = PrettyTable(args.columns.split(','))
            for r in rv:
                l = []
                for c in args.columns.split(','):
                    if c == 'last_activity_at' and r.get(c) is not None:
                        r[c] = parse_timestamp(
                            r[c]).format('YYYY-MM-DDTHH:mm:ss.SS')
                        r[c] = '{}Z'.format(r[c])
                    if c == 'expires' and r.get(c) is not None:
                        r[c] = parse_timestamp(
                            r[c]).format('YYYY-MM-DDTHH:mm:ss.SS')
                        r[c] = '{}Z'.format(r[c])
                    if type(r.get(c)) == list:
                        r[c] = ','.join(r[c])
                    l.append(r.get(c))
                t.add_row(l)
            print(t)
예제 #9
0
def main():
    p = get_argument_parser()
    p = ArgumentParser(
        description=textwrap.dedent('''\
            Env Variables:
                CIF_TOKEN
                CIF_REMOTE

            example usage:
                $ cif-tail
            '''),
        formatter_class=RawDescriptionHelpFormatter,
        prog='cif-tail',
        parents=[p],
    )

    p.add_argument('--no-verify-ssl',
                   help='turn TLS/SSL verification OFF',
                   action='store_true')
    p.add_argument('--format', default='table')
    p.add_argument('--cycle',
                   help='specify a cycle in which to run',
                   default=5)
    p.add_argument('--filters',
                   help='specify data filters to use',
                   default='itype=ipv4,confidence=7,limit=10')
    p.add_argument('--remote', default=REMOTE_ADDR)
    p.add_argument('--token', default=TOKEN)
    p.add_argument('--start',
                   default=arrow.get((arrow.utcnow().timestamp - 420)))

    args = p.parse_args()

    # setup logging
    setup_logging(args)

    verify_ssl = True
    if args.no_verify_ssl:
        verify_ssl = False

    filters = {}
    for k in args.filters.split(','):
        kk, v = k.split('=')
        filters[kk] = v

    remote = args.remote
    token = args.token
    client = Client(remote, token, verify_ssl=verify_ssl)

    start = args.start
    start = arrow.get(start)

    cycle = (int(args.cycle) * 60)

    # we want a 120s buffer for things that are being generated "now"
    end = arrow.get((arrow.utcnow().timestamp - 120))

    while True:
        logger.debug('now: %s' % arrow.utcnow())
        start = start.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'
        end = end.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'

        filters['reporttime'] = '{},{}'.format(start, end)
        logger.debug('searching {} - {}'.format(start, end))
        resp = client.indicators_search(filters)
        if args.format == 'csv':
            for l in get_lines_csv(resp):
                print(l)
        else:
            for l in get_lines_table(resp):
                print(l)

        logger.debug('sleeping for {}m'.format(args.cycle))
        sleep(cycle)

        # todo- this needs some work, maybe use last record if there was one?
        # what if there wasn't?
        start = arrow.get(arrow.get(end).timestamp + 1)
        end = arrow.get((arrow.utcnow().timestamp - 120))
예제 #10
0
def main():
    p = get_argument_parser()
    p = ArgumentParser(
        description=textwrap.dedent('''\
        example usage:
            $ cif-tokens --name [email protected] --create --admin
        '''),
        formatter_class=RawDescriptionHelpFormatter,
        prog='cif',
        parents=[p]
    )

    p.add_argument('--token', help='specify api token [default %(default)s]', default=TOKEN)
    p.add_argument('--remote', help='specify API remote [default %(default)s]', default=REMOTE_ADDR)

    p.add_argument('--create', help='create token (requires admin token', action='store_true')
    p.add_argument('--delete', help='delete token (requires admin token)', action='store_true')
    p.add_argument('--delete-token', help='specify the token to delete')

    p.add_argument('--username', help='specify username')
    p.add_argument('--name', help='specify username')

    p.add_argument('--admin', action='store_true')
    p.add_argument('--expires', help='set a token expiration timestamp')
    p.add_argument('--read', help='set the token read flag', action='store_true')
    p.add_argument('--write', help='set the token write flag', action='store_true')
    p.add_argument('--revoked', help='set the token revoked flag', action='store_true')
    p.add_argument('--groups', help='specify token groups (eg: everyone,group1,group2) [default %(default)s]',
                   default='everyone')
    p.add_argument('--no-everyone', help="do not create key in the 'everyone' group", action='store_true')
    p.add_argument('--acl', help='set the token itype acls (eg: ipv4,ipv6)', default='')

    p.add_argument('--columns', help='specify columns to print when searching [default %(default)s]',
                   default=','.join(COLS))

    p.add_argument('--config-generate', help='generate configuration file')
    p.add_argument('--config', help='specify configuration file [default %(default)s]', default=CONFIG_PATH)
    p.add_argument('--no-verify-ssl', help='Turn OFF TLS verification', action='store_true')

    p.add_argument('--update', help='update a token')

    args = p.parse_args()

    setup_logging(args)
    logger = logging.getLogger(__name__)

    o = read_config(args)
    options = vars(args)
    for v in options:
        if v == 'remote' and options[v] == REMOTE_ADDR and o.get('remote'):
            options[v] = o['remote']

        if v == 'token' and o.get('token'):
            options[v] = o['token']

        if options[v] is None:
            options[v] = o.get(v)

    if not options.get('token'):
        raise RuntimeError('missing --token')

    verify_ssl = True
    if o.get('no_verify_ssl') or options.get('no_verify_ssl'):
        verify_ssl = False

    options = vars(args)

    from cifsdk.client.http import HTTP as HTTPClient
    cli = HTTPClient(args.remote, args.token, verify_ssl=verify_ssl)

    if options.get('name'):
        options['username'] = options['name']

    rv = False
    if options.get('create'):
        if not options.get('username'):
            raise RuntimeError('missing --username')

        if not (options.get('read') or options.get('write')):
            logger.info('assuming --read token')
            options['read'] = True

        groups = set(options.get('groups').split(','))
        if not options.get('no_everyone'):
            if 'everyone' not in groups:
                groups.add('everyone')

        acl = options.get('acl').split(',')

        try:
            rv = cli.tokens_create({
                'username': options.get('username'),
                'admin': options.get('admin'),
                'expires': options.get('expires'),
                'read': options.get('read'),
                'revoked': options.get('revoked'),
                'write': options.get('write'),
                'groups': list(groups),
                'acl': acl
            })
        except AuthError as e:
            logger.error(e)
        except Exception as e:
            logger.error('token create failed: {}'.format(e))
        else:
            if options.get('config_generate'):
                data = {
                    'remote': options['remote'],
                    'token': str(rv['token']),
                }
                with open(options['config_generate'], 'w') as f:
                    f.write(yaml.dump(data, default_flow_style=False))

            t = PrettyTable(args.columns.split(','))
            l = []
            for c in args.columns.split(','):
                if c == 'last_activity_at' and rv.get(c):
                    rv[c] = arrow.get(rv[c]).format('YYYY-MM-DDTHH:MM:ss')
                    rv[c] = '{}Z'.format(rv[c])

                if c == 'expires' and rv.get(c):
                    rv[c] = arrow.get(rv[c]).format('YYYY-MM-DDTHH:MM:ss')
                    rv[c] = '{}Z'.format(rv[c])

                if rv.get(c):
                    if type(rv[c]) == list:
                        l.append(','.join(rv[c]))
                    else:
                        l.append(str(rv[c]))
                else:
                    l.append(None)
            t.add_row(l)
            print(t)

    elif options.get('delete_token'):
        try:
            rv = cli.tokens_delete({
                'token': options.get('delete_token'),
                'username': options.get('username')
            })
            if rv:
                logger.info('deleted: {} tokens successfully'.format(rv))
            else:
                logger.error('no tokens deleted')
        except Exception as e:
            logger.error('token delete failed: %s' % e)

    elif options.get('delete'):
        if not (options.get('delete_token') or options.get('username')):
            raise RuntimeError('--delete requires --delete-token or --username')
        try:
            rv = cli.tokens_delete({
                'token': options.get('delete_token'),
                'username': options.get('username')
            })
            if rv:
                logger.info('deleted: {} tokens successfully'.format(rv))
            else:
                logger.error('no tokens deleted')
        except Exception as e:
            logger.error('token delete failed: %s' % e)
    elif options.get('update'):
        if not options.get('groups'):
            raise RuntimeError('requires --groups')

        groups = options['groups'].split(',')

        rv = cli.tokens_edit({
            'token': options['update'],
            'groups': groups
        })

        if rv:
            print('token updated successfully')
            print('refreshing tokens...')
            sleep(2)
            rv = cli.tokens_search({'token': options['update']})
            t = PrettyTable(args.columns.split(','))
            for r in rv:
                l = []
                for c in args.columns.split(','):
                    if c == 'last_activity_at' and r.get(c) is not None:
                        r[c] = parse_timestamp(r[c]).format('YYYY-MM-DDTHH:mm:ss.SS')
                        r[c] = '{}Z'.format(r[c])
                    if c == 'expires' and r.get(c) is not None:
                        r[c] = parse_timestamp(r[c]).format('YYYY-MM-DDTHH:mm:ss.SS')
                        r[c] = '{}Z'.format(r[c])
                    if type(r.get(c)) == list:
                        r[c] = ','.join(r[c])
                    l.append(r.get(c))
                t.add_row(l)
            print(t)
        else:
            logger.error(rv)
    else:
        filters = {}
        if options.get('username'):
            filters['username'] = options.get('username')
        try:
            rv = cli.tokens_search(filters)
        except AuthError:
            logger.error('unauthorized')
        except Exception as e:
            logger.error('token search failed: {}'.format(e))
        else:
            t = PrettyTable(args.columns.split(','))
            for r in rv:
                l = []
                for c in args.columns.split(','):
                    if c == 'last_activity_at' and r.get(c) is not None:
                        r[c] = parse_timestamp(r[c]).format('YYYY-MM-DDTHH:mm:ss.SS')
                        r[c] = '{}Z'.format(r[c])
                    if c == 'expires' and r.get(c) is not None:
                        r[c] = parse_timestamp(r[c]).format('YYYY-MM-DDTHH:mm:ss.SS')
                        r[c] = '{}Z'.format(r[c])
                    if type(r.get(c)) == list:
                        r[c] = ','.join(r[c])
                    l.append(r.get(c))
                t.add_row(l)
            print(t)
예제 #11
0
def main():
    p = get_argument_parser()
    p = ArgumentParser(
        description=textwrap.dedent('''\
            Env Variables:
                CIF_TOKEN
                CIF_REMOTE

            example usage:
                $ cif-tail
            '''),
        formatter_class=RawDescriptionHelpFormatter,
        prog='cif-tail',
        parents=[p],
    )

    p.add_argument('--no-verify-ssl', help='turn TLS/SSL verification OFF', action='store_true')
    p.add_argument('--format', default='table')
    p.add_argument('--cycle', help='specify a cycle in which to run', default=5)
    p.add_argument('--filters', help='specify data filters to use', default='itype=ipv4,confidence=7,limit=10')
    p.add_argument('--remote', default=REMOTE_ADDR)
    p.add_argument('--token', default=TOKEN)
    p.add_argument('--start', default=arrow.get((arrow.utcnow().timestamp - 420)))

    args = p.parse_args()

    # setup logging
    setup_logging(args)

    verify_ssl = not args.no_verify_ssl

    filters = {}
    for k in args.filters.split(','):
        kk, v = k.split('=')
        filters[kk] = v

    remote = args.remote
    token = args.token
    client = Client(remote, token, verify_ssl=verify_ssl)

    start = args.start
    start = arrow.get(start)

    cycle = (int(args.cycle) * 60)
    delay = Delayer(upper=cycle)

    # we want a 120s buffer for things that are being generated "now"
    end = arrow.get((arrow.utcnow().timestamp - 120))

    while True:
        logger.debug('now: %s' % arrow.utcnow())
        start = start.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'
        end = end.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'

        filters['reporttime'] = '{},{}'.format(start, end)
        logger.debug('searching {} - {}'.format(start, end))
        try:
            resp = client.indicators_search(filters)
        except Exception:
            logger.exception("CIF API Error")
            resp = []
        if resp:
            delay.reset()
            if args.format == 'csv':
                for l in get_lines_csv(resp):
                    print(l)
            else:
                for l in get_lines_table(resp):
                    print(l)

        delay.sleep()

        # todo- this needs some work, maybe use last record if there was one?
        # what if there wasn't?
        start = arrow.get(arrow.get(end).timestamp + 1)
        end = arrow.get((arrow.utcnow().timestamp - 120))
예제 #12
0
    def run(self):
        Responder.run(self)
        confidence = None

        indicators = []

        # case details
        if self.get_param('data._type') == 'case_artifact':
            a = {}
            a['indicator'] = self.get_param('data.data', None, 'Missing indicator')
            a['tags'] = self.get_param('data.tags')
            a['tlp'] = self.get_param('data.tlp', None)
            a['desc'] = self.get_param('data.message', None)
            a['lasttime'] = self.get_param('data.createdAt', None)
            indicators.append(a)

        # alert details
        if self.get_param('data._type') == 'alert':
            for i in self.get_param('data.artifacts'):
                a = {}
                a['indicator'] = i['data']
                a['tags'] = i['tags']
                a['tlp'] = self.get_param('data.tlp', None)
                a['desc'] = self.get_param('data.description', None)
                a['lasttime'] = self.get_param('data.createdAt', None)
                if self.get_param('data.updatedAt'):
                    a['lasttime'] = self.get_param('data.updatedAt')
                indicators.append(a)

        for i in indicators:

            # map TLP to word
            tlp = self.TLP_MAP[str(i['tlp'])]

            # process tags
            tags = i['tags']
            for t in list(tags):
                # confidence tag check
                if 'confidence:' in t:
                    tags.remove(t)
                    (k, v) = t.split(':')
                    confidence = int(v)
                # remove other directive tags
                elif ':' in t:
                    tags.remove(t)

            # set to default confidence if not defined
            if not confidence:
                confidence = self.d_confidence

            # convert lasttime
            lasttime = datetime.utcfromtimestamp(i['lasttime']/1000).strftime('%Y-%m-%dT%H:%M:%S.%fZ')

            # build indicator
            ii = {
                'indicator': i['indicator'],
                'confidence': confidence,
                'description': i['desc'],
                'tags': tags,
                'tlp': tlp,
                'group': self.group,
                'lasttime': lasttime
            }

            # create indicator object
            try:
                ii = Indicator(**ii)
            except InvalidIndicator as e:
                self.error("Invalid CIF indicator {}".format(e))
            except Exception as e:
                self.error("CIF indicator error: {}".format(e))

            # submit indicator
            cli = Client(token=self.token, remote=self.remote, verify_ssl=self.verify_ssl)

            try:
                r = cli.indicators_create(ii)
            except Exception as e:
                self.error("CIF submission error: {}".format(e))

        self.report({'message': '{} indicator(s) submitted to CIFv3'.format(len(indicators))})
예제 #13
0
def main():
    logging.info("Running build_config.py")
    MONGODB_HOST = os.environ.get("MONGODB_HOST", "mongodb")
    MONGODB_PORT = os.environ.get("MONGODB_PORT", "27017")
    HPFEEDS_HOST = os.environ.get("HPFEEDS_HOST", "hpfeeds3")
    HPFEEDS_PORT = os.environ.get("HPFEEDS_PORT", "10000")
    IDENT = os.environ.get("IDENT", "")
    SECRET = os.environ.get("SECRET", "")
    CHANNELS = os.environ.get(
        "CHANNELS",
        "amun.events,conpot.events,thug.events,beeswarm.hive,dionaea.capture,dionaea.connections,thug.files,beeswarm.feeder,cuckoo.analysis,kippo.sessions,cowrie.sessions,glastopf.events,glastopf.files,mwbinary.dionaea.sensorunique,snort.alerts,wordpot.events,p0f.events,suricata.events,shockpot.events,elastichoney.events,rdphoney.sessions,uhp.events,elasticpot.events,spylex.events,big-hp.events,ssh-auth-logger.events,honeydb-agent.events"
    )
    CIF_HOST = os.environ.get("CIF_HOST", "")
    CIF_TOKEN = os.environ.get("CIF_TOKEN", "")
    CIF_PROVIDER = os.environ.get("CIF_PROVIDER", "")
    CIF_TLP = os.environ.get("CIF_TLP", "")
    CIF_CONFIDENCE = os.environ.get("CIF_CONFIDENCE", "")
    CIF_TAGS = os.environ.get("CIF_TAGS", "")
    CIF_GROUP = os.environ.get("CIF_GROUP", "")
    CIF_VERIFY_SSL = os.environ.get("CIF_VERIFY_SSL", "")
    INCLUDE_HP_TAGS = os.environ.get("INCLUDE_HP_TAGS", "false")
    IGNORE_CIDR = os.environ.get("IGNORE_CIDR", "false")
    CIF_CACHE_DB = os.environ.get("CIF_CACHE_DB", "2")
    CIF_CACHE_EXPIRE = os.environ.get("CIF_CACHE_EXPIRE", "300")

    if IDENT:
        ident = IDENT
    else:
        ident = "hpfeeds-cif-" + str(random.randint(0, 32767))

    if SECRET:
        secret = SECRET
    else:
        secret = str(uuid.uuid4()).replace("-", "")

    config = configparser.ConfigParser()
    config.read("/opt/hpfeeds-cif.cfg.template")
    config['hpfeeds']['ident'] = ident
    config['hpfeeds']['secret'] = secret
    config['hpfeeds']['hp_host'] = HPFEEDS_HOST
    config['hpfeeds']['hp_port'] = HPFEEDS_PORT
    config['hpfeeds']['channels'] = CHANNELS
    config['hpfeeds']['include_hp_tags'] = INCLUDE_HP_TAGS
    config['hpfeeds']['ignore_cidr'] = IGNORE_CIDR

    config['cifv3']['cif_host'] = CIF_HOST
    config['cifv3']['cif_token'] = CIF_TOKEN
    config['cifv3']['cif_provider'] = CIF_PROVIDER
    config['cifv3']['cif_tlp'] = CIF_TLP
    config['cifv3']['cif_confidence'] = CIF_CONFIDENCE
    config['cifv3']['cif_tags'] = CIF_TAGS
    config['cifv3']['cif_group'] = CIF_GROUP
    config['cifv3']['cif_verify_ssl'] = CIF_VERIFY_SSL
    config['cifv3']['cif_cache_db'] = CIF_CACHE_DB
    config['cifv3']['cif_cache_expire'] = CIF_CACHE_EXPIRE

    create_user(host=MONGODB_HOST,
                port=int(MONGODB_PORT),
                owner="chn",
                ident=ident,
                secret=secret,
                publish="",
                subscribe=CHANNELS)

    cli = Client(token=CIF_TOKEN, remote=CIF_HOST, verify_ssl=False)
    try:
        ret = cli.ping(write=True)
    except AuthError:
        logging.error("Authentication to %s failed." % CIF_HOST)
        sys.exit(1)

    print("Writing config...")

    with open("/opt/hpfeeds-cif.cfg", 'w') as config_file:
        config.write(config_file)
    sys.exit(0)