LastInfoSec
This integration allow to interact with the Gatewatcher LastInfoSec product via API.
Network Security · LastInfoSec
Details
| ID | LastInfoSec |
|---|---|
| Provider | Gatewatcher |
| Category | Network Security |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
This integration allow to interact with the Gatewatcher LastInfoSec product via API.
This integration was integrated and tested with version 2 of LastInfoSec.
Configure LastInfoSec in Cortex
| Parameter | Description | Required |
|---|---|---|
| LastInfoSec API token | The API Key to use for connection | True |
| Check the TLS certificate | False | |
| Use system proxy settings | False | |
| Integration Reliability | Reliability of the source providing the intelligence data | 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.
gw-lis-get-by-minute
Retrieve the data from Gatewatcher CTI feed by minute.
Max 1440 minutes.
Base Command
gw-lis-get-by-minute
Input
| Argument Name | Description | Required |
|---|---|---|
| Minute | Number of minutes to get. Max 1440 minutes. |
Required |
| Categories | Filter IoC by categories. Possible values are: phishing, malware, trojan, exploit, ransom, ransomware, tool, keylogger, agent, backdoor. | Optional |
| Type | Filter IoC by type. Possible values are: SHA1, SHA256, MD5, URL, Host. | Optional |
| Mode | Filter IoC by mode. Possible values are: detection, hunting. | Optional |
| Risk | Filter IoC by risk. Possible values are: Malicious, Suspicious, High suspicious. | Optional |
| TLP | Filter IoC by TLP. Possible values are: green, white. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| LIS.GetByMinute.Value | String | Value. |
Command example
!gw-lis-get-by-minute Minute=10
Context Example
{
"LIS": {
"GetByMinute": [
"http://103.182.16.23/900/HTMLcode.vbs",
"http://103.182.16.23/900/i0ioi0iooioo0IOI0OIOIOiooioi00IOIoioioio0ioi0iOIOioiiOIoiOIOIOioIO0IOIO0.doc",
"http://94.156.253.128/2144/io0Ioi0IOIOOIOi0i00ioioii0ioi0oiOII0OIO0OIOI0I0000%23%23%23%23%23%23%23%23%23%23%23%23%23%230000000%23%23%23%23%23%23%23%23%23%23%23%23%23%2300000000.doc",
]
}
}
Human Readable Output
Get IoC by minute
Value http://103.182.16.23/900/HTMLcode.vbs http://103.182.16.23/900/i0ioi0iooioo0IOI0OIOIOiooioi00IOIoioioio0ioi0iOIOioiiOIoiOIOIOioIO0IOIO0.doc http://94.156.253.128/2144/io0Ioi0IOIOOIOi0i00ioioii0ioi0oiOII0OIO0OIOI0I0000%23%23%23%23%23%23%23%23%23%23%23%23%23%230000000%23%23%23%23%23%23%23%23%23%23%23%23%23%2300000000.doc
gw-lis-get-by-value
Allows you to search for an IOC (url, hash, host) or a vulnerability in the Gatewatcher CTI database. If the data is known, only the IOC corresponding to the value will be returned.
Base Command
gw-lis-get-by-value
Input
| Argument Name | Description | Required |
|---|---|---|
| Value | Value to be search. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| LIS.GetByValue.Categories | String | Categories. |
| LIS.GetByValue.Risk | String | Risk. |
| LIS.GetByValue.TLP | String | TLP. |
| LIS.GetByValue.Type | String | Type. |
| LIS.GetByValue.UsageMode | String | UsageMode. |
| LIS.GetByValue.Value | String | Value. |
| LIS.GetByValue.Vulnerabilities | String | Vulnerabilities. |
Command example
!gw-lis-get-by-value Value="58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f"
Context Example
{
"LIS": {
"GetByValue": {
"Categories": [
"trojan",
"malware",
"agent"
],
"Risk": "Suspicious",
"TLP": "green",
"Type": "SHA256",
"UsageMode": "detection",
"Value": "58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f",
"Vulnerabilities": []
}
}
}
Human Readable Output
Get IoC corresponding to the value
Categories Risk TLP Type UsageMode Value Vulnerabilities trojan,
malware,
agentSuspicious green SHA256 detection 58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f
gw-lis-leaked-email-by-domain
Allows you to search for leaked emails via a domain in Gatewatcher’s CTI database. If the data is found, a list of emails is returned. otherwise, nothing is returned.
Base Command
gw-lis-leaked-email-by-domain
Input
| Argument Name | Description | Required |
|---|---|---|
| Domain | domain to be searched. | Required |
| After | Only return emails that have leaked after this date (date format: 2023-01-15T10:00:00). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| LIS.LeakedEmail.GetByDomain | String | leaked emails. |
Command example
!gw-lis-leaked-email-by-domain Domain=foobar.com
Context Example
{
"LIS": {
"LeakedEmail": {
"GetByDomain": [
"lucien@fr.foobar.com",
"valerie@fr.foobar.com",
"cyrille@nl.foobar.com",
"patrique@us.foobar.com",
]
}
}
}
Human Readable Output
Leaked email
Emails lucien@fr.foobar.com valerie@fr.foobar.com cyrille@nl.foobar.com patrique@us.foobar.com
gw-lis-is-email-leaked
Allows you to search if a specific email was leaked in Gatewatcher’s CTI database. If the data is found, the email is returned. otherwise, nothing is returned.
Base Command
gw-lis-is-email-leaked
Input
| Argument Name | Description | Required |
|---|---|---|
| email to be searched. | Required | |
| After | Only return a value if the email has leaked after this date (date format: 2023-01-15T10:00:00). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| LIS.LeakedEmail.GetByEmail | String | leaked email. |
Command example
!gw-lis-is-email-leaked Email=lucien@fr.foobar.com
Context Example
{
"LIS": {
"LeakedEmail": {
"GetByEmail": "lucien@fr.foobar.com"
}
}
}
Human Readable Output
Is email leaked
Value lucien@fr.foobar.com
url
search IOCs for URLs in Gatewatcher’s CTI database.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | list of URLs to search for, (comma separated values). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| URL.Data | String | The URL. |
| URL.Description | String | Description of the URL. |
| URL.TrafficLightProtocol | String | TLP level. |
| LIS.URL.Categories | String | Categories matching this url. |
| LIS.URL.Risk | String | Risk associated to this URL. |
| LIS.URL.TLP | String | TLP level. |
| LIS.URL.UsageMode | String | Usage mode for LIS. |
| LIS.URL.Value | String | The URL. |
| LIS.URL.Vulnerabilities | String | Vulnerabilities associated to this URL. |
Command example
!url url=http://217.196.96.84/WatchDog.exe
Context Example
{
"DBotScore": {
"Indicator": "http://217.196.96.84/WatchDog.exe",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "url",
"Vendor": "LastInfoSec"
},
"LIS": {
"URL": {
"Categories": [
"malware"
],
"Risk": "Suspicious",
"TLP": "green",
"Type": "URL",
"UsageMode": "detection",
"Value": "http://217.196.96.84/WatchDog.exe",
"Vulnerabilities": []
}
},
"URL": {
"Data": "http://217.196.96.84/WatchDog.exe",
"Description": "'http://217.196.96.84/WatchDog.exe' is a Suspicious URL. It is linked to a PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows file with a size of 62.0322265625 KB.\nThis URL is linked to a malware attack.\nThe related TTP is: T1027.002 .\nWe advised to use this IoC in detection mode.",
"TrafficLightProtocol": "green"
}
}
Human Readable Output
Get IoC corresponding to the value
Categories Risk TLP Type UsageMode Value Vulnerabilities malware Suspicious green URL detection http://217.196.96.84/WatchDog.exe
file
search IOCs for file hashes in Gatewatcher’s CTI database.
Base Command
file
Input
| Argument Name | Description | Required |
|---|---|---|
| file | list of files to search for, (comma separated values). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| File.Hashes | String | List of hashes for this file. |
| File.Imphash | String | Imphash of the file. |
| File.SSDeep | String | SSDeep of the file. |
| File.TrafficLightProtocol | String | TLP level. |
| File.Type | String | Type of file. |
| File.MD5 | String | MD5 of the file. |
| File.SHA1 | String | SHA1 of the file. |
| File.SHA256 | String | SHA256 of the file. |
| File.SHA512 | String | SHA512 of the file. |
| LIS.File.Categories | String | Categories matching this file. |
| LIS.File.Risk | String | Risk associated to this file. |
| LIS.File.TLP | String | TLP level. |
| LIS.File.UsageMode | String | Usage mode for LIS. |
| LIS.File.Value | String | Hash of the file. |
| LIS.File.Vulnerabilities | String | Vulnerabilities associated to this file. |
| DBotScore.Indicator | String | The indicator that was tested. |
Command example
!file file=58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f
Context Example
{
"DBotScore": {
"Indicator": "58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "file",
"Vendor": "LastInfoSec"
},
"File": {
"Hashes": [
{
"type": "SHA256",
"value": "58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f"
},
{
"type": "SSDeep",
"value": "1536:zhu9D+Oy/Dn/hP8PGTzBwZ6YWKSO5T3rZvSwEKSK99jzpma:zhu9WL/hEPeGU5S5TbZawEKSK99jVH"
},
{
"type": "Imphash",
"value": "3:rGsLdAIEK:tf"
}
],
"Imphash": "3:rGsLdAIEK:tf",
"SHA256": "58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f",
"SSDeep": "1536:zhu9D+Oy/Dn/hP8PGTzBwZ6YWKSO5T3rZvSwEKSK99jzpma:zhu9WL/hEPeGU5S5TbZawEKSK99jVH",
"TrafficLightProtocol": "green",
"Type": "PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows"
},
"LIS": {
"File": {
"Categories": [
"trojan",
"malware",
"agent"
],
"Risk": "Suspicious",
"TLP": "green",
"Type": "SHA256",
"UsageMode": "detection",
"Value": "58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f",
"Vulnerabilities": []
}
}
}
Human Readable Output
Get IoC corresponding to the value
Categories Risk TLP Type UsageMode Value Vulnerabilities trojan,
malware,
agentSuspicious green SHA256 detection 58b525579968cba0c68e8f7ae12e51e0b5542acc2c14a2e75fa6df44556e373f
domain
search IOCs for domains in Gatewatcher’s CTI database.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | list of domains to search for, (comma separated values). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| 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. |
| Domain.Name | String | Domain found. |
| Domain.Description | String | description of the domain. |
| Domain.TrafficLightProtocol | String | TLP level. |
| LIS.Domain.Categories | String | Categories matching this domain. |
| LIS.Domain.Risk | String | Risk associated to this domain. |
| LIS.Domain.TLP | String | TLP level. |
| LIS.Domain.Type | String | Type of domain. |
| LIS.Domain.UsageMode | String | Usage mode for LIS. |
| LIS.Domain.Value | String | The domain name. |
| LIS.Domain.Vulnerabilities | String | Vulnerabilities associated to this domain. |
Command example
!domain domain=kopabayport.co.tz
Context Example
{
"DBotScore": {
"Indicator": "kopabayport.co.tz",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "domain",
"Vendor": "LastInfoSec"
},
"Domain": {
"Description": "'kopabayport.co.tz' is a Suspicious Host.\nThis Host is linked to a malware attack.\nWe advised to use this IoC in detection mode.",
"Name": "kopabayport.co.tz",
"TrafficLightProtocol": "green"
},
"LIS": {
"Domain": {
"Categories": [
"malware"
],
"Risk": "Suspicious",
"TLP": "green",
"Type": "Host",
"UsageMode": "detection",
"Value": "kopabayport.co.tz",
"Vulnerabilities": []
}
}
}
Human Readable Output
Get IoC corresponding to the value
Categories Risk TLP Type UsageMode Value Vulnerabilities malware Suspicious green Host detection kopabayport.co.tz
Configuration parameters
token— LastInfoSec API token (required)check_cert— Check the TLS certificateproxy— Use system proxy settingsintegrationReliability— Integration Reliability
Commands (7)
-
domainsearch IOCs for domains in Gatewatcher's CTI database.
-
filesearch IOCs for file hashes in Gatewatcher's CTI database.
-
gw-lis-get-by-minuteRetrieve the data from Gatewatcher CTI feed by minute. Max 1440 minutes.
-
gw-lis-get-by-valueAllows you to search for an IOC (url, hash, host) or a vulnerability in the Gatewatcher CTI database. If the data is known, only the IOC corresponding to the value will be returned.
-
gw-lis-is-email-leakedAllows you to search if a specific email was leaked in Gatewatcher's CTI database. If the data is found, the email is returned. otherwise, nothing is returned.
-
gw-lis-leaked-email-by-domainAllows you to search for leaked emails via a domain in Gatewatcher's CTI database. If the data is found, a list of emails is returned. otherwise, nothing is returned.
-
urlsearch IOCs for URLs in Gatewatcher's CTI database.
from typing import Any from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa import urllib3 # Disable insecure warnings urllib3.disable_warnings() INDICATOR_TYPE_TO_DBOT_SCORE = { "FILE": DBotScoreType.FILE, "URL": DBotScoreType.URL, "DOMAIN": DBotScoreType.DOMAIN, } INTEGRATION_NAME = "LastInfoSec" class GwAPIException(Exception): """A base class from which all other exceptions inherit. If you want to catch all errors that the gwapi_benedictine package might raise, catch this base exception. """ class GwRequests: """Allows to easily interact with HTTP server. Class features: - Get requests package wrapper. - Put requests package wrapper. - Post requests package wrapper. - Delete requests package wrapper. """ PROXIES = {"http": "", "https": ""} def __init__(self, token: str, headers: dict = {}, check_cert: bool = False, proxy: bool = False) -> None: """Init. Disable urllib3 warning. Allow unsecure ciphers. Args: check_cert: True to validate server certificate and False instead. proxies: Requests proxies. Default to no proxies. """ self.url = "api.client.lastinfosec.com/v2" self.token = token self.headers = headers self.check_cert = check_cert if proxy: self.PROXIES["http"] = os.getenv("http_proxy", "") self.PROXIES["https"] = os.getenv("https_proxy", "") def _gen_request_kwargs( self, endpoint: str, data: dict, json_data: dict, params: dict, headers: dict, cookies: dict, redirects: bool, files: dict = None, ) -> dict: """Generate requests arguments. Args: endpoint: URL endpoint in format /XX/YY/ZZ. data: request data. json_data: Set to True if data is in json_data format and False instead. params: Set to True if data need to be send with the url and False instead. headers: Set to True if redirection is allowed and False instead. cookies: Set to True if redirection is allowed and False instead. redirects: Set to True if redirection is allowed and False instead. files: files to upload in multipart/form-data Returns: Return requests arguments in dictionnary format. """ kwargs = { "url": f"https://{self.url}{endpoint}", "headers": headers if headers else self.headers, "cookies": cookies, "verify": self.check_cert, "proxies": self.PROXIES, "allow_redirects": redirects, "data": data, "json": json_data, "params": params, "files": files, } return kwargs def _get( self, endpoint: str, data: dict = None, json_data: dict = None, params: dict = None, headers: dict = None, cookies: dict = None, redirects: bool = True, ) -> requests.Response: """Wrap the get requests. Same arguments as _gen_request_kwargs functions. Returns: Return a requests object with properties: - status_code - reason - headers - text """ kwargs = self._gen_request_kwargs( endpoint=endpoint, data=data, # type: ignore json_data=json_data, # type: ignore params=params, # type: ignore headers=headers, # type: ignore cookies=cookies, # type: ignore redirects=redirects, ) return requests.get(**kwargs) def _post( self, endpoint: str, data: dict = None, json_data: dict = None, params: dict = None, headers: dict = None, cookies: dict = None, redirects: bool = True, files: dict = None, ) -> requests.Response: """Wrap the post requests. Same arguments as _gen_request_kwargs functions. Returns: Return a requests object with properties: - status_code - reason - headers - text """ kwargs = self._gen_request_kwargs( endpoint=endpoint, data=data, # type: ignore json_data=json_data, # type: ignore params=params, # type: ignore headers=headers, # type: ignore cookies=cookies, # type: ignore redirects=redirects, files=files, ) return requests.post(**kwargs) class GwClient(GwRequests): """Client class to interact with the service API.""" def test_module(self): """Return True if status_code == 200 and False instead. Raises: GwAPIException: If status_code != 200. """ response = self._get(endpoint=f"/lis/getbyminutes/0?api_key={self.token}&headers=false") if response.status_code == 200: demisto.info("Get healthchecks on LIS API: [OK]") return True else: demisto.error("Get healthchecks on LIS API: [FAILED]", response.text, response.status_code, response.reason) return False def get_by_minute(self, minute) -> list: """Retrieve the data from Gatewatcher CTI feed by minute. Max 1440 minutes. Args: minute: Number of minutes to get. (max 1440 min) Returns: LIS Json response Raises: GwAPIException: If status_code != 200. """ response = self._get(endpoint=f"/lis/getbyminutes/{arg_to_number(minute)}?api_key={self.token}&headers=false") if response.status_code == 200: demisto.info("Get ioc by minute : [OK]") return response.json() else: raise GwAPIException("Get ioc by minute: [FAILED]", response.text, response.status_code, response.reason) def get_by_value(self, value: str) -> dict: """Allows you to search for an IOC (url, hash, host) or a vulnerability in the Gatewatcher CTI database. If the data is known, only the IOC corresponding to the value will be returned. Args: value: Value to be search Returns: Value data Raises: GwAPIException: If status_code != 200. """ response = self._post(endpoint=f"/lis/search?api_key={self.token}&headers=false", json_data=assign_params(value=value)) if response.status_code == 200: demisto.info("Get search ioc: [OK]") return response.json() else: raise GwAPIException( "Get ioc by value: [FAILED]", response.text, response.status_code, response.reason, ) def get_leaked_email_by_domain(self, domain: str, after: str) -> dict: """Allows you to search for leaked email by domain in Gatewatcher's CTI database. Args: domain: Domain to be searched after: results before this date won't be returned. Returns: Value data Raises: GwAPIException: If status_code != 200. """ url = f"/lis/leaked_emails/get_by_domain/{domain}?api_key={self.token}&headers=false" url += f"&added_after={after}" if after else "" response = self._get(endpoint=url) if response.status_code == 200: demisto.info("Get search leaked email: [OK]") return response.json() else: raise GwAPIException( "Get leaked email: [FAILED]", response.text, response.status_code, response.reason, ) def get_is_email_leaked(self, email: str, after: str) -> dict: """Allows you to search if an email has leaked in Gatewatcher's CTI database. Args: email: Email to be searched. after: results before this date won't be returned. Returns: Value data Raises: GwAPIException: If status_code != 200. """ url = f"/lis/leaked_emails/get_by_email/{email}?api_key={self.token}&headers=false" url += f"&added_after={after}" if after else "" response = self._get( endpoint=url, json_data=assign_params(value=email), ) if response.status_code == 200: demisto.info("Get search leaked email: [OK]") return response.json() else: raise GwAPIException( "Get is email leaked: [FAILED]", response.text, response.status_code, response.reason, ) def get_dbot_score(risk: str) -> int: if risk == "Malicious": return Common.DBotScore.BAD if risk == "Suspicious": return Common.DBotScore.SUSPICIOUS if risk == "High suspicious": return Common.DBotScore.SUSPICIOUS return Common.DBotScore.NONE def file_indicator(ioc: dict): md5 = None sha1 = None sha256 = None sha512 = None hash = ioc["Value"] hash_type = ioc["Type"] if hash_type == "MD5": md5 = hash elif hash_type == "SHA1": sha1 = hash elif hash_type == "SHA256": sha256 = hash elif hash_type == "SHA512": sha512 = hash return Common.File( dbot_score=get_dbot_score(ioc.get("Risk", "")), description=ioc.get("Description"), ssdeep=ioc.get("MetaData", {}).get("ssdeep"), file_type=ioc.get("MetaData", {}).get("filetype"), traffic_light_protocol=ioc.get("TLP"), imphash=ioc.get("MetaData", {}).get("imphash"), md5=md5, sha1=sha1, sha256=sha256, sha512=sha512, ) def domain_indicator(ioc: dict): return Common.Domain( domain=ioc.get("Value"), dbot_score=get_dbot_score(ioc.get("Risk", "")), description=ioc.get("Description"), traffic_light_protocol=ioc.get("TLP"), ) def url_indicator(ioc: dict): return Common.URL( url=ioc.get("Value"), dbot_score=get_dbot_score(ioc.get("Risk", "")), description=ioc.get("Description"), traffic_light_protocol=ioc.get("TLP"), ) def generic_reputation_command(client: GwClient, args: dict, cmd_type: str, reliability: str) -> List[CommandResults]: """Checks the reputation of a file, domain or url Args: client: Client to interact with the LIS API. args: Command arguments. cmd_type: Command type ("file", "domain" or "url") reliability: Integration reliability Return List of CommandResults objects. """ output_prefixes = { "file": "LIS.File", "domain": "LIS.Domain", "url": "LIS.URL", } arg_list = argToList(args[cmd_type]) results: List[CommandResults] = [] indicator_type = cmd_type # for each IOC in request args for arg in arg_list: response = client.get_by_value(value=arg) ioc = list(filter(lambda x: x["Value"] == arg, response["IOCs"]))[0] lis_result = { "Value": ioc["Value"], "Risk": ioc["Risk"], "Categories": ioc["Categories"], "Type": ioc["Type"], "TLP": ioc["TLP"], "UsageMode": ioc["UsageMode"], "Vulnerabilities": ioc["Vulnerabilities"], } readable_result = tableToMarkdown("Get IoC corresponding to the value", lis_result) if cmd_type == "file": indicator = file_indicator(ioc) elif cmd_type == "domain": indicator = domain_indicator(ioc) else: indicator = url_indicator(ioc) indicator.dbot_score = Common.DBotScore( indicator=arg, integration_name=INTEGRATION_NAME, indicator_type=indicator_type, score=get_dbot_score(ioc["Risk"]), reliability=reliability, malicious_description="Match found in LastInfoSec", ) results.append( CommandResults( indicator=indicator, readable_output=readable_result, outputs_prefix=output_prefixes[cmd_type], outputs_key_field="Value", outputs=lis_result, raw_response=response, ) ) return results def test_module(client: GwClient) -> str: # noqa: E501 """tests API connectivity. Args: client: Client to interact with the LIS API. Returns: 'Request successful' when the LIS connection works. 'Request error' when the LIS connection doesn't works. """ if client.test_module(): return "ok" else: return "Request error, please check ip/user/password/token: [ERROR]" def lis_get_by_minute(client: GwClient, args: dict[Any, Any]) -> CommandResults: # noqa: E501 """Retrieve the data from Gatewatcher CTI feed by minute. Max 1440 minutes. Args: client: Client to interact with the LIS API. args: Command arguments. Returns: CommandResults object with the "LIS.IoC.GetByMinute" prefix. """ minute = arg_to_number(args.get("Minute")) categories = argToList(args.get("Categories")) risk = argToList(args.get("Risk")) tlp = argToList(args.get("TLP")) ftype = argToList(args.get("Type")) mode = args.get("Mode") if "Filename" in ftype: raise ValueError("Filter filename is not a valid filter. Please use a different filter option.") if "Informational" in risk: raise ValueError("Filter informational is not a valid filter. Please use a different filter option.") response = client.get_by_minute(minute=minute) for case in response: if categories: case["IOCs"] = [ioc for ioc in case["IOCs"] if set(categories) & set(ioc["Categories"])] if ftype: case["IOCs"] = [ioc for ioc in case["IOCs"] if ioc["Type"] in ftype] if mode: case["IOCs"] = [ioc for ioc in case["IOCs"] if mode == ioc["UsageMode"]] if risk: case["IOCs"] = [ioc for ioc in case["IOCs"] if ioc["Risk"] in risk] if tlp: case["IOCs"] = [ioc for ioc in case["IOCs"] if ioc["TLP"] in tlp] result = [ioc["Value"] for case in response for ioc in case["IOCs"]] readable_result = tableToMarkdown("Get IoC by minute", result, headers="Value") return CommandResults( readable_output=readable_result, outputs_prefix="LIS.GetByMinute", outputs_key_field="Value", outputs=result, raw_response=result, ) def lis_get_by_value(client: GwClient, args: dict[Any, Any]) -> CommandResults: # noqa: E501 """Allows you to search for an IOC (url, hash, host) or a vulnerability in the Gatewatcher CTI database. If the data is known, only the IOC corresponding to the value will be returned. Args: client: Client to interact with the LIS API. args: Command arguments. Returns: CommandResults object with the "LIS.IoC.GetByValue" prefix. """ value = args["Value"] response = client.get_by_value(value=value) ioc = list(filter(lambda x: x["Value"] == value, response["IOCs"]))[0] result = { "Value": ioc["Value"], "Risk": ioc["Risk"], "Categories": ioc["Categories"], "Type": ioc["Type"], "TLP": ioc["TLP"], "UsageMode": ioc["UsageMode"], "Vulnerabilities": ioc["Vulnerabilities"], } readable_result = tableToMarkdown("Get IoC corresponding to the value", result) return CommandResults( readable_output=readable_result, outputs_prefix="LIS.GetByValue", outputs_key_field="Value", outputs=result, raw_response=result, ) def lis_get_leaked_email_by_domain(client: GwClient, args: dict[Any, Any]) -> CommandResults: """Allows you to search for leaked email by domain in Gatewatcher's CTI database. Args: client: Client to interact with the LIS API. args: Command arguments, Domain: domain to search for. After: date to do not return results before this date. Returns: CommandResults object with the "LIS.leakedEmail.GetByDomain" prefix. """ domain = args.get("Domain", None) after = args.get("After", None) response = client.get_leaked_email_by_domain(domain, after) emails = [res["Value"] for res in response] result = emails if len(emails) > 0 else None readable_result = tableToMarkdown("Leaked email", result, headers="Emails") return CommandResults( readable_output=readable_result, outputs_prefix="LIS.LeakedEmail.GetByDomain", outputs=result, raw_response=result, ) def lis_is_email_leaked(client: GwClient, args: dict[Any, Any]) -> CommandResults: """Allows you to search if an email has leaked in Gatewatcher's CTI database. Args: client: Client to interact with the LIS API. args: Command arguments, Email: email to search for. After: date to do not return results before this date. Returns: CommandResults object with the "LIS.leakedEmail.getByEmail" prefix. """ email = args.get("Email", None) after = args.get("After", None) response = client.get_is_email_leaked(email, after) result = email if len(response) > 0 else None readable_result = tableToMarkdown("Is email leaked", result, headers="Value") return CommandResults( readable_output=readable_result, outputs_prefix="LIS.LeakedEmail.GetByEmail", outputs=result, raw_response=result, ) def main() -> None: params = demisto.params() command = demisto.command() args = demisto.args() token = params.get("token") check_cert = params.get("check_cert", False) proxy = params.get("proxy", False) reliability = params.get("integrationReliability", "C - Fairly reliable") reliability = reliability if reliability else DBotScoreReliability.B if DBotScoreReliability.is_valid_type(reliability): reliability = DBotScoreReliability.get_dbot_score_reliability_from_str(reliability) else: return_error("Please provide a valid value for the Source Reliability parameter") demisto.debug(f"Command being called is {command}") try: client = GwClient(token=token, proxy=proxy, check_cert=check_cert) if command == "test-module": return_results(test_module(client=client)) elif command == "url": return_results(generic_reputation_command(client=client, args=args, cmd_type="url", reliability=reliability)) elif command == "file": return_results(generic_reputation_command(client=client, args=args, cmd_type="file", reliability=reliability)) elif command == "domain": return_results(generic_reputation_command(client=client, args=args, cmd_type="domain", reliability=reliability)) elif command == "gw-lis-get-by-minute": return_results(lis_get_by_minute(client=client, args=args)) elif command == "gw-lis-get-by-value": return_results(lis_get_by_value(client=client, args=args)) elif command == "gw-lis-leaked-email-by-domain": return_results(lis_get_leaked_email_by_domain(client=client, args=args)) elif command == "gw-lis-is-email-leaked": return_results(lis_is_email_leaked(client=client, args=args)) else: raise NotImplementedError(f"{command} command is not implemented.") except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{str(e)}") if __name__ in ("__main__", "__builtin__", "builtins"): main()