USTA

USTA is an Cyber Intelligence Platform that responds directly and effectively to today's complex cyber threats.

Data Enrichment & Threat Intelligence · USTA

Details

IDUSTA
ProviderPRODAFT
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/python3:3.12.8.3296088
Supported ModulesAgentix XSIAM

README

USTA is an Cyber Intelligence Platform that responds directly and effectively to today’s complex cyber threats.

Configure USTA in Cortex

Parameter Description Required
Server URL (e.g. https://usta.prodaft.com)   True
API Key You can reach out your access token : https://usta.prodaft.com/#/api-documents True
Trust any certificate (not secure)   False
Use system proxy settings   False

Commands

You can execute these commands from the 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.

usta-get-malicious-urls


You can get malicious URLs with this command

Base Command

usta-get-malicious-urls

Input

Argument Name Description Required
format Format type of the returned result. Possible values are: json, stix, stix2, txt. Default is json. Optional
url Filtering by URL Address. Optional
is_domain You can search only those with or without domain name registration. Possible values are: true, false. Default is true. Optional
url_type Filtering by malicious type. Optional
tag Filtering by tags. Example: tag=Keitaro. Optional
start Starting date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). Optional
end End Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). Optional

Context Output

Path Type Description
Usta.MaliciousUrl.country unknown Country
Usta.MaliciousUrl.created unknown Created Date
Usta.MaliciousUrl.domain unknown Domain
Usta.MaliciousUrl.ip_addresses unknown IP Addresses
Usta.MaliciousUrl.is_domain unknown Is Domain
Usta.MaliciousUrl.modified unknown Modified Date
Usta.MaliciousUrl.tags unknown Tags
Usta.MaliciousUrl.threat_type unknown Threat Type
Usta.MaliciousUrl.url unknown URL

Command Example


#### Human Readable Output

### usta-get-malware-hashs

***
You can get malware hashs with this command

#### Base Command

`usta-get-malware-hashs`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| format | Format type of the returned result. Possible values are: json, stix, stix2. Default is json. | Optional |
| md5 | Filtering by md5. | Optional |
| sha1 | Filtering by sha1. | Optional |
| tag | Filtering by tags. Example: tag=Keitaro. | Optional |
| start | Starting Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). | Optional |
| end | End Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Usta.MalwareHash.created | unknown | Created Date |
| Usta.MalwareHash.md5 | unknown | MD5 |
| Usta.MalwareHash.sha1 | unknown | SHA1 |
| Usta.MalwareHash.tags | unknown | Tags |
| Usta.MalwareHash.yara_rule | unknown | Yara Rule |

#### Command Example

Human Readable Output

usta-get-phishing-sites


You can get phishing sites with this command

Base Command

usta-get-phishing-sites

Input

Argument Name Description Required
status Filtering by status. Possible values are: open, close, in_progress, out_of_scope, passive. Optional
source Filtering by source(URL). Optional
page Paginiation. Optional

Context Output

Path Type Description
Usta.PhishingSites.current_page unknown Current page
Usta.PhishingSites.last_page unknown Last page
Usta.PhishingSites.next_page_url unknown Next page URL
Usta.PhishingSites.per_page unknown Content count per page
Usta.PhishingSites.prev_page_url unknown Prev page URL
Usta.PhishingSites.results unknown Results
Usta.PhishingSites.total unknown Content count
Usta.PhishingSites.total_pages unknown Total Page

Command Example


#### Human Readable Output

### usta-get-identity-leaks

***
With the Identity Leak API, you can access the hashed version of the credentials added to the platform.SHA256(MD5(Identity_Number))

#### Base Command

`usta-get-identity-leaks`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| start | Staring Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). | Optional |
| end | End Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Usta.IdentityLeaks.created | unknown | Created date |
| Usta.IdentityLeaks. signature | unknown | Signature |

#### Command Example

Human Readable Output

usta-get-stolen-client-accounts


You can access stolen customer accounts via Stolen-Client-accounts API.

Base Command

usta-get-stolen-client-accounts

Input

Argument Name Description Required
username Filtering by username. Optional
password Filtering by password. Optional
source It allows to filter the stolen customer accounts detected according to the source.Available values : malware, phishing_site, data_leak, clients. Possible values are: malware, phishing_site, data_leak, clients. Optional
start Starting Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). Optional
end End Date(Example: 2021-03-18-13-59 / yy-mm-dd-hh-mm). Optional

Context Output

Path Type Description
Usta.StolenClientAccounts.created unknown Created date
Usta.StolenClientAccounts.password unknown Password
Usta.StolenClientAccounts.source unknown Source
Usta.StolenClientAccounts.url unknown URL
Usta.StolenClientAccounts.username unknown Username

Command Example


#### Human Readable Output

### usta-get-domain

***
If you want to get more detailed information about malicious domain names, you can use this command.

#### Base Command

`usta-get-domain`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| domain | Search with domain name. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Usta.Domain.asn_records | unknown | ASN records |
| Usta.Domain.country | unknown | Country |
| Usta.Domain.dns_records | unknown | DNS records |
| Usta.Domain.domain | unknown | Domain |
| Usta.Domain.ip_addresses | unknown | IP addresses |
| Usta.Domain.ssl_records | unknown | SSL records |
| Usta.Domain.whois_records | unknown | Whois records |

#### Command Example

Human Readable Output

usta-get-ip-address


If you want to get more detailed information about specific IP Address, you can use this command.

Base Command

usta-get-ip-address

Input

Argument Name Description Required
ip_address Search with IP Address. Optional

Context Output

Path Type Description
Usta.IPAddress.asn_records unknown ASN records
Usta.IPAddress.country unknown Country
Usta.IPAddress.ip_address unknown IP address
Usta.IPAddress.ssl_records unknown SSL records
Usta.IPAddress.whois_records unknown Whois records

Command Example


#### Human Readable Output

### usta-send-referrer-url

***
You can search about the accuracy of the urls referring to your company's websites.

#### Base Command

`usta-send-referrer-url`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| address | URL Value. Example: http://www.google3.com. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Usta.Referrer.error | unknown | If any errors are received, it gives the details of the error |

#### Command Example

Human Readable Output

usta-search-specific-identity-leaks


With this command, you can search specific identity number that hashed in leaks

Base Command

usta-search-specific-identity-leaks

Input

Argument Name Description Required
identity_number Search with this identity number. You can search all identity number with “,” . Required

Context Output

Path Type Description
Usta.SpecificLeaks.existing unknown If the identity is leaked, you can see it in existing.
Usta.SpecificLeaks.not_existing unknown If the identity is not leaked, you can see it in not_existing

Command Example


#### Human Readable Output

### usta-close-incident

***
You can close the notifications in the status of "In Progress" or "Open", which are currently opened to your institution, via API.

#### Base Command

`usta-close-incident`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| id | Incident ID. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Usta.CloseIncident.id | unknown | If the incident is closed, returns the id value that was closed. |

#### Command Example

Human Readable Output

Configuration parameters

  • url — Server URL (e.g. https://usta.prodaft.com) (required)
  • apikey — API Key (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (10)

  • usta-close-incident

    You can close the notifications in the status of "In Progress" or "Open", which are currently opened to your institution, via API.

  • usta-get-domain

    If you want to get more detailed information about malicious domain names, you can use this command.

  • usta-get-identity-leaks

    With the Identity Leak API, you can access the hashed version of the credentials added to the platform.SHA256(MD5(Identity_Number))

  • usta-get-ip-address

    If you want to get more detailed information about specific IP Address, you can use this command.

  • usta-get-malicious-urls

    You can get malicious URLs with this command

  • usta-get-malware-hashs

    You can get malware hashs with this command

  • usta-get-phishing-sites

    You can get phishing sites with this command

  • usta-get-stolen-client-accounts

    You can access stolen customer accounts via Stolen-Client-accounts API.

  • usta-search-specific-identity-leaks

    With this command, you can search specific identity number that hashed in leaks

  • usta-send-referrer-url

    You can search about the accuracy of the urls referring to your company's websites.

import hashlib
import json
import traceback

import demistomock as demisto  # noqa: F401
import requests
import urllib3
from CommonServerPython import *  # noqa: F401

# disable insecure warnings
urllib3.disable_warnings()

""" GLOBAL VARIABLES"""
VERIFY_SSL = not demisto.params().get("insecure", False)

DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
handle_proxy()


def test_module() -> str:
    """Tests API connectivity and authentication'
    Returning 'ok' indicates that the integration works like it is supposed to.
    Connection to the service is successful.
    Raises exceptions if something goes wrong.
    :return: 'ok' if test passed, anything else will fail the test.
    :rtype: ``str``
    """

    try:
        url = demisto.params().get("url")[:-1] if str(demisto.params().get("url")).endswith("/") else demisto.params().get("url")
        CREDENTIALS = demisto.params().get("apikey")
        # AUTH_HEADERS = {'Content-Type': 'application/json'}

        params = "TOKEN " + CREDENTIALS
        headers = {"Authorization": params, "Content-Type": "application/json"}

        base_url = urljoin(url, "/api")
        endpoint = "/threat-stream/malicious-urls?format=json"

        url = urljoin(base_url, endpoint)
        req = requests.get(url, headers=headers, verify=VERIFY_SSL)
        status = req.status_code
        if status != 200:
            return str(status)
    except Exception as e:
        if "Forbidden" in str(e):
            return "Authorization Error: make sure API Key is correctly set"
        else:
            raise e
    return "ok"


class Client(BaseClient):
    """Client class to interact with the service API

    This Client implements API calls, and does not contain any SOAR logic.
    Should only do requests and return data.
    It inherits from BaseClient defined in CommonServer Python.
    Most calls use _http_request() that handles proxy, SSL verification, etc.
    For this HelloWorld implementation, no special attributes defined
    """

    def get_malicious_url(self, param: dict) -> Dict[str, Any]:
        """Gets the Malicious url using the '/threat-stream/malicious-urls' API endpoint

        :return: dict containing the Malicious URL details as returned from the API
        :rtype: ``Dict[str, Any]``
        """
        return self._http_request(method="GET", url_suffix="/threat-stream/malicious-urls", params=param)

    def get_malware_hash(self, param: dict) -> Dict[str, Any]:
        """Gets the Malicious hashs using the '/threat-stream/malware-hashs' API endpoint

        :return: dict containing the Malicious Hash details as returned from the API
        :rtype: ``Dict[str, Any]``
        """
        return self._http_request(method="GET", url_suffix="/threat-stream/malware-hashs", params=param)

    def get_phishing_sites(self, param: dict) -> Dict[str, Any]:
        """Available for all Phishing Sites created for your company that using the '/threat-stream/phishing-sites' API endpoint

        :return: dict containing the Phishing Site details as returned from the API
        :rtype: ``Dict[str, Any]``
        """
        return self._http_request(method="GET", url_suffix="/threat-stream/phishing-sites", params=param)

    def get_identity_leaks(self, param: dict) -> Dict[str, Any]:
        """Gets the Leaked Accounts related your company using the '/threat-stream/identity-leaks' API endpoint

        :return: dict containing the Account details as returned from the API
        :rtype: ``Dict[str, Any]``
        """
        return self._http_request(method="GET", url_suffix="/threat-stream/identity-leaks", params=param)

    def get_stolen_client_accounts(self, param: dict) -> Dict[str, Any]:
        """Gets the Stolen Client Accounts related any service using the '/threat-stream/stolen-client-accounts' API endpoint

        :return: dict containing the Accounts details as returned from the API
        :rtype: ``Dict[str, Any]``
        """
        return self._http_request(method="GET", url_suffix="/threat-stream/stolen-client-accounts", params=param)

    def get_domain(self, param: dict) -> Dict[str, Any]:
        """Gets the Domain details using the '/threat-stream/domain' API endpoint

        :return: dict containing the Domain details as returned from the API
        :rtype: ``Dict[str, Any]``
        """

        return self._http_request(method="POST", url_suffix="/threat-stream/domain", json_data=param)

    def get_ip_address(self, param: dict) -> Dict[str, Any]:
        """Gets the IP details using the '/threat-stream/ip-address' API endpoint

        :return: dict containing the IP details as returned from the API
        :rtype: ``Dict[str, Any]``
        """

        return self._http_request(method="POST", url_suffix="/threat-stream/ip-address", json_data=param)


def search_malicious_urls(client: Client, args: Dict[str, Any]) -> CommandResults:
    """Gets the Malicious url using the '/threat-stream/malicious-urls' API endpoint

    :type format: ``str``
    :param - format: It determines the data type of the response that will return via API.
    :Available values : json, stix, stix2, txt. Default value : json

    :type url: ``str``
    :param - url: For filtering with URL

    :type is_domain: ``boolean``
    :param - is_domain: Provides filtering for data with or without domain names

    :type url_type: ``str``
    :param - url_type: For filtering with URL Type.
    :Available values : Phishing, C2, Downloader

    :type tag: ``str``
    :param - tag: For filtering with tags

    :type start: ``str``
    :param - start: Starting parameter for analysis

    :type end: ``str``
    :param - end: End parameter for analysis
    """
    url = args.get("url")
    is_domain = args.get("is_domain")
    url_type = args.get("url_type")
    tag = args.get("tag")
    start = args.get("start")
    end = args.get("end")
    formatType = args.get("format")

    param = {}

    if start:
        startDate = timeToEpoch(start)
    else:
        startDate = start

    if end:
        endDate = timeToEpoch(end)
    else:
        endDate = end

    param = {
        "url": url,
        "is_domain": is_domain,
        "url_type": url_type,
        "tag": tag,
        "start": startDate,
        "end": endDate,
        "format": formatType,
    }

    maliciousURL = client.get_malicious_url(param=param)

    readable_output = tableToMarkdown("Malicious URL", maliciousURL)

    return CommandResults(
        readable_output=readable_output, outputs_prefix="USTA.Malicious_URL", outputs_key_field="url", outputs=maliciousURL
    )


def search_malware_hashs(client: Client, args: Dict[str, Any]) -> CommandResults:
    """Gets the Malicious hashs using the '/threat-stream/malware-hashs' API endpoint

    :type format: ``str``
    :param - format: It determines the data type of the response that will return via API.
    :Available values : json, stix, stix2, txt. Default value : json

    :type md5: ``str``
    :param - md5: For filtering with md5

    :type sha1: ``boolean``
    :param - sha1: For filtering with sha1.

    :type tag: ``str``
    :param - tag: For filtering with tags

    :type start: ``str``
    :param - start: Starting parameter for analysis

    :type end: ``str``
    :param - end: End parameter for analysis
    """
    md5 = args.get("md5")
    sha1 = args.get("sha1")
    tag = args.get("tag")
    start = args.get("start")
    end = args.get("end")
    formatType = args.get("format")

    if start:
        startDate = timeToEpoch(start)
    else:
        startDate = start

    if end:
        endDate = timeToEpoch(end)
    else:
        endDate = end

    param = {"md5": md5, "sha1": sha1, "tag": tag, "start": startDate, "end": endDate, "format": formatType}

    malwareHash = client.get_malware_hash(param=param)

    readable_output = tableToMarkdown("Malware Hashs", malwareHash)

    return CommandResults(
        readable_output=readable_output, outputs_prefix="USTA.Malware_Hash", outputs_key_field="md5", outputs=malwareHash
    )


def search_phishing_sites(client: Client, args: Dict[str, Any]) -> CommandResults:
    """Available for all Phishing Sites created for your company that using the '/threat-stream/phishing-sites' API endpoint

    :type status: ``str``
    :param - status: For filtering with status
    :Available values : open, close, in_progress, out_of_scope, passive

    :type source: ``str``
    :param - source: For filtering with source

    :type page: ``str``
    :param - page: For pagination
    """
    status = args.get("status")
    source = args.get("source")
    page = args.get("page")

    param = {"status": status, "source": source, "page": page}

    phishingSites = client.get_phishing_sites(param=param)

    readable_output = tableToMarkdown("Phishing Sites", phishingSites)

    return CommandResults(
        readable_output=readable_output, outputs_prefix="USTA.Phishing_Sites", outputs_key_field="results", outputs=phishingSites
    )


def search_identity_leaks(client: Client, args: Dict[str, Any]) -> CommandResults:
    """Gets the Leaked Accounts related your company using the '/threat-stream/identity-leaks' API endpoint

    :type start: ``str``
    :param - start: Starting parameter for analysis

    :type end: ``str``
    :param - end: End parameter for analysis
    """
    start = args.get("start")
    end = args.get("end")

    if start:
        startDate = timeToEpoch(start)
    else:
        startDate = start

    if end:
        endDate = timeToEpoch(end)
    else:
        endDate = end

    param = {"start": startDate, "end": endDate}

    identityLeaks = client.get_identity_leaks(param=param)

    readable_output = tableToMarkdown("Identity Leaks", identityLeaks)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="USTA.Identity_Leaks",
        outputs_key_field="signature",
        outputs=identityLeaks,
    )


def search_stolen_client_accounts(client: Client, args: Dict[str, Any]) -> CommandResults:
    """Gets the Stolen Client Accounts related any service using the '/threat-stream/stolen-client-accounts' API endpoint

    :type username: ``str``
    :param - username: For filtering with username

    :type password: ``boolean``
    :param - password: For filtering with password

    :type source: ``str``
    :param - source: For filtering with source

    :type start: ``str``
    :param - start: Starting parameter for analysis

    :type end: ``str``
    :param - end: End parameter for analysis
    """
    username = args.get("username")
    password = args.get("password")
    source = args.get("source")
    start = args.get("start")
    end = args.get("end")

    if start:
        startDate = timeToEpoch(start)
    else:
        startDate = start

    if end:
        endDate = timeToEpoch(end)
    else:
        endDate = end

    param = {"username": username, "password": password, "source": source, "start": startDate, "end": endDate}

    stolenClientAccounts = client.get_stolen_client_accounts(param=param)

    readable_output = tableToMarkdown("Stolen Client Accounts", stolenClientAccounts)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="USTA.Stolen_Client_Accounts",
        outputs_key_field="username",
        outputs=stolenClientAccounts,
    )


def search_domain(client: Client, args: Dict[str, Any]) -> CommandResults:
    domain = args.get("domain")

    param = {"domain": domain}

    maliciousDomain = client.get_domain(param=param)

    readable_output = tableToMarkdown("Malicious Domain", maliciousDomain)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="USTA.Malicious_Domain",
        outputs_key_field="domain",
        outputs=maliciousDomain,
    )


def search_ip_address(client: Client, args: Dict[str, Any]) -> CommandResults:
    ip_address = args.get("ip_address")

    param = {"ip_address": ip_address}

    maliciousIPAddress = client.get_ip_address(param=param)

    readable_output = tableToMarkdown("Malicious IP Address", maliciousIPAddress)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="USTA.Malicious_IP_Address",
        outputs_key_field="ip_address",
        outputs=maliciousIPAddress,
    )


def send_referrer_url() -> CommandResults:
    url = demisto.params().get("url")[:-1] if str(demisto.params().get("url")).endswith("/") else demisto.params().get("url")
    CREDENTIALS = demisto.params().get("apikey")
    # AUTH_HEADERS = {'Content-Type': 'application/json'}

    params = "TOKEN " + CREDENTIALS
    headers = {"Authorization": params, "Content-Type": "application/json"}

    base_url = urljoin(url, "/api")
    endpoint = "/threat-stream/referrers"

    url = urljoin(base_url, endpoint)

    addresses = [demisto.args().get("address")]

    data = []
    for address in addresses:
        addressParam = {"address": address}
        data.append(addressParam)

    req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL)
    referredResult = json.loads(req.content)

    readable_output = tableToMarkdown("Referred Result", referredResult)

    return CommandResults(readable_output=readable_output, outputs=referredResult)


def search_specific_identity_leaks() -> CommandResults:
    url = demisto.params().get("url")[:-1] if str(demisto.params().get("url")).endswith("/") else demisto.params().get("url")
    CREDENTIALS = demisto.params().get("apikey")
    # AUTH_HEADERS = {'Content-Type': 'application/json'}

    params = "TOKEN " + CREDENTIALS
    headers = {"Authorization": params, "Content-Type": "application/json"}

    base_url = urljoin(url, "/api")
    endpoint = "/threat-stream/identity-leaks"

    url = urljoin(base_url, endpoint)

    identities = demisto.args().get("identity_number")
    identityList = identities.split(",")

    hashedIdentities = encodeData(identityList)

    mappingHashIdentity = []
    for i in range(len(identityList)):
        mappingDict = {"Identity": identityList[i], "Identity Hash": hashedIdentities[i]}
        mappingHashIdentity.append(mappingDict)

    data = {"signatures": hashedIdentities}

    req = requests.patch(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL)
    identityLeaks = json.loads(req.content)

    readable_output = tableToMarkdown("Identity Leaks", identityLeaks)
    readable_output += tableToMarkdown("Identity Hash Mapping", mappingHashIdentity)

    return CommandResults(readable_output=readable_output, outputs=identityLeaks)


def close_incident() -> CommandResults:
    url = demisto.params().get("url")[:-1] if str(demisto.params().get("url")).endswith("/") else demisto.params().get("url")
    CREDENTIALS = demisto.params().get("apikey")
    # AUTH_HEADERS = {'Content-Type': 'application/json'}

    params = "TOKEN " + CREDENTIALS
    headers = {"Authorization": params, "Content-Type": "application/json"}

    base_url = urljoin(url, "/api")
    endpoint = "/threat-stream/close-ticket"

    url = urljoin(base_url, endpoint)

    inc_id = demisto.args().get("id")
    data = {"id": inc_id}

    req = requests.patch(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL)
    closedIncident = json.loads(req.content)

    readable_output = tableToMarkdown("Close Incident", closedIncident)

    return CommandResults(readable_output=readable_output, outputs=closedIncident)


def encodeData(identities: list) -> list:
    hashedList = []
    for identity in identities:
        hashedIdentity = hashlib.sha256((hashlib.md5(identity.encode())).hexdigest().encode()).hexdigest()  # nosec
        hashedList.append(hashedIdentity)
    return hashedList


def timeToEpoch(time: str):
    timeParameterList = time.split("-")
    if len(timeParameterList) != 5:
        error_message = "Time arguments is wrong, be sure to enter as in the example."
        return_error(error_message)  # noqa: RET503
    else:
        epochTime = datetime(
            int(timeParameterList[0]),
            int(timeParameterList[1]),
            int(timeParameterList[2]),
            int(timeParameterList[3]),
            int(timeParameterList[4]),
        ).strftime("%s")
        return epochTime


def main() -> None:
    """main function, parses params and runs command functions
    :return:
    :rtype:
    """
    CREDENTIALS = demisto.params().get("apikey")
    # AUTH_HEADERS = {'Content-Type': 'application/json'}

    # get the service API url
    base_url = urljoin(demisto.params()["url"], "/api")

    # if your Client class inherits from BaseClient, SSL verification is
    # handled out of the box by it, just pass ``verify_certificate`` to
    # the Client constructor
    verify_certificate = not demisto.params().get("insecure", False)

    # if your Client class inherits from BaseClient, system proxy is handled
    # out of the box by it, just pass ``proxy`` to the Client constructor
    proxy = demisto.params().get("proxy", False)

    """ EXECUTION """
    # LOG('command is %s' % (demisto.command(), ))
    demisto.debug(f"Command being called is {demisto.command()}")
    try:
        params = "TOKEN " + CREDENTIALS
        headers = {"Authorization": params, "Content-Type": "application/json"}

        client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy)

        if demisto.command() == "test-module":
            demisto.results(test_module())
        elif demisto.command() == "usta-get-malicious-urls":
            return_results(search_malicious_urls(client, demisto.args()))
        elif demisto.command() == "usta-get-malware-hashs":
            return_results(search_malware_hashs(client, demisto.args()))
        elif demisto.command() == "usta-get-phishing-sites":
            return_results(search_phishing_sites(client, demisto.args()))
        elif demisto.command() == "usta-get-identity-leaks":
            return_results(search_identity_leaks(client, demisto.args()))
        elif demisto.command() == "usta-get-stolen-client-accounts":
            return_results(search_stolen_client_accounts(client, demisto.args()))
        elif demisto.command() == "usta-get-domain":
            return_results(search_domain(client, demisto.args()))
        elif demisto.command() == "usta-get-ip-address":
            return_results(search_ip_address(client, demisto.args()))
        elif demisto.command() == "usta-send-referrer-url":
            return_results(send_referrer_url())
        elif demisto.command() == "usta-search-specific-identity-leaks":
            return_results(search_specific_identity_leaks())
        elif demisto.command() == "usta-close-incident":
            return_results(close_incident())

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}")


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()