C2sec irisk

Understand Your Cyber Exposure as Easy as a Google Search.

Data Enrichment & Threat Intelligence · C2sec irisk

Details

IDC2sec irisk
ProviderC2Sec
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Use the C2sec irisk integration to scan domains and return scan results.

C2sec irisk Playbooks

  • C2SEC-Domain Scan - scans domains and waits for the full response from the C2sec irisk service.

Configure C2sec irisk on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for C2sec irisk.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • API URL (e.g. https://api.c2sec.com/api)
    • API Key
    • Default domain name
    • Trust any certificate (not secure)
    • Use system proxy settings
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.

  1. Add a domain to a portfolio: irisk-add-domain
  2. Get the status of a scan: irisk-get-scan-status
  3. Re-scan a domain: irisk-rescan-domain
  4. Get the issues for a domain: irisk-get-domain-issues
  5. Get the results of a scan: irisk-get-scan-results

1. Add a domain to a portfolio


Adds a domain to a portfolio.

Base Command

irisk-add-domain

Input
Argument Name Description Required
domain Domain to add to the portfolio. If empty, the default domain will be used. Optional
newscan Flag to indicate whether a new scan is always initiated for the specified domain. Required

 

Context Output
Path Type Description
C2Sec.Domain.result string Result status of adding the new company.
C2Sec.Domain.Name string The name of the searched domain.

 

Command Example
!irisk-add-domain newscan=false domain=demisto.com
Human Readable Output

image

2. Get the status of a scan


Queries the status of a scan.

Base Command

irisk-get-scan-status

Input
Argument Name Description Required
id Domain workitemid for which to check the status. Required

 

Context Output
Path Type Description
C2sec.Domain.Scan.domain string The name of the scanned domain.
C2sec.Domain.Scan.workitemid number The ID of the current scan.
C2sec.Domain.Scan.completeTime date The time that the scan was completed.
C2sec.Domain.Scan.creationTime date The time that the scan was initiated.
C2sec.Domain.Scan.status number The status of the current scan (“processing”/“completed”).

 

Command Example
!irisk-get-scan-status id=1247
Human Readable Output

image

3. Re-scan a domain


Initiates a re-scan for a domain within a portfolio.

Base Command

irisk-rescan-domain

Input
Argument Name Description Required
domain Domain to re-scan. If empty, the default domain will be used. Optional

 

Context Output
Path Type Description
C2sec.Domain.Scan.domain string The name of the scanned domain.
C2sec.Domain.Scan.workitemid number Scan ID.
C2sec.Domain.Scan.result string The scan result status.

 

Command Example
!irisk-rescan-domain domain=demisto.com
Human Readable Output

image

4. Get the issues for a domain


Returns the issues located under the specified domain.

Base Command

irisk-get-domain-issues

Input
Argument Name Description Required
domain The domain to query. If empty, the default domain it will be used. Optional
severity Filter query results by issue severity… Optional

 

Context Output
Path Type Description
C2sec.Domain.Name string The name of the domain against which it was checked.
C2sec.Domain.Issue.ID string Issue ID.
C2sec.Domain.Issue.Asset string Asset associated with the issues. For example, IP addresses, website URLs, and so on.
C2sec.Domain.Issue.Component string The component used in the issue.
C2sec.Domain.Issue.ComponentDisplay string The display name of the component being used.
C2sec.Domain.Issue.Details string The details for the issue.
C2sec.Domain.Issue.Issue string The name of the issue.
C2sec.Domain.Issue.Severity string The severity of the issue.

 

Command Example
!irisk-get-domain-issues domain=google.com
Human Readable Output

image

5. Get the results of a scan


Queries data for a specific component for companies in the portfolio.

Base Command

irisk-get-scan-results

Input
Argument Name Description Required
domain The domain to query. If empty, default domain will be used. Required
component The component to query. Required

 

Context Output
Path Type Description
C2sec.Domain.application.result string Query status.
C2sec.Domain.application.Domain string The domain name being queried.
C2sec.Domain.application.data.appdetail string Details about the application being checked.
C2sec.Domain.application.data.info string Information regarding the data being processed.
C2sec.Domain.application.data.website string Website address being processed.
C2sec.Domain.credential.result string Query status.
C2sec.Domain.credential.Domain string The domain name being queried.
C2sec.Domain.credential.data.user string User name.
C2sec.Domain.credential.data.pw string User password.
C2sec.Domain.network.result string Query status.
C2sec.Domain.network.Domain string The domain name being queried.
C2sec.Domain.network.data.firewall string Firewall status.
C2sec.Domain.network.data.port string Port number.
C2sec.Domain.network.data.IP string IP address.
C2sec.Domain.network.data.Name string Name of the user.
C2sec.Domain.network.data.service string Name of the service being used.
C2sec.Domain.network.data.protocol string Name of the protocol being used.
C2sec.Domain.network.data.state string State of the network application (“open” or “closed”).

 

Command Example
!irisk-get-scan-results component=application domain=demisto.com
Human Readable Output

image

Configuration parameters

  • endpointURL — API URL (e.g. https://api.c2sec.com/api) (required)
  • apikey — API Key
  • apikey_creds
  • domainName — Default domain name (required)
  • unsecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (5)

  • irisk-add-domain

    Adds a domain to portfolio.

  • irisk-get-domain-issues

    Returns the issues located under the specified domain.

  • irisk-get-scan-results

    Query Data for specific component for companies in the portfolio

  • irisk-get-scan-status

    Queries the status of a scan.

  • irisk-rescan-domain

    Initiates a re-scan for a domain within a portfolio.

import demistomock as demisto
from CommonServerPython import *

from CommonServerUserPython import *

""" IMPORTS """

import requests
import urllib3

# disable insecure warnings
urllib3.disable_warnings()

API_KEY = demisto.params().get("apikey_creds", {}).get("password") or demisto.params().get("apikey")
HEADERS = {"Content-Type": "application/json", "Accept": "application/json"}

DOMAIN = demisto.params()["domainName"]
if demisto.params()["endpointURL"].count("/") == 3:
    ENDPOINTURL = demisto.params()["endpointURL"] + "/"
else:
    ENDPOINTURL = demisto.params()["endpointURL"]

USE_SSL = not demisto.params().get("unsecure", False)


def add_domain(domain, newscan):
    if newscan == "true":
        newscan = 1
    else:
        newscan = 0

    params = {"apikey": API_KEY, "domain": domain, "newscan": newscan}
    call = requests.get(ENDPOINTURL + "/iriskaddcompany", headers=HEADERS, verify=USE_SSL, params=params)

    if call.status_code == requests.codes.ok:
        result_dictionary = {"result": call.json()["result"], "Name": domain}

        md = tableToMarkdown("Add domain Result", result_dictionary)
        return {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": call.json(),
            "HumanReadable": md,
            "EntryContext": {"C2sec.Domain(val.Name && val.Name == obj.Name)": result_dictionary},
        }
    else:
        return f"Error searching domain - status code: [{call.status_code}] - reason: {call.text}"


def get_scan_status(workitemid):
    params = {"apikey": API_KEY, "workitemid": workitemid}
    call = requests.get(ENDPOINTURL + "/iriskqueryapistatus", headers=HEADERS, verify=USE_SSL, params=params)
    if call.status_code == requests.codes.ok:
        resp = call.json()
        resp["apistatus"]["workitemid"] = workitemid
        md = tableToMarkdown("Get scan Result", resp["apistatus"], removeNull=True)
        return {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": resp,
            "HumanReadable": md,
            "EntryContext": {"C2sec.Domain.Scan(val.workitemid && val.workitemid == obj.workitemid)": resp["apistatus"]},
        }
    else:
        return f"Error getting scan results [{call.status_code}] - reason: {call.text}"


def get_domain_issues(domain, severity=None):
    params = {"apikey": API_KEY, "domain": domain}
    call = requests.get(ENDPOINTURL + "/iRiskQueryIssues", headers=HEADERS, verify=USE_SSL, params=params)
    if call.status_code == requests.codes.ok:
        contexts = []
        for issue in call.json().get("issueList", []):
            if severity and severity != issue["severity"]:
                continue

            context = {
                "ID": issue["id"],
                "Issue": issue["issue"],
                "Severity": issue["severity"],
                "Component": issue["component"],
                "ComponentDisplay": issue["componentDisplay"],
                "Details": issue["detail"],
                "Asset": issue["asset"],
                "Rec": issue["rec"],
            }
            contexts.append(context)

        md = tableToMarkdown(
            "Get domain Issues Result",
            contexts,
            ["ID", "Issue", "Severity", "Component", "ComponentDisplay", "Details", "Asset", "Rec"],
        )
        return {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": call.json(),
            "HumanReadable": md,
            "EntryContext": {"C2sec.Domain(val.Name && val.Name == obj.Name)": {"Name": domain, "Issue": contexts}},
        }
    else:
        return f"Error getting issues [{call.status_code}] - reason: {call.text}"


def rescan_domain(domain):
    params = {"apikey": API_KEY, "domain": domain}
    call = requests.get(ENDPOINTURL + "/iRiskRescanCompany", headers=HEADERS, verify=USE_SSL, params=params)
    if call.status_code == requests.codes.ok:
        md = tableToMarkdown("Rescan domain Results", call.json())
        context = call.json()
        context["domain"] = domain

        return {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": call.json(),
            "HumanReadable": md,
            "EntryContext": {"C2sec.Domain.Scan(val.workitemid && val.workitemid == obj.workitemid)": context},
        }
    else:
        return f"Error rescanning the domain [{call.status_code}] - reason: {call.text}"


def get_scan_results(domain, component):
    params = {"apikey": API_KEY, "domain": domain, "component": component}
    call = requests.get(ENDPOINTURL + "/iRiskQueryComponentData", headers=HEADERS, verify=USE_SSL, params=params)

    if call.status_code == requests.codes.ok:
        resp = call.json()

        resp["Domain"] = domain
        md = tableToMarkdown(
            "Get Scan Result", resp, ["result", "Domain", "component"], metadata="The results can be found in the context"
        )

        return {
            "Type": entryTypes["note"],
            "ContentsFormat": formats["json"],
            "Contents": call.json(),
            "HumanReadable": md,
            "EntryContext": {f"C2sec.Domain.{component}(val.Domain && val.Domain == obj.Domain)": resp},
        }
    else:
        return_error(f"Error getting the scan results [{call.status_code}] - reason: {call.text}")  # noqa: RET503


LOG(f"Command being called is {demisto.command()}")
try:
    handle_proxy()
    # The command demisto.command() holds the command sent from the user.
    if demisto.command() == "test-module":
        # This is the call made when pressing the integration test button.
        test = add_domain(demisto.params()["domainName"], newscan="false")
        if (
            isinstance(test, dict)
            and "HTTPSConnectionPool" not in test
            and "error" not in test.get("Contents", {}).get("result", "")
        ):
            demisto.results("ok")
        else:
            demisto.results(test)
    elif demisto.command() == "irisk-add-domain":
        result = add_domain(demisto.args().get("domain", DOMAIN), demisto.args()["newscan"])
        demisto.results(result)
    elif demisto.command() == "irisk-get-scan-status":
        result = get_scan_status(demisto.args()["id"])
        demisto.results(result)
    elif demisto.command() == "irisk-rescan-domain":
        result = rescan_domain(demisto.args().get("domain", DOMAIN))
        demisto.results(result)
    elif demisto.command() == "irisk-get-domain-issues":
        result = get_domain_issues(demisto.args().get("domain", DOMAIN), demisto.args().get("severity"))
        demisto.results(result)
    elif demisto.command() == "irisk-get-scan-results":
        domain = demisto.args().get("domain", DOMAIN)
        result = get_scan_results(domain, demisto.args()["component"])
        demisto.results(result)

# Log exceptions
except Exception as e:
    return_error(str(e))