コード例 #1
0
ファイル: vt.py プロジェクト: FredrikMS/act-workers
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 = cli.handle_args(parseargs())

    actapi = worker.init_act(args)

    if not args.apikey:
        cli.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)

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

    elif args.domain:
        handle_domain(actapi, vtapi, in_data, output_format=args.output_format)

    else:  # Type not specified, autodetect
        handle_ioc(actapi, vtapi, in_data, output_format=args.output_format)
コード例 #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 = cli.handle_args(parseargs())

    actapi = worker.init_act(args)

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

    if not os.path.isfile(args.country_codes):
        cli.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()
コード例 #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 = cli.handle_args(parseargs())

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

    actapi = worker.init_act(args)
    process(actapi, args)
コード例 #4
0
ファイル: veris.py プロジェクト: FredrikMS/act-workers
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 = cli.handle_args(parseargs())
    actapi = worker.init_act(args)

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

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

    if not (args.veris_url or args.veris_file or args.stdin):
        cli.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):
        cli.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)
コード例 #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 = parseargs()

    try:
        shorteners = [x.strip() for x in args.url_shorteners.split(",")]
    except AttributeError:
        cli.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)
コード例 #6
0
def main() -> None:
    """program entry point"""

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

    if not args.feed_uri:
        cli.fatal("--feed-uri not specified")

    if args.dump_dir and not args.dump_dir.is_dir():
        os.makedirs(args.dump_dir)

    proxies = ({
        "http": args.proxy_string,
        "https": args.proxy_string
    } if args.proxy_string else None)

    actapi = worker.init_act(args)

    try:
        # Get "updated" from last successful run
        last_run_filename = get_last_run_filename(args.feed_cache,
                                                  args.feed_uri)

        with pid.PidFile(force_tmpdir=True, pidname="act_feed.pid"):
            handle_feed(
                last_run_filename,
                args.feed_uri,
                actapi,
                args.dump_dir,
                proxies,
                args.cert_file,
                args.no_exit_on_error,
            )

    except pid.base.PidFileAlreadyLockedError:
        error("pid file found - feed is already running")
コード例 #7
0
def run() -> None:
    args = cli.handle_args(parseargs())
    actapi = worker.init_act(args)

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

    proxies = ({
        "http": args.proxy_string,
        "https": args.proxy_string
    } if args.proxy_string else None)

    for in_data in sys.stdin:
        in_data = in_data.strip()

        if args.hexdigest or HASH_RE.search(in_data):
            handle_hexdigest(
                actapi,
                in_data,
                args.apikey,
                args.secret,
                proxies,
                output_format=args.output_format,
            )

        elif args.domain:
            handle_domain(
                actapi,
                in_data,
                args.apikey,
                args.secret,
                proxies,
                output_format=args.output_format,
            )
コード例 #8
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 = cli.handle_args(parseargs())

    actapi = worker.init_act(args)

    if not (args.privatekey and args.publickey):
        cli.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"])
            )
            handle_uri(actapi, dp["url"])
        ### --- IP -> malwareFamily
        if dp["malwareFamily"] and dp["ip"]:
            handle_facts(
                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"]),
                )
            )
        ### --- URL -> malwareFamily
        elif dp["networkType"] == "url" and dp["malwareFamily"]:
            handle_uri(actapi, dp["url"])
            handle_facts(
                act.api.fact.fact_chain(
                    actapi.fact("connectsTo")
                    .source("content", "*")
                    .destination("uri", dp["url"]),
                    actapi.fact("classifiedAs")
                    .source("content", "*")
                    .destination("tool", dp["malwareFamily"]),
                )
            )
        ### --- FQDN -> malwareFamily
        elif dp["networkType"] == "network" and dp["domain"] and dp["malwareFamily"]:
            handle_facts(
                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"]),
                )
            )
        ### --- 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]:
                        handle_facts(
                            act.api.fact.fact_chain(
                                actapi.fact("represents")
                                .source("hash", dp[digest_type])
                                .destination("content", "*"),
                                actapi.fact("classifiedAs")
                                .source("content", "*")
                                .destination("tool", dp["malwareFamily"]),
                            )
                        )
                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]:
                        handle_facts(
                            act.api.fact.fact_chain(
                                actapi.fact("represents")
                                .source("hash", dp[digest_type])
                                .destination("content", "*"),
                                actapi.fact("observedIn")
                                .source("content", "*")
                                .destination("incident", "*"),
                                actapi.fact("attributedTo")
                                .source("incident", "*")
                                .destination("threatActor", dp["actor"]),
                            )
                        )
                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"])
                        )

                        handle_facts(
                            act.api.fact.fact_chain(
                                actapi.fact("observedIn")
                                .source("content", dp["sha256"])
                                .destination("incident", "*"),
                                actapi.fact("attributedTo")
                                .source("incident", "*")
                                .destination("threatActor", dp["actor"]),
                            )
                        )
        ### 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),
                )