Beispiel #1
0
def main() -> None:
    """main function"""

    # Look for default ini file in "/etc/actworkers.ini" and ~/config/actworkers/actworkers.ini
    # (or replace .config with $XDG_CONFIG_DIR if set)
    args = worker.handle_args(parseargs())

    actapi = worker.init_act(args)

    if not args.apikey:
        worker.fatal("You must specify --apikey on command line or in config file")

    in_data = sys.stdin.read().strip()

    proxies = {
        'http': args.proxy_string,
        'https': args.proxy_string
    } if args.proxy_string else None

    vtapi = VirusTotalApi(args.apikey, proxies=proxies)

    if args.hexdigest:
        handle_hexdigest(actapi, vtapi, in_data, output_format=args.output_format)

    if args.ip:
        handle_ip(actapi, vtapi, in_data, output_format=args.output_format)

    if args.domain:
        handle_domain(actapi, vtapi, in_data, output_format=args.output_format)
Beispiel #2
0
def main() -> None:
    " main function "

    # Look for default ini file in "/etc/actworkers.ini" and
    # ~/config/actworkers/actworkers.ini
    # (or replace .config with $XDG_CONFIG_DIR if set)

    args = worker.handle_args(parseargs())

    if not args.argus_apikey:
        worker.fatal(
            "You must specify --apikey on command line or in config file")

    actapi = worker.init_act(args)
    process(actapi, args)
Beispiel #3
0
def main() -> None:
    """main function"""

    # Look for default ini file in "/etc/actworkers.ini" and ~/config/actworkers/actworkers.ini
    # (or replace .config with $XDG_CONFIG_DIR if set)
    args = worker.handle_args(parseargs())

    actapi = worker.init_act(args)

    if not args.country_codes:
        worker.fatal(
            "You must specify --country-codes on command line or in config file"
        )

    if not os.path.isfile(args.country_codes):
        worker.fatal(
            "Country/region file not found at specified location: {}".format(
                args.country_codes), 2)

    # Get map of CC -> Country Name
    cn_map = get_cn_map(args.country_codes)

    db_cache = get_db_cache(CACHE_DIR)

    # Read IPs from stdin
    if args.stdin:
        in_data = sys.stdin.read().split("\n")
        handle_ip(actapi, cn_map, in_data, db_cache, args.proxy_string,
                  args.output_format)

    # Bulk lookup
    elif args.bulk:
        all_ips = open(args.bulk, "r").readlines()
        batch_size = 50
        i = 0
        while i < len(all_ips):
            handle_ip(actapi, cn_map, (all_ips[i:i + batch_size]), db_cache,
                      args.proxy_string, args.output_format)
            i += batch_size
            time.sleep(1)

    db_cache.close()
Beispiel #4
0
def main() -> None:
    """Main function"""
    # Look for default ini file in "/etc/actworkers.ini" and
    # ~/config/actworkers/actworkers.ini (or replace .config with
    # $XDG_CONFIG_DIR if set)
    args = parseargs()

    try:
        shorteners = [x.strip() for x in args.url_shorteners.split(",")]
    except AttributeError:
        worker.fatal("Empty list of shorteners?")

    actapi = worker.init_act(args)

    proxies = {
        'http': args.proxy_string,
        'https': args.proxy_string
    } if args.proxy_string else None

    process(actapi, shorteners, args.user_agent, proxies, args.output_format)
Beispiel #5
0
def main() -> None:
    """main function"""

    # Look for default ini file in "/etc/actworkers.ini" and ~/config/actworkers/actworkers.ini
    # (or replace .config with $XDG_CONFIG_DIR if set)
    args = worker.handle_args(parseargs())
    actapi = worker.init_act(args)

    if not args.country_codes:
        worker.fatal(
            "You must specify --country-codes on command line or in config file"
        )

    if not args.veris_prefix:
        worker.fatal("You must specify --veris-prefix")

    if not (args.veris_url or args.veris_file or args.stdin):
        worker.fatal("You must specify --veris-url, --veris-file or --stdin")

    args.veris_prefix = args.veris_prefix.upper()

    if not os.path.isfile(args.country_codes):
        worker.fatal(
            "Country/region file not found at specified location: {}".format(
                args.country_codes), 2)

    args.threat_actor_variety = [
        variety.strip() for variety in args.threat_actor_variety.split(",")
    ]

    # Configuration object that will be passed around to functions
    config = {
        # act API
        "actapi":
        actapi,

        # Map of CC -> Country Name
        "cn_map":
        get_cn_map(args.country_codes),

        # Map of CC -> Country Name
        "campaign_map":
        get_campaigns(args.veris_prefix, args.veris_campaign)
        if args.veris_campaign else {},

        # Cache of url > sha256
        "db_cache":
        urlcache.URLCache(
            requests_common_kwargs={
                "proxies": {
                    'http': args.proxy_string,
                    'https': args.proxy_string
                },
                "timeout": args.http_timeout
            }),
        "proxies": {
            'http': args.proxy_string,
            'https': args.proxy_string
        } if args.proxy_string else None,
    }

    # Add all arguments from args to config
    config.update(vars(args))

    process(config)
Beispiel #6
0
def main() -> None:
    """main function"""

    # Look for default ini file in "/etc/actworkers.ini" and ~/config/actworkers/actworkers.ini
    # (or replace .config with $XDG_CONFIG_DIR if set)
    args = worker.handle_args(parseargs())

    actapi = worker.init_act(args)

    if not (args.privatekey and args.publickey):
        worker.fatal("You must specify --privatekey and --publickey on command line or in config file")

    proxies = {
        'http': args.proxy_string,
        'https': args.proxy_string
    } if args.proxy_string else None

    iSightHandler = ISightAPIRequestHandler(args.root, args.privatekey, args.publickey)
    data = iSightHandler.indicators(days=args.days, proxies=proxies)

    if 'success' not in data or not data['success']:
        logging.error("Unable to download from isight API [%s]", data['message'] if 'message' in data else "NA")
        return

    timestamp = int(time.time())
    ### DEBUG -- dump json to disc for each run
    if args.debugdir:
        with open(os.path.join(args.debugdir, "error-{0}.json".format(timestamp)), "w") as f:
            json.dump(data, f)

    for i, dp in enumerate(data['message']):
        ### --- Handle mentions facts
        # Create report ID from the url (same approach as for feeds) and title to this ID.
        reportID = hashlib.sha256(dp['webLink'].encode('utf8')).hexdigest()
        handle_fact(actapi.fact('name', dp['title']).source('report', reportID))
        for obj in OBJECT_MAP:  # run through all fields that we want to mention
            if obj in dp and dp[obj]:  # if the report contains data in the field
                factType = OBJECT_MAP[obj](dp[obj])  # translate to ACT fact type
                handle_fact(actapi.fact('mentions')  # and create fact from field
                            .source('report', reportID)
                            .destination(factType, dp[obj].lower()))
        if dp['url']:
            handle_fact(actapi.fact('mentions')
                        .source('report', reportID)
                        .destination('uri', dp['url']))
            try:
                handle_uri(actapi, dp['url'])
            except act.api.base.ValidationError as err:
                logging.error("%s while storing url from mentions [%s]", err, dp['url'])
        ### --- IP -> malwareFamily
        if dp['malwareFamily'] and dp['ip']:
            chain = act.api.fact.fact_chain(
                actapi.fact('connectsTo')
                .source('content', '*')
                .destination('uri', '*'),
                actapi.fact('componentOf')
                .source('ipv4', dp['ip'])
                .destination('uri', '*'),
                actapi.fact('classifiedAs')
                .source('content', '*')
                .destination('tool', dp['malwareFamily'].lower()))
            for fact in chain:
                handle_fact(fact)
        ### --- URL -> malwareFamily
        elif dp['networkType'] == 'url' and dp['malwareFamily']:
            try:
                handle_uri(actapi, dp['url'])
            except act.api.base.ValidationError as err:
                logging.error("%s while storing url from mentions [%s]", err, dp['url'])

            chain = act.api.fact.fact_chain(
                actapi.fact('connectsTo')
                .source('content', '*')
                .destination('uri', dp['url']),
                actapi.fact('classifiedAs')
                .source('content', '*')
                .destination('tool', dp['malwareFamily'].lower()))
            for fact in chain:
                handle_fact(fact)
        ### --- FQDN -> malwareFamily
        elif dp['networkType'] == 'network' and dp['domain'] and dp['malwareFamily']:
            chain = act.api.fact.fact_chain(
                actapi.fact('connectsTo')
                .source('content', '*')
                .destination('uri', '*'),
                actapi.fact('componentOf')
                .source('fqdn', dp['domain'])
                .destination('uri', '*'),
                actapi.fact('classifiedAs')
                .source('content', '*')
                .destination('tool', dp['malwareFamily'].lower()))
            for fact in chain:
                handle_fact(fact)
        ### --- hash -> malwareFamily
        elif dp['fileType'] and dp['malwareFamily'] and (dp['sha1'] or dp['sha256'] or dp['md5']):
            for digest_type in ['md5', 'sha1', 'sha256']:
                ### In some cases the iSight api does not return a sha256 hashdigest
                ### so we need to make a chain through a placeholder content
                if not dp['sha256']:
                    if dp[digest_type]:
                        chain = act.api.fact.fact_chain(
                            actapi.fact('represents')
                            .source('hash', dp[digest_type])
                            .destination('content', '*'),
                            actapi.fact('classifiedAs')
                            .source('content', '*')
                            .destination('tool', dp['malwareFamily']))
                        for fact in chain:
                            handle_fact(fact)
                else:  ## There is a sha256, so we do _not_ need a chain
                    if dp[digest_type]:
                        handle_fact(actapi.fact('classifiedAs')
                                    .source('content', dp['sha256'])
                                    .destination('tool', dp['malwareFamily']))
                        handle_fact(actapi.fact('represents')
                                    .source('hash', dp[digest_type])
                                    .destination('content', dp['sha256']))
        ### -- Hash --> actor
        elif dp['fileType'] and dp['actor'] and (dp['sha1'] or dp['sha256'] or dp['md5']):
            for digest_type in ['md5', 'sha1', 'sha256']:
                ### In some cases the iSight api does not return a sha256 hashdigest
                ### so we need to make a chain through a placeholder content
                if not dp['sha256']:
                    if dp[digest_type]:
                        chain = act.api.fact.fact_chain(
                            actapi.fact('represents')
                            .source('hash', dp[digest_type])
                            .destination('content', '*'),
                            actapi.fact('observedIn')
                            .source('content', '*')
                            .destination('event', '*'),
                            actapi.fact('attributedTo')
                            .source('event', '*')
                            .destination('incident', '*'),
                            actapi.fact('attributedTo')
                            .source('incident', '*')
                            .destination('threatActor', dp['actor']))
                        for fact in chain:
                            handle_fact(fact)
                else:  ## There is a sha256, so we do _not_ need a chain between all the way from hexdigest
                    if dp[digest_type]:
                        handle_fact(actapi.fact('represents')
                                    .source('hash', dp[digest_type])
                                    .destination('content', dp['sha256']))
                        chain = act.api.fact.fact_chain(
                            actapi.fact('observedIn')
                            .source('content', dp['sha256'])
                            .destination('event', '*'),
                            actapi.fact('attributedTo')
                            .source('event', '*')
                            .destination('incident', '*'),
                            actapi.fact('attributedTo')
                            .source('incident', '*')
                            .destination('threatActor', dp['actor']))
                        for fact in chain:
                            handle_fact(fact)
        ### We do have a sha256 of a file (but possibly nothing else). Add the content to hexdigest facts
        elif dp['fileType'] and dp['sha256']:
            for digest in ['sha1', 'md5', 'sha256']:
                if dp[digest]:
                    handle_fact(actapi.fact('represents')
                                .source('hash', dp[digest])
                                .destination('content', dp['sha256']))
            if args.debugdir:
                fields = [k for k, v in dp.items() if v and k not in ['reportId', 'title', 'ThreatScape',
                                                                      'audience', 'intelligenceType',
                                                                      'publishDate', 'reportLink', 'webLink']]
                logging.error("[%s] Extra fields while handeling index[%s] '%s'", timestamp, i, ", ".join(fields))


        ### -- DEBUG!
        else:
            if args.debugdir:
                fields = [k for k, v in dp.items() if v and k not in ['reportId', 'title', 'ThreatScape',
                                                                      'audience', 'intelligenceType',
                                                                      'publishDate', 'reportLink', 'webLink']]
                logging.error("[%s] Unable to handle index[%s] with fields '%s'", timestamp, i, ", ".join(fields))