Exemplo n.º 1
0
def main():
    parser = ArgumentParser(description=textwrap.dedent('''\
        example usage:
            $ csirtg --search example.com
            $ csirtg --user csirtgadgets --feeds
            $ csirtg --user csirtgadgets --feed uce-urls
            $ csirtg --user csirtgadgets --feed-new scanners --description 'a feed of port scanners'
            $ csirtg --user csirtgadgets --feed scanners --indicator-new 1.1.1.1 --tags scanner --comment
              'this is a port scanner'
            $ csirtg --user csirtgadgets --feed uce-attachments --new --attachment 'fax.zip'
              --description 'file attached in uce email'
        '''),
                            formatter_class=RawDescriptionHelpFormatter,
                            prog='csirtg')

    parser.add_argument("-v",
                        "--verbose",
                        action="count",
                        help="set verbosity level [default: %(default)s]")
    parser.add_argument('-d', '--debug', action="store_true")

    parser.add_argument('--token', help="specify token", default=TOKEN)
    parser.add_argument('-l',
                        '--limit',
                        help="specify results limit [default: %(default)s]",
                        default=LIMIT)
    parser.add_argument('--remote',
                        help="remote api location [default: %(default)s]",
                        default=REMOTE)
    parser.add_argument('--timeout',
                        help='connection timeout [default: %(default)s]',
                        default=TIMEOUT)
    parser.add_argument('-C',
                        '--config',
                        help="configuration file [default: %(default)s]",
                        default=os.path.expanduser("~/.csirtg.yml"))  # env var

    parser.add_argument('--format',
                        help="specify an output format [default: %(default)s]",
                        default='table')
    parser.add_argument('--columns',
                        help='specify output columns [default %(default)s]',
                        default=','.join(COLUMNS))

    # actions
    parser.add_argument('-q', '--search', help="search for an indicator")
    parser.add_argument('--feeds',
                        action="store_true",
                        help="show a list of feeds (per user)")
    parser.add_argument('--new',
                        action='store_true',
                        help="create a new feed or indicator")

    parser.add_argument('--predict',
                        help="test an indicator against the prediction api")
    parser.add_argument('--predict-stdin', action="store_true")

    # vars
    parser.add_argument('--user', help="specify a user")
    parser.add_argument('--feed', help="specify feed name")
    parser.add_argument('--feed-new', help='help specify a new feed')
    parser.add_argument('--indicator',
                        dest='indicator',
                        help="specify an indicator [eg: 1.2.3.4, example.com, "
                        "http://example.com/1.html")
    parser.add_argument('--indicator-new', help='create a new indicator')
    parser.add_argument('--tags', help="specify tags")
    parser.add_argument('--comment', help="enter a comment for the indicator")
    parser.add_argument('--description', help="specify a feed description")

    parser.add_argument('--portlist',
                        help="specify a portlist [eg: 22,23-35,443]")
    parser.add_argument('--protocol', help="specify TCP, UDP or ICMP")

    parser.add_argument(
        '--firsttime',
        help="timestamp when first seen [eg: 2015-11-23T00:00:00Z]")
    parser.add_argument(
        '--lasttime',
        help=
        "timestamp when last seen [eg: 2015-11-24T00:00:00Z], treated as 'greater "
        "than'")

    parser.add_argument('--attachment',
                        help="specify an attachment [eg: /path/to/file]")
    parser.add_argument('--attachment-name',
                        help="specify the attachment filename")

    parser.add_argument('--no-verify-ssl',
                        help='Turn TLS verification OFF',
                        action="store_true")

    parser.add_argument('--sinkhole', action='store_true')

    parser.add_argument(
        '--threatmodel',
        '--tm',
        help='predict using a threatmodel (eg: wes/phishing-urls)')

    # Process arguments
    args = parser.parse_args()
    setup_logging(args)

    logger = logging.getLogger(__name__)

    if args.verbose:
        logger.setLevel(logging.INFO)

    if args.debug:
        logger.setLevel(logging.DEBUG)

    options = vars(args)
    o = read_config(args)
    options.update(o)

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

    cli = Client(remote=options['remote'],
                 token=options['token'],
                 verify_ssl=verify_ssl)

    if options.get('sinkhole'):
        import sys
        if not sys.stdin.isatty():
            stdin = sys.stdin.read()
        else:
            logger.error("No data passed via STDIN")
            raise SystemExit

        from csirtgsdk.sinkhole import Sinkhole
        ret = Sinkhole(cli).post(stdin)

        if ret.get('status') == 'unauthorized':
            logger.error('unauthorized')
        else:
            if logger.getEffectiveLevel() == logging.DEBUG:
                print("Predictions: \n")
                for p in ret.get('predictions', []):
                    print("\t%s" % p)

        raise SystemExit

    if options.get('threatmodel'):
        try:
            from csirtgsdk.threatmodel import Threatmodel
        except:
            print("")
            print(
                "Missing some extra machine learning libraries required to make this work.."
            )
            print("$ pip install numpy keras pandas tensorflow")
            print("")
            raise SystemExit

        user, name = options['threatmodel'].split('/')
        m = Threatmodel(cli).show(user, name, options['search'])

        print("Prediction: %f" % (m * 100))

        raise SystemExit

    if options.get('predict') or options.get('predict_stdin'):
        import sys
        if options.get('predict'):
            logger.info("Searching for: {0}".format(options.get('predict')))
            predict = options['predict']
            ret = Predict(cli).get(predict)
            print("Prediction Score: %s - %s" % (ret, predict))
        else:
            import sys
            if not sys.stdin.isatty():
                for predict in sys.stdin.read().split("\n"):
                    if predict == '':
                        continue
                    ret = Predict(cli).get(predict)
                    print("Prediction Score: %s - %s" % (ret, predict))
            else:
                logger.error("No data passed via STDIN")
                raise SystemExit

        raise SystemExit

    if options.get('search'):
        logger.info("Searching for: {0}".format(options.get('search')))
        ret = Search(cli).search(options.get('search'), limit=options['limit'])
        if isinstance(ret, dict):
            ret = [ret]

        print(FORMATS[options.get('format')](data=ret,
                                             cols=args.columns.split(',')))
        raise SystemExit

    if options.get('indicator_new') or options.get('attachment'):
        options['indicator'] = options['indicator_new']
        logger.info("Creating indicator in feed {0} for user {1}".format(
            options['feed'], options['user']))
        ret = Indicator(cli, options).submit()
        logger.info('posted: {0}'.format(ret['location']))

        if isinstance(ret, dict):
            ret = [ret]

        print(FORMATS[options.get('format')](data=ret,
                                             cols=args.columns.split(',')))
        raise SystemExit

    if options.get('feeds'):
        logger.info("Searching feeds for user: {0}".format(options['user']))
        f = Feed(cli)
        feeds = f.index(options['user'])
        for l in f.get_lines(feeds):
            print(l)
        raise SystemExit

    if options.get('feed_new'):
        if not options.get('user'):
            parser.error('--user is required')

        if not options.get('description'):
            parser.error('--description is required')

        logger.info("Creating feed {0} for user {1}".format(
            options['feed_new'], options['user']))
        f = Feed(cli)
        feed = f.new(options['user'],
                     options['feed_new'],
                     description=options['description'])
        for l in f.get_lines(feed):
            print(l)

        raise SystemExit

    if options.get('feed'):
        if not options.get('user'):
            parser.error('--user is required')

        logger.info("Fetching feed {0} for user {1}".format(
            options['feed'], options['user']))
        data = Feed(cli).show(
            options['user'],
            options['feed'],
            limit=options['limit'],
            lasttime=options['lasttime'],
        )

        if data.get('indicators'):
            print(FORMATS[options.get('format')](data=data['indicators'],
                                                 cols=args.columns.split(',')))
Exemplo n.º 2
0
def main():
    parser = ArgumentParser(description=textwrap.dedent('''\
        example usage:
            $ csirtg --search example.com
            $ csirtg --user csirtgadgets --feeds
            $ csirtg --user csirtgadgets --feed uce-urls
            $ csirtg --user csirtgadgets --new --feed scanners --description 'a feed of port scanners'
            $ csirtg --user csirtgadgets --feed scanners --new --indicator 1.1.1.1 --tags scanner --comment
              'this is a port scanner'
            $ csirtg --user csirtgadgets --feed uce-attachments --new --attachment 'fax.zip'
              --description 'file attached in uce email'
        '''),
                            formatter_class=RawDescriptionHelpFormatter,
                            prog='csirtg')

    parser.add_argument("-v",
                        "--verbose",
                        action="count",
                        help="set verbosity level [default: %(default)s]")
    parser.add_argument('-d', '--debug', action="store_true")

    parser.add_argument('--token', help="specify token", default=TOKEN)
    parser.add_argument('-l',
                        '--limit',
                        help="specify results limit [default: %(default)s]",
                        default=LIMIT)
    parser.add_argument('--remote',
                        help="remote api location [default: %(default)s]",
                        default=REMOTE)
    parser.add_argument('--timeout',
                        help='connection timeout [default: %(default)s]',
                        default=TIMEOUT)
    parser.add_argument('-C',
                        '--config',
                        help="configuration file [default: %(default)s]",
                        default=os.path.expanduser("~/.csirtg.yml"))  # env var

    parser.add_argument('--format',
                        help="specify an output format [default: %(default)s]",
                        default='table')
    # actions
    parser.add_argument('-q', '--search', help="search for an indicator")
    parser.add_argument('--feeds',
                        action="store_true",
                        help="show a list of feeds (per user)")
    parser.add_argument('--new',
                        action='store_true',
                        help="create a new feed or indicator")

    # vars
    parser.add_argument('--user', help="specify a user")
    parser.add_argument('--feed', help="specify feed name")
    parser.add_argument('--indicator',
                        dest='indicator',
                        help="specify an indicator [eg: 1.2.3.4, example.com, "
                        "http://example.com/1.html")
    parser.add_argument('--tags', help="specify tags")
    parser.add_argument('--comment', help="enter a comment for the indicator")
    parser.add_argument('--description', help="specify a feed description")

    parser.add_argument('--portlist',
                        help="specify a portlist [eg: 22,23-35,443]")
    parser.add_argument('--protocol', help="specify TCP, UDP or ICMP")

    parser.add_argument(
        '--firsttime',
        help="timestamp when first seen [eg: 2015-11-23T00:00:00Z]")
    parser.add_argument(
        '--lasttime',
        help=
        "timestamp when last seen [eg: 2015-11-24T00:00:00Z], treated as 'greater "
        "than'")

    parser.add_argument('--attachment',
                        help="specify an attachment [eg: /path/to/file]")
    parser.add_argument('--attachment-name',
                        help="specify the attachment filename")

    parser.add_argument('--no-verify-ssl',
                        help='Turn TLS verification OFF',
                        action="store_true")

    # Process arguments
    args = parser.parse_args()
    setup_logging(args)

    logger = logging.getLogger(__name__)

    ## TODO -- yconf ?
    options = vars(args)
    o = read_config(args)
    options.update(o)

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

    cli = Client(remote=options['remote'],
                 token=options['token'],
                 verify_ssl=verify_ssl)

    if options.get('search'):
        logger.info("Searching for: {0}".format(options.get('search')))
        ret = Search(cli).search(options.get('search'), limit=options['limit'])
        format = format_factory(options['format'])
        format(ret).write()
        logger.info("Done")

    elif options.get('feeds'):
        logger.info("Searching feeds for user: {0}".format(options['user']))
        feeds = Feed(cli).index(options['user'])
        from prettytable import PrettyTable
        cols = ['name', 'description', 'license', 'updated_at']
        t = PrettyTable(cols)
        for f in feeds:
            r = []
            for c in cols:
                y = f['feed'].get(c)
                if c == 'license':
                    y = y['name']
                y = str(y)
                y = (y[:30] + '..') if len(y) > 30 else y
                r.append(y)
            t.add_row(r)
        print(str(t))
        logger.info("Done")

    elif options.get('feed') and options.get('new') and (
            not options.get('indicator') and not options.get('attachment')):
        if not options.get('user'):
            parser.error('--user is required')

        logger.info("Creating feed {0} for user {1}".format(
            options['feed'], options['user']))
        feed = Feed(cli).new(options['user'],
                             options['feed'],
                             description=options['description'])

        from prettytable import PrettyTable
        cols = ['name', 'description', 'license', 'updated_at']
        t = PrettyTable(cols)
        r = []
        for c in cols:
            y = feed.get(c)
            if c == 'license':
                y = y['name']
            y = str(y)
            y = (y[:30] + '..') if len(y) > 30 else y
            r.append(y)
        t.add_row(r)

        print(str(t))
        logger.info("Done")

    elif options.get('feed') and not options.get('new'):
        if not options.get('user'):
            parser.error('--user is required')

        logger.info("Fetching feed {0} for user {1}".format(
            options['feed'], options['user']))
        data = Feed(cli).show(
            options['user'],
            options['feed'],
            limit=options['limit'],
            lasttime=options['lasttime'],
        )

        if data['feed'].get('indicators'):
            format = format_factory(options['format'])
            format(data).write()
        logger.info("Done")

    # submit new indicator
    elif options.get('feed') and (
            options.get('indicator') or
        (options.get('attachment') and not options.get('indicator'))
    ) and options.get('new') and options.get('user'):
        try:
            logger.info("Creating indicator in feed {0} for user {1}".format(
                options['feed'], options['user']))
            ret = Indicator(cli, options).submit()
            logger.info('posted: {0}'.format(ret['indicator']['location']))
            ret = {'feed': {'indicators': [ret]}}
            format = format_factory(options['format'])
            format(ret).write()
            logger.info("Done")

        except RuntimeError as e:
            logger.error(e)