Cyberint Feed
Use the Cyberint Feed integration to get indicators from the feed.
Data Enrichment & Threat Intelligence · Cyberint · Feed
Details
| ID | Cyberint Feed |
|---|---|
| Provider | Check Point Software Technologies |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.9.0 |
| Docker Image | demisto/python3:3.12.13.10404775 |
| Supported Modules | Agentix XSIAM |
README
Use the Cyberint Feed integration to get indicators from the feed.
Configure Cyberint Feed on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for Cyberint Feed.
-
Click Add instance to create and configure a new integration instance.
Parameter Description Required Cyberint API URL Example: https://yourcompany.cyberint.ioTrue API access token True Fetch indicators Should be checked (true) False Indicator Type Which indicator types to fetch True Confidence Confidence about the indicator details. The value of confidence to fetch indicators from. The value between 0-100. False Severity Severity about the indicator details. The value of severity to fetch indicators from. The value between 0-100. False Tags Supports CSV values. False Bypass exclusion list When selected, the exclusion list is ignored for indicators from this feed. This means that if an indicator from this feed is on the exclusion list, the indicator might still be added to the system. False Trust any certificate (not secure) False Use system proxy settings False - 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.
cyberint-get-indicators
Gets indicators from the feed.
Base Command
cyberint-get-indicators
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | The maximum number of results to return. The default value is 10. Default is 10. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.indicator.ioc_value | String | The indicator value. |
| Cyberint.indicator.ioc_type | String | The indicator type. |
| Cyberint.indicator.description | String | The feed description. |
| Cyberint.indicator.detected_activity | String | The feed detected activity. |
| Cyberint.indicator.observation_date | String | The feed observation date. |
| Cyberint.indicator.severity_score | String | The feed severity score. |
| Cyberint.indicator.confidence | String | The feed confidence. |
Command example
!cyberint-get-indicators limit=10 execution-timeout=700
Context Example
{
"Cyberint": [
{
"fields": {
"Description": "Recognized as Malicious.",
"FirstSeenBySource": "2024-01-23T22:53:36+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as Malicious.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc1",
"observation_date": "2024-01-23T22:53:36+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc1"
},
{
"fields": {
"Description": "Recognized as zzz.",
"FirstSeenBySource": "2024-01-23T22:55:36+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as zzz.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc2",
"observation_date": "2024-01-23T22:55:36+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc2"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2024-01-23T22:53:35+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc3",
"observation_date": "2024-01-23T22:53:35+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc3"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2024-01-23T22:55:31+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc4",
"observation_date": "2024-01-23T22:55:31+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc4"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2024-01-23T22:55:35+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc5",
"observation_date": "2024-01-23T22:55:35+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc5"
},
{
"fields": {
"Description": "Recognized as Trojan.xxx.",
"FirstSeenBySource": "2024-01-23T22:55:39+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as Trojan.xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc6",
"observation_date": "2024-01-23T22:55:39+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc6"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2024-01-12T01:39:06+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc7",
"observation_date": "2024-01-12T01:39:06+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc7"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2024-01-23T22:55:36+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc8",
"observation_date": "2024-01-23T22:55:36+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc8"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2023-12-16T21:28:01+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 70,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc9",
"observation_date": "2023-12-16T21:28:01+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc9"
},
{
"fields": {
"Description": "Recognized as xxx.",
"FirstSeenBySource": "2024-01-23T22:55:35+00:00",
"reportedby": "Cyberint",
"trafficlightprotocol": "GREEN"
},
"rawJSON": {
"confidence": 80,
"description": "Recognized as xxx.",
"detected_activity": "malware_payload",
"ioc_type": "file/sha256",
"ioc_value": "ioc10",
"observation_date": "2024-01-23T22:55:35+00:00",
"severity_score": 100
},
"service": "Cyberint",
"type": "File",
"value": "ioc10"
}
]
}
Human Readable Output
Indicators from Cyberint Feed
| Name | Type | Description |
|---|---|---|
| Detected activity | String | Type of detected activity. |
| IoC type | String | The indicator type. |
| IoC value | String | The indicator value. |
| Observation date | String | Observation date of detected activity. |
| Severity score | Number | Severity score of detected activity. |
| Confidence | Number | Confidence of detected activity. |
| Description | String | Description of detected activity. |
cyberint-get-file-sha256
Gets File SHA256 from the feed.
Base Command
cyberint-get-file-sha256
Input
| Argument Name | Description | Required |
|---|---|---|
| value | File SHA256 hash | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.file_sha256.entity.type | String | The indicator type. |
| Cyberint.file_sha256.entity.value | String | The indicator value. |
| Cyberint.file_sha256.enrichment.first_seen | String | First seen. |
| Cyberint.file_sha256.enrichment.download_urls | String | Download URLs. |
| Cyberint.file_sha256.enrichment.filenames | String | Filenames. |
| Cyberint.file_sha256.benign | String | Benign. |
| Cyberint.file_sha256.risk.malicious_score | String | Malicious score. |
| Cyberint.file_sha256.risk.occurrences_count | String | Occurrences count. |
Command example
!cyberint-get-file-sha256 value=6a7b02c43837dcb8e40d271edb88d13d2e723c721a74931857aaef4853317789
Context Example
{
"data": {
"entity": {
"type": "file/sha256",
"value": "6a7b02c43837dcb8e40d271edb88d13d2e723c721a74931857aaef4853317789"
},
"risk": {
"malicious_score": 100,
"detected_activities": [
{
"type": "malware",
"observation_date": "2025-03-05T14:47:43.994848+00:00",
"description": "",
"confidence": 100,
"occurrences_count": 1
},
{
"type": "malware_payload",
"observation_date": "2025-02-12T21:08:13+00:00",
"description": "Detected in 1 source(s). Recognized as Trojan.Agent.CYZT.",
"confidence": 80,
"occurrences_count": 1
}
],
"occurrences_count": 2
},
"enrichment": {
"related_entities": null,
"filenames": [
"rifaien2-TwxvxoHtj44icOI0.exe"
],
"first_seen": "2025-02-12T21:08:13+00:00",
"download_urls": []
},
"benign": false
}
}
Human Readable Output
File SHA256 Entity
| Name | Type | Description |
|---|---|---|
| Type | String | The indicator type. |
| Value | String | The indicator value. |
| Malicious score | Number | Malicious score. |
| Benign | Boolean | Benign. |
File SHA256 Enrichment
| Name | Type | Description |
|---|---|---|
| Filenames | String | List of filenames. |
| First seen | String | First seen. |
| Download URLs | String | List of download URLs. |
File SHA256 Detected activities
| Name | Type | Description |
|---|---|---|
| Type | String | Type of detected activity. |
| Observation date | String | Observation date of detected activity. |
| Description | String | Description of detected activity. |
| Confidence | Number | Confidence of detected activity. |
| Occurrences count | Number | Occurrences count of detected activity. |
cyberint-get-domain
Gets Domain from the feed.
Base Command
cyberint-get-domain
Input
| Argument Name | Description | Required |
|---|---|---|
| value | Domain | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.domain.entity.type | String | The indicator type. |
| Cyberint.domain.entity.value | String | The indicator value. |
| Cyberint.domain.risk.malicious_score | String | Malicious score. |
| Cyberint.domain.risk.occurrences_count | String | Occurrences count. |
| Cyberint.domain.enrichment.ips | String | IPs. |
| Cyberint.domain.enrichment.whois.created_date | String | Created date. |
| Cyberint.domain.enrichment.whois.updated_date | String | Updated date. |
| Cyberint.domain.enrichment.whois.expiration_date | String | Expiration date. |
| Cyberint.domain.enrichment.whois.registrant_name | String | Registrant name. |
| Cyberint.domain.enrichment.whois.registrant_email | String | Registrant email. |
| Cyberint.domain.enrichment.whois.registrant_organization | String | Registrant organization. |
| Cyberint.domain.enrichment.whois.registrant_country | String | Registrant country. |
| Cyberint.domain.enrichment.whois.registrant_telephone | String | Registrant telephone. |
| Cyberint.domain.enrichment.whois.technical_contact_email | String | Technical contact email. |
| Cyberint.domain.enrichment.whois.technical_contact_name | String | Technical contact name. |
| Cyberint.domain.enrichment.whois.technical_contact_organization | String | Technical contact organization. |
| Cyberint.domain.enrichment.whois.registrar_name | String | Registrar name. |
| Cyberint.domain.enrichment.whois.admin_contact_name | String | Admin contact name. |
| Cyberint.domain.enrichment.whois.admin_contact_organization | String | Admin contact organization. |
| Cyberint.domain.enrichment.whois.admin_contact_email | String | Admin contact email. |
| Cyberint.domain.benign | String | Benign. |
Command example
!cyberint-get-domain value=dummy.com
Context Example
{
"data": {
"entity": {
"type": "domain",
"value": "domain.com"
},
"risk": {
"malicious_score": 80,
"detected_activities": [
{
"type": "infecting_url",
"observation_date": "2025-03-05T14:47:23.534044+00:00",
"description": "URL that may infect it’s visitors with malware.",
"confidence": 100,
"occurrences_count": 1
},
{
"type": "phishing_website",
"observation_date": "2024-09-16T06:26:16+00:00",
"description": "Detected phishing website targeting Dummy.",
"confidence": 20,
"occurrences_count": 1
}
],
"occurrences_count": 2
},
"enrichment": {
"related_entities": null,
"ips": [
"11.197.130.221"
],
"whois": {
"registrant_name": null,
"registrant_email": null,
"registrant_organization": null,
"registrant_country": "USA",
"registrant_telephone": null,
"technical_contact_email": null,
"technical_contact_name": null,
"technical_contact_organization": null,
"registrar_name": "Registrar.com",
"admin_contact_name": null,
"admin_contact_organization": null,
"admin_contact_email": null,
"created_date": "2024-09-10T09:29:58",
"updated_date": "2024-10-18T05:44:51",
"expiration_date": "2025-09-10T23:59:59"
}
},
"benign": false
}
}
Human Readable Output
Domain Entity
| Name | Type | Description |
|---|---|---|
| Type | String | The indicator type. |
| Value | String | The indicator value. |
| Malicious score | Number | Malicious score. |
| Occurrences count | Number | Occurrences count. |
| Benign | Boolean | Benign. |
Domain Enrichment
| Name | Type | Description |
|---|---|---|
| IPs | String | List of IP addresses. |
| Whois registrant name | String | Whois registrant name. |
| Whois registrant email | String | Whois registrant email. |
| Whois registrant organization | String | Whois registrant organization. |
| Whois registrant country | String | Whois registrant country. |
| Whois registrant telephone | String | Whois registrant telephone. |
| Whois technical contact email | String | Whois technical contact email. |
| Whois technical contact name | String | Whois technical contact name. |
| Whois technical contact organization | String | Whois technical contact organization. |
| Whois registrar name | String | Whois registrar name. |
| Whois admin contact name | String | Whois admin contact name. |
| Whois admin contact organization | String | Whois admin contact organization. |
| Whois admin contact email | String | Whois admin contact email. |
| Whois admin contact email | String | Whois admin contact email. |
| Created date | String | Created date. |
| Updated date | String | Updated date. |
| Expiration date | String | Expiration date. |
Domain Detected activities
| Name | Type | Description |
|---|---|---|
| Type | String | Type of detected activity. |
| Observation date | String | Observation date of detected activity. |
| Description | String | Description of detected activity. |
| Confidence | Number | Confidence of detected activity. |
| Occurrences count | Number | Occurrences count of detected activity. |
cyberint-get-ipv4
Gets Domain from the feed.
Base Command
cyberint-get-ipv4
Input
| Argument Name | Description | Required |
|---|---|---|
| value | IPv4 | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.ipv4.entity.type | String | The indicator type. |
| Cyberint.ipv4.entity.value | String | The indicator value. |
| Cyberint.ipv4.risk.malicious_score | String | Malicious score. |
| Cyberint.ipv4.risk.occurrences_count | String | Occurrences count. |
| Cyberint.ipv4.enrichment.geo.country | String | Country. |
| Cyberint.ipv4.enrichment.geo.city | String | City. |
| Cyberint.ipv4.enrichment.asn.number | String | ASN number. |
| Cyberint.ipv4.enrichment.asn.organization | String | ASN organization. |
| Cyberint.ipv4.enrichment.suspicious_urls | String | Suspicious URLs. |
| Cyberint.ipv4.enrichment.suspicious_domains | String | Suspicious domains. |
| Cyberint.ipv4.benign | String | Benign. |
Command example
!cyberint-get-ipv4 value=1.1.1.1
Context Example
{
"data": {
"entity": {
"type": "ipv4",
"value": "11.197.130.221"
},
"risk": {
"malicious_score": 100,
"detected_activities": [
{
"type": "payload_delivery",
"observation_date": "2025-02-13T08:38:50+00:00",
"description": "Detected hosting malware.",
"confidence": 20,
"occurrences_count": 836
},
{
"type": "phishing_website",
"observation_date": "2025-03-05T10:17:32+00:00",
"description": "Detected phishing website targeting Dummy, ING Direct, genericcloudflare.",
"confidence": 20,
"occurrences_count": 143
},
{
"type": "cnc_server",
"observation_date": "2025-02-14T22:21:12.084000+00:00",
"description": "Detected in 21 source(s). Recognized as Quasar RAT. Detected activity linked to: Bumblebee (Malware), Cotton Sandstorm (Threat-Actor-Group), DadSec (Malware), GHOSTSPIDER (Malware), Quasar RAT (Malware), Salt Typhoon (Threat-Actor-Group), Sneaky 2FA (Malware), Vidar (Malware)",
"confidence": 90,
"occurrences_count": 21
}
],
"occurrences_count": 1000
},
"enrichment": {
"related_entities": [
{
"entity_id": "c654837d-444e-4f5c-a444-09fd8250696c",
"entity_type": "Malware",
"entity_name": "GHOSTSPIDER"
},
{
"entity_id": "70b54325-05ea-46c6-b4e9-b25bc3617104",
"entity_type": "Threat-Actor-Group",
"entity_name": "Salt Typhoon"
},
{
"entity_id": "baffd4c4-4483-4b84-96eb-0d19af94d2e8",
"entity_type": "Malware",
"entity_name": "DadSec"
},
{
"entity_id": "862341a5-1951-4e09-b3c1-baac41dc7bcb",
"entity_type": "Malware",
"entity_name": "Vidar"
},
{
"entity_id": "7b0a986f-733e-4497-8867-6aed00b802b8",
"entity_type": "Threat-Actor-Group",
"entity_name": "Cotton Sandstorm"
},
{
"entity_id": "58cbb47d-176d-4937-9ebc-5121ceb36cf9",
"entity_type": "Malware",
"entity_name": "Sneaky 2FA"
},
{
"entity_id": "2728ad3e-d870-4654-afd3-9a839f97dd72",
"entity_type": "Malware",
"entity_name": "Bumblebee"
},
{
"entity_id": "fc26b8a7-a7cc-47b8-be1e-92b7a969543b",
"entity_type": "Malware",
"entity_name": "Quasar RAT"
}
],
"geo": {
"country": "United States",
"city": null
},
"asn": {
"number": 16509,
"organization": "AMAZON-02"
},
"suspicious_urls": [],
"suspicious_domains": []
},
"benign": false
}
}
Human Readable Output
IPv4 Entity
| Name | Type | Description |
|---|---|---|
| Type | String | The indicator type. |
| Value | String | The indicator value. |
| Malicious score | Number | Malicious score. |
| Occurrences count | Number | Occurrences count. |
| IPs | String | List of IP addresses. |
| Hostname | String | Hostname. |
| Domain | String | Domain. |
| Benign | Boolean | Benign. |
IPv4 Enrichment
| Name | Type | Description |
|---|---|---|
| Suspicious Urls | String | List of Suspicious Urls. |
| Suspicious Domains | String | List of Suspicious domains. |
IPv4 Detected activities
| Name | Type | Description |
|---|---|---|
| Type | String | Type of detected activity. |
| Observation date | String | Observation date of detected activity. |
| Description | String | Description of detected activity. |
| Confidence | Number | Confidence of detected activity. |
| Occurrences count | Number | Occurrences count of detected activity. |
cyberint-get-url
Gets Domain from the feed.
Base Command
cyberint-get-url
Input
| Argument Name | Description | Required |
|---|---|---|
| value | URL | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.url.entity.type | String | The indicator type. |
| Cyberint.url.entity.value | String | The indicator value. |
| Cyberint.url.risk.malicious_score | String | Malicious score. |
| Cyberint.url.risk.occurrences_count | String | Occurrences count. |
| Cyberint.url.enrichment.ips | String | IPs. |
| Cyberint.url.enrichment.hostname | String | Hostname. |
| Cyberint.url.enrichment.domain | String | Domain. |
| Cyberint.url.benign | String | Benign. |
Command example
!cyberint-get-url value=http://dummy.com
Context Example
{
"data": {
"entity": {
"type": "url",
"value": "http://dummy.com"
},
"risk": {
"malicious_score": 80,
"detected_activities": [
{
"type": "infecting_url",
"observation_date": "2025-03-05T11:18:01.941280+00:00",
"description": "URL that may infect it’s visitors with malware.",
"confidence": 100,
"occurrences_count": 1
}
],
"occurrences_count": 1
},
"enrichment": {
"related_entities": null,
"ips": [],
"hostname": null,
"domain": null
},
"benign": false
}
}
Human Readable Output
URL Entity
| Name | Type | Description |
|---|---|---|
| Type | String | The indicator type. |
| Value | String | The indicator value. |
| Malicious score | Number | Malicious score. |
| Occurrences count | Number | Occurrences count. |
| IPs | String | List of IP addresses. |
| Hostname | String | Hostname. |
| Domain | String | Domain. |
| Benign | Boolean | Benign. |
URL Detected activities
| Name | Type | Description |
|---|---|---|
| Type | String | Type of detected activity. |
| Observation date | String | Observation date of detected activity. |
| Description | String | Description of detected activity. |
| Confidence | Number | Confidence of detected activity. |
| Occurrences count | Number | Occurrences count of detected activity. |
cyberint-cve-enrich
Enriches one or more CVE identifiers with Cyberint vulnerability intelligence, including EPSS, CVSS, CWE, the Cyberint CVE score and active-exploitation evidence.
Base Command
cyberint-cve-enrich
Input
| Argument Name | Description | Required |
|---|---|---|
| cve_id | CVE identifier to enrich (e.g., CVE-2024-1234). Supports a comma-separated list of identifiers. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.CVE.cve_id | String | The CVE identifier. |
| Cyberint.CVE.cyberint_score | Number | Cyberint proprietary risk score for the CVE. |
| Cyberint.CVE.epss | Number | EPSS (Exploit Prediction Scoring System) probability score. |
| Cyberint.CVE.description | String | The CVE description. |
| Cyberint.CVE.published | Date | The date the CVE was published. |
| Cyberint.CVE.last_updated | Date | The date the CVE was last updated. |
| Cyberint.CVE.cvss.cvss_v3.base_score | Number | CVSS v3 base score. |
| Cyberint.CVE.cvss.cvss_v3.base_severity | String | CVSS v3 base severity. |
| Cyberint.CVE.cvss.cvss_v4.base_score | Number | CVSS v4 base score. |
| Cyberint.CVE.cwes.cwe_id | String | Associated CWE identifier. |
| Cyberint.CVE.cwes.name | String | Associated CWE name. |
| Cyberint.CVE.risk_factors | Unknown | Risk factors associated with the CVE. |
| Cyberint.CVE.exploited_by | Unknown | Threat actors observed exploiting the CVE. |
| Cyberint.CVE.products | Unknown | Products affected by the CVE. |
| Cyberint.CVE.recommendation | String | Cyberint remediation recommendation for the CVE. |
| Cyberint.CVE.references | Unknown | External references for the CVE. |
| CVE.ID | String | The CVE identifier. |
| CVE.CVSS | String | The CVSS score of the CVE. |
| CVE.Published | Date | The date the CVE was published. |
| CVE.Description | String | The CVE description. |
Command Example
!cyberint-cve-enrich cve_id="CVE-2024-1234"
cyberint-credential-leak-lookup
Looks up leaked employee or customer credentials associated with a company domain, using the Cyberint leaked-credentials API.
Base Command
cyberint-credential-leak-lookup
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | The company domain to search leaked credentials for (e.g., example.com). | Required |
| last_seen_from | Only return credentials last seen on or after this ISO-formatted date (YYYY-MM-DDTHH:MM:SSZ). | Optional |
| last_seen_to | Only return credentials last seen on or before this ISO-formatted date (YYYY-MM-DDTHH:MM:SSZ). | Optional |
| limit | Maximum number of leaked credential records to return per credential type (employee/customer). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cyberint.LeakedCredential.domain | String | The company domain that was searched. |
| Cyberint.LeakedCredential.total | Number | Total number of leaked credential records returned. |
| Cyberint.LeakedCredential.employee_total | Number | Number of leaked employee credential records returned. |
| Cyberint.LeakedCredential.customer_total | Number | Number of leaked customer credential records returned. |
| Cyberint.LeakedCredential.employee_credentials.username | String | The leaked employee account username. |
| Cyberint.LeakedCredential.employee_credentials.first_seen | Date | The date the employee credential was first observed. |
| Cyberint.LeakedCredential.employee_credentials.last_seen | Date | The date the employee credential was last observed. |
| Cyberint.LeakedCredential.employee_credentials.entries | Unknown | The leaked credential entries (password, source, URL) for the employee account. |
| Cyberint.LeakedCredential.customer_credentials.username | String | The leaked customer account username. |
| Cyberint.LeakedCredential.customer_credentials.first_seen | Date | The date the customer credential was first observed. |
| Cyberint.LeakedCredential.customer_credentials.last_seen | Date | The date the customer credential was last observed. |
| Cyberint.LeakedCredential.customer_credentials.entries | Unknown | The leaked credential entries (password, source, URL) for the customer account. |
Command Example
!cyberint-credential-leak-lookup domain="example.com"
Configuration parameters
url— Cyberint API URL (required)client_name— Company Name (required)access_token— API Key (Leave empty. Fill in the API Key in the password field.) (required)feed— Fetch indicatorsfeedReputation— Indicator ReputationfeedReliability— Source Reliability (required)tlp_color— Traffic Light Protocol Colorindicator_type— Indicator Type (required)feed_name— Feed Name (required)confidence_from— Confidenceseverity_from— SeverityfeedExpirationPolicy—feedExpirationInterval—feedFetchInterval— Feed Fetch IntervalfeedTags— TagsfeedBypassExclusionList— Bypass exclusion listinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (7)
-
cyberint-credential-leak-lookupLooks up leaked employee or customer credentials associated with a company domain, using the Cyberint leaked-credentials API.
-
cyberint-cve-enrichEnriches one or more CVE identifiers with Cyberint vulnerability intelligence, including EPSS, CVSS, CWE, the Cyberint CVE score and active-exploitation evidence.
-
cyberint-get-domainGets Domain enrichment from the feed.
-
cyberint-get-file-sha256Gets File SHA256 enrichment from the feed.
-
cyberint-get-indicatorsGets indicators from the feed.
-
cyberint-get-ipv4Gets IPv4 enrichment from the feed.
-
cyberint-get-urlGets URL enrichment from the feed.
import http import json import math from json import JSONDecodeError from typing import Any import demistomock as demisto import urllib3 from CommonServerPython import * urllib3.disable_warnings() DATE_FORMAT = "%Y-%m-%d" DEFAULT_INTERVAL = 30 # 30 minutes EXECUTION_TIMEOUT_SECONDS = 1200 # 20 minutes MAX_LIMIT_SIZE_PER_EXEC = 100000 PAGE_SIZE = 20000 class Client(BaseClient): """ Client to use in the Cyberint Feed integration. """ def __init__( self, base_url: str, access_token: str, verify: bool = False, proxy: bool = False, ): params = demisto.params() self._cookies = {"access_token": access_token} self._headers = { "X-Integration-Type": "XSOAR", "X-Integration-Instance-Name": demisto.integrationInstance(), "X-Integration-Instance-Id": "", "X-Integration-Customer-Name": params.get("client_name", ""), "X-Integration-Version": str(get_pack_version()), } super().__init__(base_url, verify=verify, proxy=proxy, headers=self._headers) @logger def request_daily_feed( self, date_time: str = None, limit: int = 1000, execution_start_time: datetime = datetime.now(), test: bool = False ) -> list[dict[str, Any]]: """ Retrieves all entries from the feed with pagination support. Args: date_time (str): The date-time value to use in the URL. Defaults to None. limit (int): The maximum number of entries to retrieve per request. Defaults to 1000. execution_start_time (datetime): The start time of the execution. Defaults to now. test (bool): If true, only return one page for testing connection. Returns: A list of objects, containing the indicators. """ result = [] init_offset = offset = demisto.getIntegrationContext().get("offset", 0) date_time = date_time or str(datetime.now().strftime(DATE_FORMAT)) has_more = True demisto.debug(f"Fetching feed offset {offset}") while has_more: if offset >= init_offset + MAX_LIMIT_SIZE_PER_EXEC: demisto.setIntegrationContext({"date_time": date_time, "offset": offset}) has_more = False continue demisto.debug(f"Fetching feed offset {offset}") # if the execution exceeded the timeout we will break if not test and is_execution_time_exceeded(start_time=execution_start_time): demisto.debug(f"Execution time exceeded: {EXECUTION_TIMEOUT_SECONDS} seconds from: {execution_start_time}") has_more = False continue start_time = time.time() # Using the method to fetch and process the feed response indicators = self.process_feed_response(date_time, limit, offset) if not indicators: # No more data or an error occurred demisto.setIntegrationContext({"offset": 0}) has_more = False else: result.extend(indicators) # Append valid indicators to the result end_time = time.time() demisto.debug(f"Duration of offset processing {offset}: {math.ceil(end_time - start_time)} seconds") # Update the offset for the next request offset += limit has_more = True demisto.debug(f"Feed has more incidents for fetching: {has_more}") if test: # if test module, end the loop demisto.debug("Test execution") has_more = False continue return result def process_feed_response(self, date_time: str, limit: int, offset: int) -> list[dict[str, Any]]: """ Makes the API request to retrieve the indicators, handles JSON decoding, and processes the feed. Args: date_time (str): The date-time value to use in the URL. limit (int): The maximum number of entries to retrieve per request. offset (int): The offset to retrieve the correct page of results. Returns: A list of indicator dictionaries, or an empty list if no valid indicators are found. """ result: List[Any] = [] response = self.retrieve_indicators_from_api(date_time, limit, offset) try: # If json is invalid, return empty list (non 200 or invalid JSON) feeds = response.strip().split("\n") ioc_feeds = [json.loads(feed) for feed in feeds] except JSONDecodeError as e: demisto.error(f"Failed to decode JSON: {e}") return result # Return empty result on failure if not ioc_feeds: # No data found demisto.debug("No more indicators found") return result # Process valid feeds for indicator in ioc_feeds: ioc_value = indicator.get("ioc_value") if auto_detect_indicator_type(ioc_value): result.append(indicator) return result @logger def retrieve_indicators_from_api(self, date_time, limit, offset): url_suffix = f"/ioc/api/v1/feed/daily/{date_time}?limit={limit}&offset={offset}" demisto.debug(f"URL to fetch indicators: {url_suffix}") response = self._http_request( method="GET", url_suffix=url_suffix, cookies=self._cookies, resp_type="text", timeout=120, retries=3, ) return response @logger def retrieve_file_sha256_from_api(self, value: str) -> dict[str, Any]: """ Makes the API request to retrieve File SHA256 IoC. Args: value (str): string ^[a-f0-9]{64}$. Returns: Enrichment information. """ url_suffix = f"/ioc/api/v1/file/sha256?value={value}" demisto.debug(f"URL to retrieve File SHA256 IoC: {url_suffix}") response = self._http_request( method="GET", url_suffix=url_suffix, cookies=self._cookies, timeout=120, retries=3, ) return response @logger def retrieve_domain_from_api(self, value: str) -> dict[str, Any]: """ Makes the API request to retrieve Domain IoC. Args: value (str): string ^[a-f0-9]{64}$. Returns: Enrichment information. """ url_suffix = f"/ioc/api/v1/domain?value={value}" demisto.debug(f"URL to retrieve Domain IoC: {url_suffix}") response = self._http_request( method="GET", url_suffix=url_suffix, cookies=self._cookies, timeout=120, retries=3, ) return response @logger def retrieve_ipv4_from_api(self, value: str) -> dict[str, Any]: """ Makes the API request to retrieve IPv4 IoC. Args: value (str): string ^[a-f0-9]{64}$. Returns: Enrichment information. """ url_suffix = f"/ioc/api/v1/ipv4?value={value}" demisto.debug(f"URL to retrieve IPv4 IoC: {url_suffix}") response = self._http_request( method="GET", url_suffix=url_suffix, cookies=self._cookies, timeout=120, retries=3, ) return response @logger def retrieve_url_from_api(self, value: str) -> dict[str, Any]: """ Makes the API request to retrieve URL IoC. Args: value (str): string. Returns: Enrichment information. """ url_suffix = f"/ioc/api/v1/url?value={value}" demisto.debug(f"URL to retrieve URL IoC: {url_suffix}") response = self._http_request( method="GET", url_suffix=url_suffix, cookies=self._cookies, timeout=120, retries=3, ) return response @logger def retrieve_cve_intelligence(self, cve_id: str) -> dict[str, Any]: """ Makes the API request to retrieve enriched CVE intelligence. Args: cve_id (str): The CVE identifier (e.g. CVE-2024-1234). Returns: CVE intelligence information (a VulnerabilityDetail object). """ url_suffix = f"/cve-intel/external/api/v1/vulnerability/{cve_id}" demisto.debug(f"URL to retrieve CVE intelligence: {url_suffix}") return self._http_request( method="GET", url_suffix=url_suffix, cookies=self._cookies, timeout=120, retries=3, ) @logger def retrieve_leaked_credentials_by_domain(self, domain: str) -> dict[str, Any]: """ Makes the API request to retrieve leaked credentials for a company domain. Args: domain (str): The company domain to search leaked credentials for. Returns: Leaked credentials information (a Response[ByDomainData] object). """ url_suffix = "/exposed-credentials/by_domain/" demisto.debug(f"URL to retrieve leaked credentials: {url_suffix}") return self._http_request( method="POST", url_suffix=url_suffix, json_data={"domain": domain}, cookies=self._cookies, timeout=120, retries=3, ) def test_module(client: Client, feed_enabled: Optional[bool]) -> str: """ Builds the iterator to check that the feed is accessible. Args: client: Client object. Returns: Outputs. """ try: if feed_enabled: demisto.info("Feed is enabled. Check that the feed is accessible.") client.request_daily_feed(limit=10, test=True) else: demisto.info("Feed is disabled. Check that the enrichment is accessible.") client.retrieve_domain_from_api("checkpoint.com") except DemistoException as exc: if exc.res and (exc.res.status_code == http.HTTPStatus.UNAUTHORIZED or exc.res.status_code == http.HTTPStatus.FORBIDDEN): return "Authorization Error: invalid `API Token`" raise exc return "ok" def fetch_indicators( client: Client, tlp_color: str, feed_names: list[str], indicator_types: list[str], confidence_from: int, severity_from: int, date_time: str = None, feed_tags: List = [], limit: int = -1, execution_start_time: datetime = datetime.now(), ) -> list[dict[str, Any]]: """ Retrieves indicators from the feed. Args: client (Client): API Client. tlp_color (str): The Traffic Light Protocol (TLP) designation to apply to indicators fetched from the feed. feed_names (list): The feed names. indicator_types (list): Which indicator types to fetch. confidence_from (int): The value of confidence to fetch indicators from. severity_from (int): The value of severity to fetch indicators from. date_time (str): Date time string to fetch indicators from. feed_tags (list): tags to assign fetched indicators. limit (int): The maximum number of results to return. execution_start_time (datetime): The start time of the execution. Defaults to now. Returns: Indicators. """ demisto.debug("Fetching indicators") iterator = client.request_daily_feed(date_time, limit=PAGE_SIZE, execution_start_time=execution_start_time) indicators = [] for item in iterator: if ( ("All" in indicator_types or item.get("ioc_type") in indicator_types) and ("All" in feed_names or item.get("detected_activity") in feed_names) and (item.get("confidence") >= confidence_from) and (item.get("severity_score") >= severity_from) ): indicator_value = item["ioc_value"] if indicator_type := auto_detect_indicator_type(indicator_value): indicator_obj = { "type": indicator_type, "value": indicator_value, "service": "Cyberint", "rawJSON": item, "fields": { "reportedby": "Cyberint", "firstseenbysource": item.get("observation_date"), "detected_activity": item.get("detected_activity"), "severity_score": item.get("severity_score"), "confidence": item.get("confidence"), "description": item.get("description"), }, } if feed_tags: indicator_obj["fields"]["tags"] = feed_tags if tlp_color: indicator_obj["fields"]["trafficlightprotocol"] = tlp_color indicators.append(indicator_obj) if limit > 0 and len(indicators) >= limit: demisto.debug(f"Indicators limit reached (total): {len(indicators)}") break return indicators def get_indicators_command( client: Client, args: dict[str, Any], ) -> CommandResults: """ Wrapper for retrieving indicators from the feed to the war-room. Args: client: Cyberint API Client. args: Command arguments. Returns: Outputs indicators. """ date = args.get("date") or datetime.now().strftime("%Y-%m-%d") limit = int(args.get("limit", 0)) offset = int(args.get("offset", 0)) indicators = client.process_feed_response(date, limit, offset) human_readable = tableToMarkdown( "Indicators from Cyberint Feed:", indicators, headers=["detected_activity", "ioc_type", "ioc_value", "observation_date", "severity_score", "confidence", "description"], headerTransform=ioc_header_transformer, removeNull=False, ) return CommandResults( readable_output=human_readable, outputs_prefix="Cyberint.indicator", outputs_key_field="value", raw_response=indicators, outputs=indicators, ) def get_url_command( client: Client, args: dict[str, Any], ) -> CommandResults: """ Wrapper for retrieving enrichment for URL from the feed to the war-room. Args: client: Cyberint API Client. args: Command arguments. Returns: Outputs indicators. """ value = args.get("value", "") indicator = client.retrieve_url_from_api(value) indicator_data = indicator.get("data", {}) indicator_formatted = [ { "type": indicator_data.get("entity", {}).get("type"), "value": indicator_data.get("entity", {}).get("value"), "malicious_score": (indicator_data.get("risk") or {}).get("malicious_score"), "occurrences_count": (indicator_data.get("risk") or {}).get("occurrences_count"), "ips": (indicator_data.get("enrichment") or {}).get("ips"), "hostname": (indicator_data.get("enrichment") or {}).get("hostname"), "domain": (indicator_data.get("enrichment") or {}).get("domain"), "benign": indicator_data.get("benign"), } ] human_readable = tableToMarkdown( "URL Entity", indicator_formatted, headers=["type", "value", "malicious_score", "occurrences_count", "ips", "hostname", "domain", "benign"], headerTransform=indicator_header_transformer, removeNull=False, ) detected_activities: list = (indicator_data.get("risk", {}) or {}).get("detected_activities", []) for activity in detected_activities: activity = activity or {} activities_formatted = [ { "type": activity.get("type", ""), "observation_date": activity.get("observation_date", ""), "description": activity.get("description", ""), "confidence": activity.get("confidence", ""), "occurrences_count": activity.get("occurrences_count", ""), } ] human_readable += tableToMarkdown( "URL Detected activities", activities_formatted, date_fields=["observation_date"], headers=["type", "observation_date", "description", "confidence", "occurrences_count"], headerTransform=indicator_header_transformer, removeNull=False, ) related_entities: list = (indicator_data.get("enrichment", {}) or {}).get("related_entities", []) or [] for entity in related_entities: entity = entity or {} entities_formatted = [ { "entity_id": entity.get("entity_id", ""), "entity_type": entity.get("entity_type", ""), "entity_name": entity.get("entity_name", ""), } ] human_readable += tableToMarkdown( "URL Related Entities", entities_formatted, headers=["entity_id", "entity_type", "entity_name"], headerTransform=indicator_header_transformer, removeNull=False, ) return CommandResults( readable_output=human_readable, outputs_prefix="Cyberint.url", outputs_key_field="value", raw_response=indicator_data, outputs=indicator_data, ) def get_ipv4_command( client: Client, args: dict[str, Any], ) -> CommandResults: """ Wrapper for retrieving enrichment for Domain from the feed to the war-room. Args: client: Cyberint API Client. args: Command arguments. Returns: Outputs indicators. """ value = args.get("value", "") indicator = client.retrieve_ipv4_from_api(value) indicator_data = indicator.get("data", {}) indicator_formatted = [ { "type": indicator_data.get("entity", {}).get("type"), "value": indicator_data.get("entity", {}).get("value"), "malicious_score": (indicator_data.get("risk") or {}).get("malicious_score"), "occurrences_count": (indicator_data.get("risk") or {}).get("occurrences_count"), "country": (indicator_data.get("enrichment", {}).get("geo") or {}).get("country"), "city": (indicator_data.get("enrichment", {}).get("geo") or {}).get("city"), "asn_number": (indicator_data.get("enrichment", {}).get("asn") or {}).get("number"), "asn_organization": (indicator_data.get("enrichment", {}).get("asn") or {}).get("organization"), "suspicious_urls": indicator_data.get("enrichment", {}).get("suspicious_urls", []), "suspicious_domains": indicator_data.get("enrichment", {}).get("suspicious_domains", []), "benign": indicator_data.get("benign"), } ] human_readable = tableToMarkdown( "IPv4 Entity", indicator_formatted, headers=[ "type", "value", "malicious_score", "occurrences_count", "country", "city", "asn_number", "asn_organization", "benign", ], headerTransform=indicator_header_transformer, removeNull=False, ) human_readable += tableToMarkdown( "IPv4 Enrichment", indicator_formatted, headers=["suspicious_urls", "suspicious_domains"], headerTransform=indicator_header_transformer, removeNull=False, ) detected_activities: list = (indicator_data.get("risk", {}) or {}).get("detected_activities", []) for activity in detected_activities: activity = activity or {} activities_formatted = [ { "type": activity.get("type", ""), "observation_date": activity.get("observation_date", ""), "description": activity.get("description", ""), "confidence": activity.get("confidence", ""), "occurrences_count": activity.get("occurrences_count", ""), } ] human_readable += tableToMarkdown( "IPv4 Detected activities", activities_formatted, date_fields=["observation_date"], headers=["type", "observation_date", "description", "confidence", "occurrences_count"], headerTransform=indicator_header_transformer, removeNull=False, ) related_entities: list = (indicator_data.get("risk", {}) or {}).get("related_entities", []) for entity in related_entities: entity = entity or {} entities_formatted = [ { "entity_id": entity.get("entity_id", ""), "entity_type": entity.get("entity_type", ""), "entity_name": entity.get("entity_name", ""), } ] human_readable += tableToMarkdown( "Domain Related Entities", entities_formatted, headers=["entity_id", "entity_type", "entity_name"], headerTransform=indicator_header_transformer, removeNull=False, ) return CommandResults( readable_output=human_readable, outputs_prefix="Cyberint.ipv4", outputs_key_field="value", raw_response=indicator_data, outputs=indicator_data, ) def get_domain_command( client: Client, args: dict[str, Any], ) -> CommandResults: """ Wrapper for retrieving enrichment for Domain from the feed to the war-room. Args: client: Cyberint API Client. args: Command arguments. Returns: Outputs indicators. """ value = args.get("value", "") indicator = client.retrieve_domain_from_api(value) indicator_data = indicator.get("data", {}) indicator_formatted = [ { "type": (indicator_data.get("entity") or {}).get("type"), "value": (indicator_data.get("entity") or {}).get("value"), "malicious_score": (indicator_data.get("risk") or {}).get("malicious_score"), "ips": (indicator_data.get("enrichment") or {}).get("ips"), "occurrences_count": (indicator_data.get("risk") or {}).get("occurrences_count"), "registrant_name": (indicator_data.get("enrichment", {}).get("whois") or {}).get("registrant_name"), "registrant_email": (indicator_data.get("enrichment", {}).get("whois") or {}).get("registrant_email"), "registrant_organization": (indicator_data.get("enrichment", {}).get("whois") or {}).get("registrant_organization"), "registrant_country": (indicator_data.get("enrichment", {}).get("whois") or {}).get("registrant_country"), "registrant_telephone": (indicator_data.get("enrichment", {}).get("whois") or {}).get("registrant_telephone"), "technical_contact_email": (indicator_data.get("enrichment", {}).get("whois") or {}).get("technical_contact_email"), "technical_contact_name": (indicator_data.get("enrichment", {}).get("whois") or {}).get("technical_contact_name"), "technical_contact_organization": (indicator_data.get("enrichment", {}).get("whois") or {}).get( "technical_contact_organization" ), "registrar_name": (indicator_data.get("enrichment", {}).get("whois") or {}).get("registrar_name"), "admin_contact_name": (indicator_data.get("enrichment", {}).get("whois") or {}).get("admin_contact_name"), "admin_contact_organization": (indicator_data.get("enrichment", {}).get("whois") or {}).get( "admin_contact_organization" ), "admin_contact_email": (indicator_data.get("enrichment", {}).get("whois") or {}).get("admin_contact_email"), "created_date": (indicator_data.get("enrichment", {}).get("whois") or {}).get("created_date"), "updated_date": (indicator_data.get("enrichment", {}).get("whois") or {}).get("updated_date"), "expiration_date": (indicator_data.get("enrichment", {}).get("whois") or {}).get("expiration_date"), "benign": indicator_data.get("benign"), } ] human_readable = tableToMarkdown( "Domain Entity", indicator_formatted, headers=["type", "value", "malicious_score", "occurrences_count", "benign"], headerTransform=indicator_header_transformer, removeNull=False, ) human_readable += tableToMarkdown( "Domain Enrichment", indicator_formatted, date_fields=["created_date", "updated_date", "expiration_date"], headers=[ "ips", "registrant_name", "registrant_email", "registrant_organization", "registrant_country", "registrant_telephone", "technical_contact_email", "technical_contact_name", "technical_contact_organization", "registrar_name", "admin_contact_name", "admin_contact_organization", "admin_contact_email", "created_date", "updated_date", "expiration_date", ], headerTransform=indicator_header_transformer, removeNull=False, ) detected_activities: list = (indicator_data.get("risk", {}) or {}).get("detected_activities", []) for activity in detected_activities or []: activities_formatted = [ { "type": (activity or {}).get("type", ""), "observation_date": (activity or {}).get("observation_date", ""), "description": (activity or {}).get("description", ""), "confidence": (activity or {}).get("confidence", ""), "occurrences_count": (activity or {}).get("occurrences_count", ""), } ] human_readable += tableToMarkdown( "Domain Detected activities", activities_formatted, date_fields=["observation_date"], headers=["type", "observation_date", "description", "confidence", "occurrences_count"], headerTransform=indicator_header_transformer, removeNull=False, ) related_entities: list = (indicator_data.get("risk", {}) or {}).get("related_entities", []) for entity in related_entities or []: entities_formatted = [ { "entity_id": (entity or {}).get("entity_id", ""), "entity_type": (entity or {}).get("entity_type", ""), "entity_name": (entity or {}).get("entity_name", ""), } ] human_readable += tableToMarkdown( "Domain Related Entities", entities_formatted, headers=["entity_id", "entity_type", "entity_name"], headerTransform=indicator_header_transformer, removeNull=False, ) return CommandResults( readable_output=human_readable, outputs_prefix="Cyberint.domain", outputs_key_field="value", raw_response=indicator_data, outputs=indicator_data, ) def get_file_sha256_command( client: Client, args: dict[str, Any], ) -> CommandResults: """ Wrapper for retrieving enrichment for file SHA256 hash from the feed to the war-room. Args: client: Cyberint API Client. args: Command arguments. Returns: Outputs indicators. """ value = args.get("value", "") indicator = client.retrieve_file_sha256_from_api(value) indicator_data = indicator.get("data", {}) indicator_formatted = [ { "type": indicator_data.get("entity", {}).get("type", ""), "value": indicator_data.get("entity", {}).get("value", ""), "malicious_score": indicator_data.get("risk", {}).get("malicious_score", ""), "filenames": indicator_data.get("enrichment", {}).get("filenames", []), "first_seen": indicator_data.get("enrichment", {}).get("first_seen", ""), "download_urls": indicator_data.get("enrichment", {}).get("download_urls", []), "benign": indicator_data.get("benign", ""), } ] human_readable = tableToMarkdown( "File SHA256 Entity", indicator_formatted, headers=["type", "value", "malicious_score", "benign"], headerTransform=indicator_header_transformer, removeNull=False, ) human_readable += tableToMarkdown( "File SHA256 Enrichment", indicator_formatted, date_fields=["first_seen"], headers=["filenames", "first_seen", "download_urls"], headerTransform=indicator_header_transformer, removeNull=False, ) detected_activities: list = (indicator_data.get("risk", {}) or {}).get("detected_activities", []) for activity in detected_activities or []: activity = activity or {} activities_formatted = [ { "type": activity.get("type", ""), "observation_date": activity.get("observation_date", ""), "description": activity.get("description", ""), "confidence": activity.get("confidence", ""), "occurrences_count": activity.get("occurrences_count", ""), } ] human_readable += tableToMarkdown( "File SHA256 Detected activities", activities_formatted, date_fields=["observation_date"], headers=["type", "observation_date", "description", "confidence", "occurrences_count"], headerTransform=indicator_header_transformer, removeNull=False, ) related_entities: list = (indicator_data.get("risk", {}) or {}).get("related_entities", []) for entity in related_entities or []: entity = entity or {} entities_formatted = [ { "entity_id": entity.get("entity_id", ""), "entity_type": entity.get("entity_type", ""), "entity_name": entity.get("entity_name", ""), } ] human_readable += tableToMarkdown( "File SHA256 Related Entities", entities_formatted, headers=["entity_id", "entity_type", "entity_name"], headerTransform=indicator_header_transformer, removeNull=False, ) return CommandResults( readable_output=human_readable, outputs_prefix="Cyberint.file_sha256", outputs_key_field="value", raw_response=indicator_data, outputs=indicator_data, ) def fetch_indicators_command( client: Client, params: dict[str, Any], ) -> list[dict[str, Any]]: """ Wrapper for fetching indicators from the feed to the Indicators tab. Args: client: Cyberint API Client. params: Integration parameters. Returns: Indicators. """ feed_enabled = params.get("feed", True) tlp_color = params.get("tlp_color", "") feed_tags = argToList(params.get("feedTags")) severity_from = arg_to_number(params.get("severity_from")) or 0 confidence_from = arg_to_number(params.get("confidence_from")) or 0 feed_names = argToList(params.get("feed_name")) indicator_types = argToList(params.get("indicator_type")) fetch_interval = arg_to_number(params.get("feedFetchInterval")) or DEFAULT_INTERVAL indicators = [] if feed_enabled: # if now-interval is yesterday, call feeds for yesterday too if is_x_minutes_ago_yesterday(fetch_interval): indicators = fetch_indicators( client=client, date_time=get_yesterday_time(), tlp_color=tlp_color, feed_tags=feed_tags, feed_names=feed_names, indicator_types=indicator_types, severity_from=severity_from, confidence_from=confidence_from, ) indicators += fetch_indicators( client=client, tlp_color=tlp_color, feed_tags=feed_tags, feed_names=feed_names, indicator_types=indicator_types, severity_from=severity_from, confidence_from=confidence_from, ) return indicators def get_today_time() -> str: """Get current date time. Returns: str: Today date string. """ return datetime.now().strftime(DATE_FORMAT) def get_yesterday_time() -> str: """Get yesterday date time. Returns: str: Yesterday date string. """ current_time = datetime.now() yesterday = current_time - timedelta(days=1) return yesterday.strftime(DATE_FORMAT) def is_x_minutes_ago_yesterday(minutes: int) -> bool: """Check if x minutes ago is yesterday. Args: minutes (int): The amount of minutes to reduce from today. Returns: bool: True if x minutes ago is yesterday, else False. """ current_time = datetime.now() x_minutes_ago = current_time - timedelta(minutes=minutes) yesterday = current_time - timedelta(days=1) return x_minutes_ago.date() == yesterday.date() def pick_cvss_collection(cvss: dict[str, Any]) -> tuple[Optional[float], Optional[str], Optional[str]]: """ Picks the most relevant CVSS base score and the matching version + vector string from a Cyberint CVSS object. Preference order: v4, then v3, then v2. Args: cvss (dict): The CVSS object from a Cyberint VulnerabilityDetail response. Returns: A tuple of (base_score, version, vector_string) all from the same CVSS collection, or (None, None, None). """ for version_key in ("cvss_v4", "cvss_v3", "cvss_v2"): collection = cvss.get(version_key) or {} if collection.get("base_score") is not None: return collection.get("base_score"), collection.get("version"), collection.get("vector_string") return None, None, None def get_cve_command(client: Client, args: dict[str, Any]) -> list[CommandResults]: """ Enriches one or more CVE identifiers with Cyberint vulnerability intelligence. Args: client: Cyberint API Client. args: Command arguments. Expects a 'cve_id' argument (CSV supported). Returns: One CommandResults entry per CVE. """ cve_ids = argToList(args.get("cve_id")) if not cve_ids: raise DemistoException("You must supply at least one CVE identifier in the 'cve_id' argument.") command_results: list[CommandResults] = [] for cve_id in cve_ids: raw_response = client.retrieve_cve_intelligence(cve_id) cve_data = raw_response.get("data", raw_response) if isinstance(raw_response, dict) else {} cve_data = cve_data or {} # Ensure the CVE identifier is always present in the output, even for a sparse response. cve_data.setdefault("cve_id", cve_id) cvss = cve_data.get("cvss") or {} base_score, cvss_version, cvss_vector = pick_cvss_collection(cvss) cwes = cve_data.get("cwes") or [] cwe_ids = [item.get("cwe_id") if isinstance(item, dict) else item for item in cwes] exploited_by = cve_data.get("exploited_by") or [] actor_names = [item.get("name") if isinstance(item, dict) else item for item in exploited_by] indicator = Common.CVE( id=cve_data.get("cve_id", cve_id), cvss=base_score, cvss_score=base_score, cvss_version=cvss_version, cvss_vector=cvss_vector, published=cve_data.get("published"), modified=cve_data.get("last_updated"), description=cve_data.get("description"), ) human_readable = tableToMarkdown( f"Cyberint CVE Intelligence: {cve_id}", { "CVE ID": cve_data.get("cve_id"), "Cyberint Score": cve_data.get("cyberint_score"), "CVSS Score": base_score, "EPSS": cve_data.get("epss"), "CWE": ", ".join(filter(None, cwe_ids)), "Risk Factors": ", ".join(cve_data.get("risk_factors") or []), "Exploited By": ", ".join(filter(None, actor_names)), "Affected Products": ", ".join(cve_data.get("products") or []), "Published": cve_data.get("published"), }, removeNull=True, ) command_results.append( CommandResults( outputs_prefix="Cyberint.CVE", outputs_key_field="cve_id", outputs=cve_data, readable_output=human_readable, raw_response=raw_response, indicator=indicator, ) ) return command_results def summarize_credential_records(records: list[dict[str, Any]]) -> list[dict[str, Any]]: """ Builds a password-free summary of leaked-credential records for human-readable output. Args: records (list): Leaked-credential records (LeakedCredentialRecord objects). Returns: A list of summary dictionaries, one per record. """ summary = [] for record in records: entries = record.get("entries") or [] summary.append( { "Username": record.get("username"), "First Seen": record.get("first_seen"), "Last Seen": record.get("last_seen"), "Exposures": len(entries), "Sources": ", ".join(sorted({entry.get("source") for entry in entries if entry.get("source")})), } ) return summary def filter_credentials_by_last_seen( records: list[dict[str, Any]], last_seen_from: Optional[str], last_seen_to: Optional[str] ) -> list[dict[str, Any]]: """ Filters leaked-credential records by their 'last seen' date. The leaked-credentials by_domain API does not support date filtering server-side, so it is applied here. Args: records (list): Leaked-credential records. last_seen_from (str): Optional lower bound for the record 'last seen' date. last_seen_to (str): Optional upper bound for the record 'last seen' date. Returns: The filtered list of records. """ if not last_seen_from and not last_seen_to: return records start = arg_to_datetime(last_seen_from) end = arg_to_datetime(last_seen_to) filtered = [] for record in records: last_seen = arg_to_datetime(record.get("last_seen")) if last_seen is None: continue if start and last_seen < start: continue if end and last_seen > end: continue filtered.append(record) return filtered def get_leaked_credentials_by_domain_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Looks up leaked employee and customer credentials associated with a company domain. Args: client: Cyberint API Client. args: Command arguments. Expects 'domain'; optionally 'last_seen_from', 'last_seen_to' and 'limit'. Returns: Outputs the leaked credentials. """ domain = args.get("domain") if not domain: raise DemistoException("You must supply a 'domain' argument.") last_seen_from = args.get("last_seen_from") last_seen_to = args.get("last_seen_to") limit = arg_to_number(args.get("limit")) raw_response = client.retrieve_leaked_credentials_by_domain(domain) data = raw_response.get("data") if isinstance(raw_response, dict) else None data = data or {} employee_records = (data.get("employee") or {}).get("raw_data") or [] customer_records = (data.get("customer") or {}).get("raw_data") or [] employee_records = filter_credentials_by_last_seen(employee_records, last_seen_from, last_seen_to) customer_records = filter_credentials_by_last_seen(customer_records, last_seen_from, last_seen_to) if limit: employee_records = employee_records[:limit] customer_records = customer_records[:limit] outputs = { "domain": domain, "employee_total": len(employee_records), "customer_total": len(customer_records), "total": len(employee_records) + len(customer_records), "employee_credentials": employee_records, "customer_credentials": customer_records, } # Passwords are intentionally excluded from the readable tables to avoid exposing them in the war room. human_readable = f"### Cyberint Leaked Credentials for {domain}\n" human_readable += f"Employee credentials: {len(employee_records)} | Customer credentials: {len(customer_records)}\n" human_readable += tableToMarkdown("Employee Credentials", summarize_credential_records(employee_records), removeNull=True) human_readable += tableToMarkdown("Customer Credentials", summarize_credential_records(customer_records), removeNull=True) return CommandResults( outputs_prefix="Cyberint.LeakedCredential", outputs_key_field="domain", outputs=outputs, readable_output=human_readable, raw_response=raw_response, ) @logger def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ params = demisto.params() args = demisto.args() base_url = params.get("url") access_token = params.get("access_token").get("password") insecure = not params.get("insecure", False) proxy = params.get("proxy", False) feed_enabled = demisto.params().get("feed", True) command = demisto.command() demisto.debug(f"Command being called is {command}") try: client = Client( base_url=base_url, access_token=access_token, verify=insecure, proxy=proxy, ) if command == "test-module": return_results(test_module(client, feed_enabled)) elif command == "cyberint-get-indicators": return_results(get_indicators_command(client, args)) elif command == "cyberint-get-file-sha256": return_results(get_file_sha256_command(client, args)) elif command == "cyberint-get-domain": demisto.debug("cyberint-get-domain") return_results(get_domain_command(client, args)) elif command == "cyberint-get-ipv4": demisto.debug("cyberint-get-ipv4") return_results(get_ipv4_command(client, args)) elif command == "cyberint-get-url": demisto.debug("cyberint-get-url") return_results(get_url_command(client, args)) elif command == "cyberint-cve-enrich": demisto.debug("cyberint-cve-enrich") return_results(get_cve_command(client, args)) elif command == "cyberint-credential-leak-lookup": demisto.debug("cyberint-credential-leak-lookup") return_results(get_leaked_credentials_by_domain_command(client, args)) elif command == "fetch-indicators": indicators = fetch_indicators_command(client, params) demisto.debug(f"Total {len(indicators)} indicators to be submitted") for iter_ in batch(indicators, batch_size=5000): demisto.debug(f"Submit {len(iter_)} indicators to XSOAR") demisto.createIndicators(iter_) demisto.debug("Fetch indicators operation completed") else: raise NotImplementedError(f"Command {command} is not implemented.") except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{e!s}") @logger def is_execution_time_exceeded(start_time: datetime) -> bool: """ Checks if the execution time so far exceeded the timeout limit. Args: start_time (datetime): the time when the execution started. Returns: bool: true, if execution passed timeout settings, false otherwise. """ end_time = datetime.now() secs_from_beginning = (end_time - start_time).seconds demisto.debug(f"Execution duration is {secs_from_beginning} secs so far") return secs_from_beginning > EXECUTION_TIMEOUT_SECONDS def ioc_header_transformer(header: str) -> str: """ Returns a correct header. Args: header (Str): header. Returns: header (Str). """ if header == "detected_activity": return "Detected activity" if header == "ioc_type": return "IoC type" if header == "ioc_value": return "IoC value" if header == "observation_date": return "Observation date" if header == "severity_score": return "Severity score" if header == "confidence": return "Confidence" if header == "description": return "Description" return string_to_table_header(header) def indicator_header_transformer(header: str) -> str: """ Returns a correct header. Args: header (Str): header. Returns: header (Str). """ if header == "type": return "Type" if header == "value": return "Value" if header == "malicious_score": return "Malicious score" if header == "detected_activities": return "Detected activities" if header == "related_entities": return "Related entities" if header == "filenames": return "Filenames" if header == "first_seen": return "First seen" if header == "download_urls": return "Download URLs" if header == "benign": return "Benign" if header == "observation_date": return "Observation date" if header == "occurrences_count": return "Occurrences count" if header == "ips": return "IPs" if header == "registrant_name": return "Whois registrant name" if header == "registrant_email": return "Whois registrant email" if header == "registrant_organization": return "Whois registrant organization" if header == "registrant_country": return "Whois registrant country" if header == "registrant_telephone": return "Whois registrant telephone" if header == "technical_contact_email": return "Whois technical contact email" if header == "technical_contact_name": return "Whois technical contact name" if header == "technical_contact_organization": return "Whois technical contact organization" if header == "registrar_name": return "Whois registrar name" if header == "admin_contact_name": return "Whois admin contact name" if header == "admin_contact_organization": return "Whois admin contact organization" if header == "admin_contact_email": return "Whois admin contact email" if header == "created_date": return "Created date" if header == "updated_date": return "Updated date" if header == "expiration_date": return "Expiration date" if header == "hostname": return "Hostname" if header == "domain": return "Domain" if header == "asn_number": return "ASN number" if header == "asn_organization": return "ASN organization" return string_to_table_header(header) if __name__ in ["__main__", "builtin", "builtins"]: main()