ThreatCrowd_v2 Deprecated

Deprecated. No available replacement.

Data Enrichment & Threat Intelligence · Threat Crowd (Deprecated)

Details

IDThreatCrowd_v2
ProviderAT&T Cybersecurity
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/python3:3.10.5.31797
Supported ModulesAgentix XSIAM

README

Query Threat Crowd for reports.
This integration was integrated and tested with version v2 of ThreatCrowd

Configure ThreatCrowd v2 in Cortex

Parameter Description Required
Server   True
Source Reliability Reliability of the source providing the intelligence data. True
Max Number of Entries How many entries to fetch. For full data use -1. 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.

ip


Get a report of an IP address.

Base Command

ip

Input

Argument Name Description Required
ip An IP address for which to retrieve a report. Required
limit Maximum number of results to fetch. Optional

Context Output

Path Type Description
IP.Address String IP address.
IP.Malicious.Vendor String The vendor reporting the IP address as malicious.
IP.Malicious.Description String A description explaining why the IP address was reported as malicious.
ThreatCrowd.IP.hashes String Hashes related to the ip.
ThreatCrowd.IP.permalink String The link to ip in the product.
ThreatCrowd.IP.references String References related to the ip.
ThreatCrowd.IP.resolutions String Resolutions related to the ip.
ThreatCrowd.IP.value String The ip value.
ThreatCrowd.IP.votes Number The votes given to the ip.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.

Command Example

!ip ip="x.x.x.x"

Context Example

{
    "DBotScore": {
        "Indicator": "x.x.x.x",
        "Reliability": "C - Fairly reliable",
        "Score": 3,
        "Type": "ip",
        "Vendor": "Threat Crowd"
    },
    "IP": {
        "Address": "x.x.x.x",
        "Malicious": {
            "Description": null,
            "Vendor": "Threat Crowd"
        }
    },
    "ThreatCrowd": {
        "IP": {
            "hashes": [
                "06d40abb65ee157ff2574df8d24743f1",
                "16e0a5aa50917ecadc0c2a7726e72ad0",
                "1e77eaba33333c91adfa28e97558677a",
                "210b6e761b4cb7d71e862606c0f28846",
                "226751fb62f99ff5a2c948dea15319df",
                "23ad6fc6ddb25a0974b90d9ec2df7757",
                "2f80660b47db546c6907edd95868b901",
                "36e6f6f725c77e505ccb466069c41c15",
                "3e06f3e3f4da7ea914bbd42bd17c7aef",
                "4d8d5d96caa717c92fea5ac2b1d6ae23"
            ],
            "permalink": "https://www.threatcrowd.org/ip.php?ip=x.x.x.x",
            "references": [],
            "resolutions": [
                {
                    "domain": "example.example.net",
                    "last_resolved": "2018-08-05"
                },
                {
                    "domain": "www.example.com",
                    "last_resolved": "2020-01-11"
                }
            ],
            "response_code": "1",
            "value": "x.x.x.x",
            "votes": -1
        }
    }
}

Human Readable Output

Threat crowd report for ip x.x.x.x

DBotScore: BAD

Resolutions

domain last_resolved
example.example.net 2018-08-05
www.example.com 2020-01-11

Hashes

Hashes
16e0a5aa50917ecadc0c2a7726e72ad0
1e77eaba33333c91adfa28e97558677a
210b6e761b4cb7d71e862606c0f28846
226751fb62f99ff5a2c948dea15319df
23ad6fc6ddb25a0974b90d9ec2df7757
2f80660b47db546c6907edd95868b901
36e6f6f725c77e505ccb466069c41c15
3e06f3e3f4da7ea914bbd42bd17c7aef
4d8d5d96caa717c92fea5ac2b1d6ae23

References

No entries.

domain


Get a report of a domain.

Base Command

domain

Input

Argument Name Description Required
domain The domain for which to retrieve a report. Required
limit Maximum number of results to fetch. Optional

Context Output

Path Type Description
Domain.Name String The domain name, for example: “google.com”.
Domain.Malicious.Vendor String The vendor reporting the domain as malicious.
Domain.Malicious.Description String A description explaining why the domain was reported as malicious.
ThreatCrowd.Domain.hashes String Hashes related to the domain.
ThreatCrowd.Domain.permalink String A link to domain search in the product.
ThreatCrowd.Domain.references String References related to the domain.
ThreatCrowd.Domain.resolutions String Resolutions related to the domain.
ThreatCrowd.Domain.subdomains String The subdomains related to the domain.
ThreatCrowd.Domain.emails String The emails related to the domain.
ThreatCrowd.Domain.value String The name of the domain.
ThreatCrowd.Domain.votes Number The votes given to the domain.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.

Command Example

!domain domain="example.com"

Context Example

{
    "DBotScore": {
        "Indicator": "example.com",
        "Reliability": "C - Fairly reliable",
        "Score": 3,
        "Type": "domain",
        "Vendor": "Threat Crowd"
    },
    "Domain": {
        "Malicious": {
            "Description": null,
            "Vendor": "Threat Crowd"
        },
        "Name": "example.com"
    },
    "ThreatCrowd": {
        "Domain": {
            "emails": [
                "domains@example.com",
                "example@example.com"
            ],
            "hashes": [],
            "permalink": "https://www.threatcrowd.org/domain.php?domain=example.com",
            "references": [
                "example.example.example"
            ],
            "response_code": "1",
            "subdomains": [
                "media.example.com",
                "e.example.com",
                "finance.example.com"
            ],
            "value": "example.com",
            "votes": -1
        }
    }
}

Human Readable Output

Threat crowd report for domain example.com

DBotScore: BAD

Resolutions

ip_address last_resolved
x.x.x.x 2014-04-01
x.x.x.x 2020-07-22
x.x.x.x 2021-03-05
x.x.x.x 2020-10-18

Subdomains

subdomains
example.example.com

###

emails permalink references response_code value votes  
domains@example.info,
example@example.com
  https://www.threatcrowd.org/domain.php?domain=example.com example.example 1 example.com -1

email


Get a report of an email address.

Base Command

email

Input

Argument Name Description Required
email The email address for which to retrieve a report. Required
limit Maximum number of results to fetch. Optional

Context Output

Path Type Description
ThreatCrowd.Account.value String The email address.
ThreatCrowd.Account.domains String The domains related to the email address.
ThreatCrowd.Account.permalink String The Link to the email address in the product.
ThreatCrowd.Account.references String The refernces related to the email address.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.

Command Example

!email email=example@example.com

Context Example

{
    "DBotScore": {
        "Indicator": "example@example.com",
        "Reliability": "C - Fairly reliable",
        "Score": 0,
        "Type": "email",
        "Vendor": "Threat Crowd"
    },
    "Email": {
        "Address": "example@example.com"
    },
    "ThreatCrowd": {
        "Account": {
            "domains": [
                "example.com",
                "example2.com",
                "example3.com",
            ],
            "permalink": "https://www.threatcrowd.org/email.php?email=example@example.com",
            "references": [],
            "response_code": "1",
            "value": "example@example.com"
        }
    }
}

Human Readable Output

Threat crowd report for Email example@example.com
DBotScore: None

Results

domains permalink response_code value  
example.com,
https://www.threatcrowd.org/email.php?email=example@example.com   1 example@example.com

threat-crowd-antivirus


Get a report of an antivirus.

Base Command

threat-crowd-antivirus

Input

Argument Name Description Required
antivirus The antivirus for which to retrieve a report. Required
limit Maximum number of results to fetch. Optional

Context Output

Path Type Description
ThreatCrowd.AntiVirus.hashes String The hashes related to the antivirus
ThreatCrowd.AntiVirus.permalink String The link to the antivitrus in the product
ThreatCrowd.AntiVirus.references Unknown The references of the antivirus.
ThreatCrowd.AntiVirus.value String The name of the antivirus

Command Example

!threat-crowd-antivirus antivirus="plugx" using=ThreatCrowdv2_instance_1

Context Example

{
    "ThreatCrowd": {
        "AntiVirus": {
            "hashes": [
                "31d0e421894004393c48de1769744687",
                "5cd3f073caac28f915cf501d00030b31",
                "bbd9acdd758ec2316855306e83dba469",
                "ef9d8cd06de03bd5f07b01c1cce9761f",
                "06bd026c77ce6ab8d85b6ae92bb34034",
                "2af64ba808c79dccd2c1d84f010b22d7",
                "47a311084bffddf6c00b4eb947b4086b",
                "4c5e55c2ce6e9176970aeecf9533cdbf",
                "4f92b6c9c55142ee562e8237ce1436a2",
                "876f24c4102a4e911ab77ee328643dd2"
            ],
            "permalink": "https://www.threatcrowd.org/listMalware.php?antivirus=plugx",
            "references": [],
            "response_code": "1",
            "value": "plugx"
        }
    }
}

Human Readable Output

Threat crowd report for antivirus plugx

hashes permalink response_code value
31d0e421894004393c48de1769744687,
5cd3f073caac28f915cf501d00030b31,
bbd9acdd758ec2316855306e83dba469,
ef9d8cd06de03bd5f07b01c1cce9761f,
06bd026c77ce6ab8d85b6ae92bb34034,
2af64ba808c79dccd2c1d84f010b22d7,
47a311084bffddf6c00b4eb947b4086b,
4c5e55c2ce6e9176970aeecf9533cdbf,
4f92b6c9c55142ee562e8237ce1436a2,
876f24c4102a4e911ab77ee328643dd2
https://www.threatcrowd.org/listMalware.php?antivirus=plugx 1 plugx

file


Get a report of a hash.

Base Command

file

Input

Argument Name Description Required
file The hash for which to retrieve a report. Required
limit Maximum number of results to fetch. Optional

Context Output

Path Type Description
File.MD5 String The MD5 hash of the file.
File.SHA1 String The SHA1 hash of the file.
File.Malicious.Vendor String The vendor that reported the file as malicious.
File.Malicious.Description String A description explaining why the file was determined to be malicious.
ThreatCrowd.File.sha1 String The SHA1 hash of the file.
ThreatCrowd.File.references String The refernces related to the file.
ThreatCrowd.File.permalink String The link to the file in the product.
ThreatCrowd.File.ips String The ips related to the file.
ThreatCrowd.File.domains String The domains related to the file.
ThreatCrowd.File.value String The file identifier.
ThreatCrowd.File.scans String The scans related to thefile.
ThreatCrowd.File.md5 String The MD5 of the file.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.

Command Example

!file file=31d0e421894004393c48de1769744687 using=ThreatCrowdv2_instance_1

Context Example

{
    "DBotScore": {
        "Indicator": "31d0e421894004393c48de1769744687",
        "Reliability": "C - Fairly reliable",
        "Score": 0,
        "Type": "file",
        "Vendor": "Threat Crowd"
    },
    "File": {
        "MD5": "31d0e421894004393c48de1769744687",
        "SHA1": "4f0eb746d81a616fb9bdff058997ef47a4209a76"
    },
    "ThreatCrowd": {
        "File": {
            "domains": [
                "hpservice.homepc.it",
                "facebook.controlliamo.com"
            ],
            "ips": [
                "8.8.8.8"
            ],
            "md5": "31d0e421894004393c48de1769744687",
            "permalink": "https://www.threatcrowd.org/malware.php?md5=31d0e421894004393c48de1769744687",
            "references": [],
            "response_code": "1",
            "scans": [
                "Error Scanning File",
                "Malware-gen*Win32*Malware-gen",
                "Gen*Variant.Symmi.50061",
                "W32/Trojan.VSQD-1927",
                "BDS/Plugx.266990",
                "Gen*Variant.Symmi.50061",
                "Gen*Variant.Symmi.50061",
                "Win32/Korplug.CF",
                "W32/FakeAV.CX",
                "Generic11_c.CDQL"
            ],
            "sha1": "4f0eb746d81a616fb9bdff058997ef47a4209a76",
            "value": "31d0e421894004393c48de1769744687"
        }
    }
}

Human Readable Output

Threat crowd report for File 31d0e421894004393c48de1769744687:

DBotScore: None

Results

domains ips md5 permalink references response_code scans sha1 value
hpservice.homepc.it,facebook.controlliamo.com 8.8.8.8 31d0e421894004393c48de1769744687 https://www.threatcrowd.org/malware.php?md5=31d0e421894004393c48de1769744687   1 Error Scanning File,Malware-genWin32Malware-gen,GenVariant.Symmi.50061,W32/Trojan.VSQD-1927,BDS/Plugx.266990,GenVariant.Symmi.50061,Gen*Variant.Symmi.50061,Win32/Korplug.CF,W32/FakeAV.CX,Generic11_c.CDQL 4f0eb746d81a616fb9bdff058997ef47a4209a76 31d0e421894004393c48de1769744687

Configuration parameters

  • server_url — Server (required)
  • integrationReliability — Source Reliability (required)
  • entry_limit — Max number of results per indicator (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (5)

  • domain

    Get a report of a domain.

  • email

    Get a report of an email address.

  • file

    Get a report of a hash.

  • ip

    Get a report of an IP address.

  • threat-crowd-antivirus

    Get a report of an antivirus.

import demistomock as demisto
from CommonServerPython import *
from CommonServerUserPython import *
from typing import Dict, Any, List, Optional, Tuple

''' CONSTANTS '''

VENDOR = 'Threat Crowd'
DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'  # ISO8601 format with UTC, default in XSOAR

''' CLIENT CLASS '''


class Client(BaseClient):
    def __init__(self, base_url: str, verify: bool, proxy: bool, reliability: DBotScoreReliability,
                 entry_limit: int):
        super().__init__(base_url=base_url, verify=verify, proxy=proxy)
        self.reliability = reliability
        self.entry_limit = entry_limit

    def _get_limit_for_command(self, command_limit: int = None):
        if command_limit:
            return None if command_limit == -1 else command_limit
        else:
            return self.entry_limit


''' HELPER FUNCTIONS '''


def _get_list_without_empty(list_to_change: list) -> list:
    if list_to_change:
        return [entry for entry in list_to_change if entry]
    return list_to_change


def handle_resolutions(resolutions: List[dict], limit: Optional[int]) -> List[dict]:
    """ Gets a resolution section from response with following struct: [{"last_resolved": "2014-12-14", "domain": "example.com"}]
        return a sorted list truncated to limit, desc by time."""

    resolutions = resolutions[:limit]
    resolutions.sort(key=lambda x: x['last_resolved'], reverse=True)
    return resolutions


def _get_dbot_score(json_res: dict) -> Tuple[int, str]:
    """
    Calculates DBot score according to https://github.com/AlienVault-OTX/ApiV2/blob/master/README.md#votes
    """
    # checks that response is valid
    if json_res.get('response_code') == '1':
        votes = json_res.get('votes')
        if votes == -1:
            return Common.DBotScore.BAD, 'BAD'
        elif votes == 0:
            return Common.DBotScore.SUSPICIOUS, 'SUSPICIOUS'
        elif votes == 1:
            return Common.DBotScore.GOOD, 'GOOD'

    return Common.DBotScore.NONE, 'None'


''' COMMAND FUNCTIONS '''


def ip_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]:
    command_results: List[CommandResults] = []
    api_url = 'ip/report/'
    entries_limit = client._get_limit_for_command(arg_to_number(args.get('limit'), 'limit', False))
    ips = argToList(args.get('ip'))
    for ip in ips:
        res = client._http_request(method='GET', url_suffix=api_url, params={'ip': ip})

        # adding value to both outputs and raw results as it is not provided in the API response
        res['value'] = ip
        score, score_str = _get_dbot_score(res)

        dbot = Common.DBotScore(
            ip, DBotScoreType.IP, VENDOR, score, reliability=client.reliability)
        ip_object = Common.IP(ip, dbot)

        hashes = res.get('hashes', [])[:entries_limit]
        resolutions = handle_resolutions(res.get('resolutions', []), entries_limit)

        markdown = f"### Threat crowd report for ip {ip}: \n  ### DBotScore: {score_str} \n" \
                   f"{tableToMarkdown('Resolutions', resolutions, removeNull=True)} \n " \
                   f"{tableToMarkdown('Hashes', hashes, headers='Hashes', removeNull=True)}" \
                   f"{tableToMarkdown('References', res.get('references'), removeNull=True, headers='References')}"

        outputs = {
            'hashes': hashes,
            'permalink': res.get('permalink'),
            'resolutions': resolutions,
            'references': res.get('references'),
            'response_code': res.get('response_code'),
            'votes': res.get('votes'),
            'value': res.get('value')
        }

        # using res.copy() to avoid changing all previous entries's values.
        command_results.append(CommandResults(
            outputs_prefix='ThreatCrowd.IP',
            outputs=outputs,
            outputs_key_field='value',
            indicator=ip_object,
            readable_output=markdown,
            raw_response=res.copy()

        ))

    return command_results


def email_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]:
    command_results: List[CommandResults] = []
    api_url = 'email/report/'
    emails = argToList(args.get('email'))
    for email in emails:
        res = client._http_request(method='GET', url_suffix=api_url, params={'email': email})

        # adding value to both outputs and raw results as it is not provided in the API response
        res['value'] = email
        score, score_str = _get_dbot_score(res)
        dbot = Common.DBotScore(
            email, DBotScoreType.EMAIL, VENDOR, score, reliability=client.reliability)
        email_object = Common.EMAIL(email, dbot)

        markdown = f"### Threat crowd report for Email {email} \n " \
                   f"DBotScore: {score_str} \n {tableToMarkdown('Results', res, removeNull=True)}"

        # using res.copy() to avoid changing all previous entries's values.
        command_results.append(CommandResults(
            outputs_prefix='ThreatCrowd.Account',
            outputs=res.copy(),
            outputs_key_field='value',
            indicator=email_object,
            readable_output=markdown,
            raw_response=res.copy()

        ))

    return command_results


def domain_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]:
    command_results: List[CommandResults] = []
    api_url = 'domain/report/'
    entries_limit = client._get_limit_for_command(arg_to_number(args.get('limit'), 'limit', False))
    domains = argToList(args.get('domain'))
    for domain in domains:
        res = client._http_request(method='GET', url_suffix=api_url, params={'domain': domain})

        # adding value to both outputs and raw results as it is not provided in the API response
        res['value'] = domain
        score, score_str = _get_dbot_score(res)
        dbot = Common.DBotScore(
            domain, DBotScoreType.DOMAIN, VENDOR, score, reliability=client.reliability)
        domain_object = Common.Domain(domain, dbot)

        markdown = f"### Threat crowd report for domain {domain} \n ### DBotScore: {score_str} \n"

        subdomains = res.get('subdomains')[:entries_limit]
        resolutions = handle_resolutions(res.get('resolutions', []), entries_limit)

        markdown += f'{tableToMarkdown("Resolutions", resolutions, removeNull=True)} \n ' \
                    f'{tableToMarkdown("Subdomains", subdomains, headers=["subdomains"])} \n'
        res_to_show = res.copy()
        res_to_show.pop("resolutions")
        res_to_show.pop("subdomains")
        markdown += f'{tableToMarkdown(" ", res_to_show, removeNull=True)}'

        outputs = {
            'hashes': res.get('hashes'),
            'permalink': res.get('permalink'),
            'resolutions': resolutions,
            'references': res.get('references'),
            'response_code': res.get('response_code'),
            'votes': res.get('votes'),
            'subdomains': subdomains,
            'value': res.get('value')
        }

        # using res.copy() to avoid changing all previous entries's values.
        command_results.append(CommandResults(
            outputs_prefix='ThreatCrowd.Domain',
            outputs=outputs,
            outputs_key_field='value',
            indicator=domain_object,
            readable_output=markdown,
            raw_response=res.copy()

        ))

    return command_results


def antivirus_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]:
    command_results: List[CommandResults] = []
    api_url = 'antivirus/report/'
    antivirus_list = argToList(args.get('antivirus'))
    entries_limit = client._get_limit_for_command(arg_to_number(args.get('limit'), 'limit', False))

    for antivirus in antivirus_list:
        res = client._http_request(method='GET', url_suffix=api_url, params={'antivirus': antivirus})

        # adding value to both outputs and raw results as it is not provided in the API response
        res['value'] = antivirus
        res['hashes'] = res['hashes'][:entries_limit]

        markdown = tableToMarkdown(f"Threat crowd report for antivirus {antivirus}", res, removeNull=True)

        # using res.copy() to avoid changing all previous entries's values.
        command_results.append(CommandResults(
            outputs_prefix='ThreatCrowd.AntiVirus',
            outputs=res.copy(),
            outputs_key_field='value',
            readable_output=markdown,
            raw_response=res.copy()
        ))

    return command_results


def file_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]:
    command_results: List[CommandResults] = []
    api_url = 'file/report/'
    files = argToList(args.get('file'))
    entries_limit = client._get_limit_for_command(arg_to_number(args.get('limit'), 'limit', False))

    for file_hash in files:
        res = client._http_request(method='GET', url_suffix=api_url, params={'resource': file_hash})

        # adding value to both outputs and raw results as it is not provided in the API response
        res['value'] = file_hash

        score, score_str = _get_dbot_score(res)
        dbot = Common.DBotScore(
            file_hash, DBotScoreType.FILE, VENDOR, score, reliability=client.reliability)
        file_object = Common.File(dbot, md5=res.get('md5'), sha1=res.get('sha1'))

        # removes empty entries returned by API
        res['scans'] = _get_list_without_empty(res.get('scans'))[:entries_limit]

        markdown = f"### Threat crowd report for File {file_hash}: \n ### DBotScore: {score_str} \n " \
                   f"{tableToMarkdown('Results', res)}".replace('<br>', '')

        # using res.copy() to avoid changing all previous entries's values.
        command_results.append(CommandResults(
            outputs_prefix='ThreatCrowd.File',
            outputs=res.copy(),
            outputs_key_field='value',
            indicator=file_object,
            readable_output=markdown,
            raw_response=res.copy()
        ))

    return command_results


def test_module(client: Client) -> str:
    try:
        api_url = 'ip/report/'
        client._http_request(method='GET', url_suffix=api_url, params={'ip': '1.1.1.1'})
        message = 'ok'
    except DemistoException as e:
        if 'Forbidden' in str(e) or 'Authorization' in str(e):
            message = 'Authorization Error: make sure API Key is correctly set.'
        else:
            raise e
    return message


''' MAIN FUNCTION '''


def main() -> None:
    command_functions = {'email': email_command,
                         'domain': domain_command,
                         'ip': ip_command,
                         'threat-crowd-antivirus': antivirus_command,
                         'file': file_command}
    command = demisto.command()

    demisto.debug(f'Command being called is {command}')
    try:
        params = demisto.params()
        base_url = params.get('server_url')
        verify_certificate = not params.get('insecure', False)
        proxy = params.get('proxy', False)
        entry_limit = arg_to_number(params.get('entry_limit'), 'entry_limit', True)
        if not entry_limit:
            raise Exception("Please Provide a limit for number of entries. To receive all entries use -1")
        reliability = params.get('integrationReliability')
        reliability = reliability if reliability else DBotScoreReliability.C

        if DBotScoreReliability.is_valid_type(reliability):
            reliability = DBotScoreReliability.get_dbot_score_reliability_from_str(reliability)
        else:
            raise Exception("Please provide a valid value for the Source Reliability parameter.")

        client = Client(
            base_url=base_url,
            verify=verify_certificate,
            proxy=proxy,
            reliability=reliability,
            entry_limit=entry_limit
        )

        if command == 'test-module':
            result = test_module(client)
            return_results(result)

        else:
            if command in command_functions:
                return_results(command_functions[command](client, demisto.args()))
            else:
                raise NotImplementedError(f'command {command} is not implemented.')

    # Log exceptions and return errors
    except Exception as e:
        return_error(f'Failed to execute {command} command.\nError:\n{str(e)}')


''' ENTRY POINT '''

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