HYAS Insight

Use the HYAS Insight integration to interactively lookup PassiveDNS, DynamicDNS, WHOIS, Sample Malware Records, C2 Attribution, Passive Hash, SSL Certificate, Open Source Indicators, Device Geo, Sinkhole, Malware Sample Information – either as playbook tasks or through API calls in the War Room.

Data Enrichment & Threat Intelligence · HYAS Insight

Details

IDHYAS Insight
ProviderSilent Push
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

HYAS Insight

HYAS Insight is a threat investigation and attribution solution that uses exclusive data sources and non-traditional mechanisms to improve visibility and productivity for analysts, researchers, and investigators while increasing the accuracy of findings. HYAS Insight connects attack instances and campaigns to billions of indicators of compromise to deliver insights and visibility. With an easy-to-use user interface, transforms, and API access, HYAS Insight combines rich threat data into a powerful research and attribution solution. HYAS Insight is complemented by the HYAS Intelligence team that helps organizations to better understand the nature of the threats they face on a daily basis.

Use the HYAS Insight integration to interactively lookup PassiveDNS, DynamicDNS, WHOIS, Sample Malware Records, C2 Attribution, Passive Hash, SSL Certificate, Open Source Indicators, Device Geo, Sinkhole, Malware Sample Information.

How to get a HYAS API Key

In order to obtain a HYAS Insight API key to use with Cortex XSOAR, please contact your HYAS Insight Admin. If you are unsure who your Admin is, you can also contact HYAS Support via email at support@hyas.com, by visiting the HYAS website https://www.hyas.com/contact, or by using the HYAS Insight web UI by clicking the ‘help’ icon at the top right of the screen, to request a key.

Partner Contributed Integration

Integration Author: HYAS

Support and maintenance for this integration are provided by the author. Please use the following contact details:
Email: support@hyas.com
URL: https://support.hyas.com

Configure HYASInsight in Cortex

Parameter Required
HYAS Insight Api Key True
Trust any certificate (not secure) False
Use system proxy settings False

Commands

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

hyas-get-passive-dns-records-by-indicator


Returns PassiveDNS records for the provided indicator value.

Base Command

hyas-get-passive-dns-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ipv4, domain. Required
indicator_value Indicator value to query. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.PassiveDNS.count Number The passive dns count
HYAS.PassiveDNS.domain String The domain of the passive dns information requested
HYAS.PassiveDNS.first_seen Date The first time this domain was seen
HYAS.PassiveDNS.ip.geo.city_name String City of the ip organization
HYAS.PassiveDNS.ip.geo.country_iso_code String Country ISO code of the ip organization
HYAS.PassiveDNS.ip.geo.country_name String Country name of the ip organization
HYAS.PassiveDNS.ip.geo.location_latitude Number The latitude of the ip organization
HYAS.PassiveDNS.ip.geo.location_longitude Number The longitude of the ip organization
HYAS.PassiveDNS.ip.geo.postal_code String The longitude of the ip organization
HYAS.PassiveDNS.ip.ip String IP of the organization
HYAS.PassiveDNS.ip.isp.autonomous_system_number String The ASN of the ip
HYAS.PassiveDNS.ip.isp.autonomous_system_organization String The ASO of the ip
HYAS.PassiveDNS.ip.isp.ip_address String The IP
HYAS.PassiveDNS.ip.isp.isp String The Internet Service Provider
HYAS.PassiveDNS.ip.isp.organization String The ISP organization
HYAS.PassiveDNS.ipv4 String The ipv4 address of the passive dns record
HYAS.PassiveDNS.last_seen Date The last time this domain was seen
HYAS.PassiveDNS.sources Unknown A list of pDNS providers which the data came from

Command example

!hyas-get-passive-dns-records-by-indicator indicator_type="domain" indicator_value="domain.org" limit="3"

Context Example

{
    "HYAS": {
        "PassiveDNS": [
            {
                "count": 310833,
                "domain": "domain.org",
                "first_seen": "2015-06-08T19:16:18Z",
                "ip": {
                    "geo": {
                        "city_name": "Boston",
                        "country_iso_code": "US",
                        "country_name": "United States",
                        "location_latitude": "42.3584",
                        "location_longitude": "-71.0598",
                        "postal_code": "02108"
                    },
                    "ip": "65.254.244.180",
                    "isp": {
                        "autonomous_system_number": "AS29873",
                        "autonomous_system_organization": "Newfold Digital, Inc.",
                        "ip_address": "65.254.244.180",
                        "isp": "Newfold Digital, Inc.",
                        "organization": "Newfold Digital, Inc."
                    }
                },
                "ipv4": "65.254.244.180",
                "last_seen": "2023-06-30T02:05:29Z",
                "sources": [
                    "hyas",
                    "farsight"
                ]
            },
            {
                "count": 62645,
                "domain": "domain.org",
                "first_seen": "2010-07-13T17:29:58Z",
                "ip": {
                    "geo": {
                        "city_name": "Seattle",
                        "country_iso_code": "US",
                        "country_name": "United States",
                        "location_latitude": "47.6062",
                        "location_longitude": "-122.3321",
                        "postal_code": "98101"
                    },
                    "ip": "216.34.94.184",
                    "isp": {
                        "autonomous_system_number": "AS3561",
                        "autonomous_system_organization": "CenturyLink Communications, LLC",
                        "ip_address": "216.34.94.184",
                        "isp": "Dotster, Inc.",
                        "organization": "Dotster, Inc."
                    }
                },
                "ipv4": "216.34.94.184",
                "last_seen": "2015-06-08T17:50:06Z",
                "sources": [
                    "farsight"
                ]
            },
            {
                "count": 1,
                "domain": "'.domain.org",
                "first_seen": "2011-02-17T11:17:10Z",
                "ip": {
                    "geo": {
                        "city_name": "Seattle",
                        "country_iso_code": "US",
                        "country_name": "United States",
                        "location_latitude": "47.6062",
                        "location_longitude": "-122.3321",
                        "postal_code": "98101"
                    },
                    "ip": "216.34.94.184",
                    "isp": {
                        "autonomous_system_number": "AS3561",
                        "autonomous_system_organization": "CenturyLink Communications, LLC",
                        "ip_address": "216.34.94.184",
                        "isp": "Dotster, Inc.",
                        "organization": "Dotster, Inc."
                    }
                },
                "ipv4": "216.34.94.184",
                "last_seen": "2011-02-17T11:17:10Z",
                "sources": [
                    "farsight"
                ]
            }
        ]
    }
}

Human Readable Output

HYAS PassiveDNS records for domain : domain.org

Count Domain First seen City Name Country Code Country Name Latitude Longitude Postal Code IP ISP ASN ISP ASN Organization ISP IP Address ISP ISP Organization IPV4 Last Seen Sources
310833 domain.org 2015-06-08T19:16:18Z Boston US United States 42.3584 -71.0598 02108 65.254.244.180 AS29873 Newfold Digital, Inc. 65.254.244.180 Newfold Digital, Inc. Newfold Digital, Inc. 65.254.244.180 2023-06-30T02:05:29Z hyas,
farsight
62645 domain.org 2010-07-13T17:29:58Z Seattle US United States 47.6062 -122.3321 98101 216.34.94.184 AS3561 CenturyLink Communications, LLC 216.34.94.184 Dotster, Inc. Dotster, Inc. 216.34.94.184 2015-06-08T17:50:06Z farsight
1 ‘.domain.org 2011-02-17T11:17:10Z Seattle US United States 47.6062 -122.3321 98101 216.34.94.184 AS3561 CenturyLink Communications, LLC 216.34.94.184 Dotster, Inc. Dotster, Inc. 216.34.94.184 2011-02-17T11:17:10Z farsight

hyas-get-dynamic-dns-records-by-indicator


Returns DynamicDNS records for the provided indicator value.

Base Command

hyas-get-dynamic-dns-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ip, domain, email. Required
indicator_value Indicator value to query. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.DynamicDNS.a_record String The A record for the domain
HYAS.DynamicDNS.account String The account holder name
HYAS.DynamicDNS.created Date The date which the domain was created
HYAS.DynamicDNS.created_ip String The ip address of the account holder
HYAS.DynamicDNS.domain String The domain associated with the dynamic dns information
HYAS.DynamicDNS.domain_creator_ip String The ip address of the domain creator
HYAS.DynamicDNS.email String The email address connected to the domain

Command example

!hyas-get-dynamic-dns-records-by-indicator indicator_type="ip" indicator_value="4.4.4.4" limit="3"

Context Example

{
    "HYAS": {
        "DynamicDNS": [
            {
                "a_record": "4.4.4.4",
                "a_record_geo": {
                    "geo": {
                        "city_name": "Paris",
                        "country_iso_code": "FR",
                        "country_name": "France",
                        "location_latitude": "48.8534",
                        "location_longitude": "2.3488",
                        "postal_code": "75000"
                    },
                    "isp": {
                        "autonomous_system_number": "AS3356",
                        "autonomous_system_organization": "Level 3 Parent, LLC",
                        "ip_address": "4.4.4.4",
                        "isp": "Level 3 Communications, Inc.",
                        "organization": "Level 3 Communications, Inc."
                    }
                },
                "account": "free",
                "created": "2022-03-14T11:05:14Z",
                "created_geo": {
                    "geo": {
                        "city_name": "Adelaide",
                        "country_iso_code": "AU",
                        "country_name": "Australia",
                        "location_latitude": "-34.8595",
                        "location_longitude": "138.6192",
                        "postal_code": "5085"
                    },
                    "isp": {
                        "autonomous_system_number": "AS1221",
                        "autonomous_system_organization": "Telstra Corporation Ltd",
                        "ip_address": "4.4.4.4",
                        "isp": "Telstra",
                        "organization": "Telstra"
                    }
                },
                "created_ip": "4.4.4.4",
                "domain": "block-make.duckdns.org",
                "domain_creator_geo": {
                    "geo": {
                        "city_name": "Adelaide",
                        "country_iso_code": "AU",
                        "country_name": "Australia",
                        "location_latitude": "-34.8666",
                        "location_longitude": "138.6768",
                        "postal_code": "5075"
                    },
                    "isp": {
                        "autonomous_system_number": "AS1221",
                        "autonomous_system_organization": "Telstra Corporation Ltd",
                        "ip_address": "4.4.4.4",
                        "isp": "Telstra",
                        "organization": "Telstra"
                    }
                },
                "domain_creator_ip": "4.4.4.4",
                "email": "DarkMagicSource@github"
            },
            {
                "a_record": "4.4.4.4",
                "a_record_geo": {
                    "geo": {
                        "city_name": "Paris",
                        "country_iso_code": "FR",
                        "country_name": "France",
                        "location_latitude": "48.8534",
                        "location_longitude": "2.3488",
                        "postal_code": "75000"
                    },
                    "isp": {
                        "autonomous_system_number": "AS3356",
                        "autonomous_system_organization": "Level 3 Parent, LLC",
                        "ip_address": "4.4.4.4",
                        "isp": "Level 3 Communications, Inc.",
                        "organization": "Level 3 Communications, Inc."
                    }
                },
                "account": "free",
                "created": "2023-02-27T10:00:12Z",
                "created_geo": {
                    "geo": {
                        "city_name": "Adelaide",
                        "country_iso_code": "AU",
                        "country_name": "Australia",
                        "location_latitude": "-34.8595",
                        "location_longitude": "138.6192",
                        "postal_code": "5085"
                    },
                    "isp": {
                        "autonomous_system_number": "AS1221",
                        "autonomous_system_organization": "Telstra Corporation Ltd",
                        "ip_address": "4.4.4.4",
                        "isp": "Telstra",
                        "organization": "Telstra"
                    }
                },
                "created_ip": "4.4.4.4",
                "domain": "flindersmc.duckdns.org",
                "domain_creator_geo": {
                    "geo": {
                        "city_name": "Adelaide",
                        "country_iso_code": "AU",
                        "country_name": "Australia",
                        "location_latitude": "-35.0075",
                        "location_longitude": "138.5437",
                        "postal_code": "5046"
                    },
                    "isp": {
                        "autonomous_system_number": "AS1221",
                        "autonomous_system_organization": "Telstra Corporation Ltd",
                        "ip_address": "4.4.4.4",
                        "isp": "Telstra",
                        "organization": "Telstra"
                    }
                },
                "domain_creator_ip": "4.4.4.4",
                "email": "DarkMagicSource@github"
            },
            {
                "a_record": "4.4.4.4",
                "a_record_geo": {
                    "geo": {
                        "city_name": "Paris",
                        "country_iso_code": "FR",
                        "country_name": "France",
                        "location_latitude": "48.8534",
                        "location_longitude": "2.3488",
                        "postal_code": "75000"
                    },
                    "isp": {
                        "autonomous_system_number": "AS3356",
                        "autonomous_system_organization": "Level 3 Parent, LLC",
                        "ip_address": "4.4.4.4",
                        "isp": "Level 3 Communications, Inc.",
                        "organization": "Level 3 Communications, Inc."
                    }
                },
                "account": "free",
                "created": "2020-04-11T17:01:15Z",
                "created_geo": {
                    "geo": {
                        "city_name": "Toronto",
                        "country_iso_code": "CA",
                        "country_name": "Canada",
                        "location_latitude": "43.7001",
                        "location_longitude": "-79.4163",
                        "postal_code": "M5A"
                    },
                    "isp": {
                        "autonomous_system_number": "AS174",
                        "autonomous_system_organization": "Cogent Communications",
                        "ip_address": "4.4.4.4",
                        "isp": "Amanah Tech Inc.",
                        "organization": "Amanah Tech Inc."
                    }
                },
                "created_ip": "4.4.4.4",
                "domain": "mysql.duckdns.org",
                "email": "xyz"
            }
        ]
    }
}

Human Readable Output

HYAS DynamicDNS records for ip : 4.4.4.4

A Record Account Created Date Account Holder IP Address Domain Domain Creator IP Address Email Address
4.4.4.4 free 2022-03-14T11:05:14Z 4.4.4.4 block-make.duckdns.org 4.4.4.4 DarkMagicSource@github
4.4.4.4 free 2023-02-27T10:00:12Z 4.4.4.4 flindersmc.duckdns.org 4.4.4.4 DarkMagicSource@github
4.4.4.4 free 2020-04-11T17:01:15Z 4.4.4.4 mysql.duckdns.org   xyz

hyas-get-whois-records-by-indicator


Returns WHOIS records for the provided indicator value.

Base Command

hyas-get-whois-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: domain, email, phone. Required
indicator_value Indicator value to query. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.WHOIS.address Unknown address
HYAS.WHOIS.city Unknown city
HYAS.WHOIS.country Unknown country
HYAS.WHOIS.domain String The domain of the registrant
HYAS.WHOIS.domain_2tld String The second-level domain of the registrant
HYAS.WHOIS.domain_created_datetime Date The date and time when the whois record was created
HYAS.WHOIS.domain_expires_datetime Date The date and time when the whois record expires
HYAS.WHOIS.domain_updated_datetime Date The date and time when the whois record was last updated
HYAS.WHOIS.email Unknown email
HYAS.WHOIS.idn_name String The international domain name
HYAS.WHOIS.nameserver Unknown nameserver
HYAS.WHOIS.phone.phone String The phone number registrant contact in e164 format
HYAS.WHOIS.phone.phone_info.carrier String Phone number carrier
HYAS.WHOIS.phone.phone_info.country String Phone number country
HYAS.WHOIS.phone.phone_info.geo String Phone number geo. Can be city, province, region or country
HYAS.WHOIS.privacy_punch Boolean True if this record has additional information bypassing privacy protect
HYAS.WHOIS.registrar String The domain registrar

Command example

!hyas-get-whois-records-by-indicator indicator_type="domain" indicator_value="edubolivia.org" limit="3"

Context Example

{
    "HYAS": {
        "WHOIS": [
            {
                "abuse_emails": [],
                "address": [],
                "city": [],
                "country": [
                    "BO"
                ],
                "datetime": "2021-07-15T08:00:25.296Z",
                "domain": "edubolivia.org",
                "domain_2tld": "edubolivia.org",
                "domain_created_datetime": "2010-04-08T13:24:40Z",
                "domain_expires_datetime": "2022-04-08T13:24:40Z",
                "domain_updated_datetime": "2021-03-26T13:55:53Z",
                "email": [
                    "xyz"
                ],
                "idn_name": null,
                "name": [
                    "pablo maldonado"
                ],
                "nameserver": [
                    "ns1.solucionesrmc.com",
                    "ns2.solucionesrmc.com"
                ],
                "organization": [],
                "phone": [],
                "privacy_punch": false,
                "registrar": "pdr ltd. d/b/a publicdomainregistry.com",
                "state": [],
                "whois_nameserver": [],
                "whois_pii": []
            },
            {
                "abuse_emails": [],
                "address": [],
                "city": [],
                "country": [],
                "datetime": "2023-06-30T09:01:13.703Z",
                "domain": "edubolivia.org",
                "domain_2tld": "edubolivia.org",
                "domain_created_datetime": "2010-04-08T13:24:40Z",
                "domain_expires_datetime": "2024-04-08T13:24:40Z",
                "domain_updated_datetime": "2023-03-26T12:56:44Z",
                "email": [],
                "idn_name": null,
                "name": [],
                "nameserver": [
                    "ns1.dns-parking.com",
                    "ns2.dns-parking.com"
                ],
                "organization": [],
                "phone": [],
                "privacy_punch": false,
                "registrar": "pdr ltd. d/b/a publicdomainregistry.com",
                "state": [],
                "whois_nameserver": [],
                "whois_pii": []
            },
            {
                "abuse_emails": [],
                "address": [],
                "city": [],
                "country": [],
                "datetime": "2023-06-30T09:01:13.703Z",
                "domain": "edubolivia.org",
                "domain_2tld": "edubolivia.org",
                "domain_created_datetime": "2010-04-08T13:24:40Z",
                "domain_expires_datetime": "2023-04-08T13:24:40Z",
                "domain_updated_datetime": "2022-12-14T07:28:16Z",
                "email": [],
                "idn_name": null,
                "name": [],
                "nameserver": [
                    "ns3.server-us.com",
                    "ns4.server-us.com"
                ],
                "organization": [],
                "phone": [],
                "privacy_punch": false,
                "registrar": "pdr ltd. d/b/a publicdomainregistry.com",
                "state": [],
                "whois_nameserver": [],
                "whois_pii": []
            }
        ]
    }
}

Human Readable Output

HYAS WHOIS records for domain : edubolivia.org

Country Domain Domain_2tld Domain Created Time Domain Expires Time Domain Updated Time Email Address IDN Name Nameserver Privacy_punch Registrar
BO edubolivia.org edubolivia.org 2010-04-08T13:24:40Z 2022-04-08T13:24:40Z 2021-03-26T13:55:53Z xyz None ns1.solucionesrmc.com,
ns2.solucionesrmc.com
false pdr ltd. d/b/a publicdomainregistry.com
  edubolivia.org edubolivia.org 2010-04-08T13:24:40Z 2024-04-08T13:24:40Z 2023-03-26T12:56:44Z   None ns1.dns-parking.com,
ns2.dns-parking.com
false pdr ltd. d/b/a publicdomainregistry.com
  edubolivia.org edubolivia.org 2010-04-08T13:24:40Z 2023-04-08T13:24:40Z 2022-12-14T07:28:16Z   None ns3.server-us.com,
ns4.server-us.com
false pdr ltd. d/b/a publicdomainregistry.com

hyas-get-whois-current-records-by-domain


Returns WHOIS Current records for the provided indicator value.

Base Command

hyas-get-whois-current-records-by-domain

Input

Argument Name Description Required
domain Domain value to query. Required

Context Output

Path Type Description
HYAS.WHOISCurrent.abuse_emails Unknown abuse emails
HYAS.WHOISCurrent.address Unknown address
HYAS.WHOISCurrent.city Unknown city
HYAS.WHOISCurrent.country Unknown country
HYAS.WHOISCurrent.domain String The domain of the registrant
HYAS.WHOISCurrent.domain_2tld String The second-level domain of the registrant
HYAS.WHOISCurrent.domain_created_datetime Date The date and time when the whois record was created
HYAS.WHOISCurrent.domain_expires_datetime Date The date and time when the whois record expires
HYAS.WHOISCurrent.domain_updated_datetime Date The date and time when the whois record was last updated
HYAS.WHOISCurrent.email Unknown email
HYAS.WHOISCurrent.idn_name String The international domain name
HYAS.WHOISCurrent.nameserver Unknown nameserver
HYAS.WHOISCurrent.organization Unknown organization
HYAS.WHOISCurrent.phone Unknown The phone number
HYAS.WHOISCurrent.registrar String The domain registrar
HYAS.WHOISCurrent.state Unknown The state

Command example

!hyas-get-whois-current-records-by-domain domain="edubolivia.org"

Context Example

{
    "HYAS": {
        "WHOISCurrent": {
            "items": [
                {
                    "abuse_emails": [
                        "abuse@publicdomainregistry.com"
                    ],
                    "address": [],
                    "city": [],
                    "country": [
                        "Bolivia"
                    ],
                    "datetime": null,
                    "domain": "edubolivia.org",
                    "domain_2tld": "edubolivia.org",
                    "domain_created_datetime": "2010-04-08T13:24:40Z",
                    "domain_expires_datetime": "2024-04-08T13:24:40Z",
                    "domain_updated_datetime": "2023-03-26T12:56:44Z",
                    "email": [
                        "please query the rdds service of the registrar of record identified in this output for information on how to contact the registrant, admin, or tech contact of the queried domain name."
                    ],
                    "idn_name": null,
                    "name": [
                        "Redacted For Privacy\nPablo Maldonado"
                    ],
                    "nameserver": [
                        "ns1.dns-parking.com",
                        "ns2.dns-parking.com"
                    ],
                    "organization": [],
                    "phone": [
                        {
                            "phone": "REDACTED FOR PRIVACY ext. REDACTED FOR PRIVACY"
                        }
                    ],
                    "privacy_punch": false,
                    "registrar": "pdr ltd. d/b/a publicdomainregistry.com",
                    "state": [
                        "la Paz"
                    ],
                    "whois_nameserver": [
                        {
                            "domain": "ns1.dns-parking.com"
                        },
                        {
                            "domain": "ns2.dns-parking.com"
                        }
                    ],
                    "whois_pii": [
                        {
                            "email": "please query the rdds service of the registrar of record identified in this output for information on how to contact the registrant, admin, or tech contact of the queried domain name.",
                            "phone_e164": "REDACTED FOR PRIVACY ext. REDACTED FOR PRIVACY"
                        },
                        {
                            "email": "please query the rdds service of the registrar of record identified in this output for information on how to contact the registrant, admin, or tech contact of the queried domain name.",
                            "geo_country_alpha_2": "Bolivia",
                            "name": "Redacted For Privacy\nPablo Maldonado",
                            "phone_e164": "REDACTED FOR PRIVACY ext. REDACTED FOR PRIVACY",
                            "state": "la Paz"
                        }
                    ]
                }
            ],
            "source": "whois",
            "total_count": 1
        }
    }
}

Human Readable Output

HYAS WHOISCurrent records for domain : edubolivia.org

Abuse Emails Country Domain Domain_2tld Domain Created Time Domain Expires Time Domain Updated Time Email Address IDN Name Nameserver Phone Info Registrar State
abuse@publicdomainregistry.com Bolivia edubolivia.org edubolivia.org 2010-04-08T13:24:40Z 2024-04-08T13:24:40Z 2023-03-26T12:56:44Z please query the rdds service of the registrar of record identified in this output for information on how to contact the registrant, admin, or tech contact of the queried domain name. None ns1.dns-parking.com,
ns2.dns-parking.com
{‘phone’: ‘REDACTED FOR PRIVACY ext. REDACTED FOR PRIVACY’} pdr ltd. d/b/a publicdomainregistry.com la Paz

hyas-get-malware-samples-records-by-indicator


Returns Malware Sample records for the provided indicator value.

Base Command

hyas-get-malware-samples-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: domain, ipv4, md5. Required
indicator_value Indicator value to query. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.MalwareSamples.datetime Date The date which the sample was processed
HYAS.MalwareSamples.domain String The domain of the sample
HYAS.MalwareSamples.ipv4 String The ipv4 of the sample
HYAS.MalwareSamples.ipv6 String The ipv6 of the sample
HYAS.MalwareSamples.md5 String The md5 of the sample
HYAS.MalwareSamples.sha1 String The sha1 of the sample
HYAS.MalwareSamples.sha256 String The sha256 of the sample

Command example

!hyas-get-malware-samples-records-by-indicator indicator_type="domain" indicator_value="chennaigastrosurgeon.com" limit="3"

Context Example

{
    "HYAS": {
        "MalwareSamples": [
            {
                "datetime": "2022-09-28T00:00:00Z",
                "domain": "chennaigastrosurgeon.com",
                "ipv4": "4.4.4.4",
                "md5": "0268fb20d9143c429138034969e06833"
            },
            {
                "datetime": "2022-09-27T00:00:00Z",
                "domain": "chennaigastrosurgeon.com",
                "ipv4": "4.4.4.4",
                "md5": "21a77bca1417deb64a2ab7df77786ded"
            },
            {
                "datetime": "2022-09-24T00:00:00Z",
                "domain": "chennaigastrosurgeon.com",
                "ipv4": "4.4.4.4",
                "md5": "953951ede4e9f706e6842fa4eb4e2e65"
            }
        ]
    }
}

Human Readable Output

HYAS MalwareSamples records for domain : chennaigastrosurgeon.com

Datetime Domain IPV4 Address MD5 Value
2022-09-28T00:00:00Z chennaigastrosurgeon.com 4.4.4.4 0268fb20d9143c429138034969e06833
2022-09-27T00:00:00Z chennaigastrosurgeon.com 4.4.4.4 21a77bca1417deb64a2ab7df77786ded
2022-09-24T00:00:00Z chennaigastrosurgeon.com 4.4.4.4 953951ede4e9f706e6842fa4eb4e2e65

hyas-get-c2attribution-records-by-indicator


Return C2 Attribution records for the provided indicator value.

Base Command

hyas-get-c2attribution-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ip, domain, sha256, email. Required
indicator_value Indicator Value. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.C2_Attribution.actor_ipv4 String The actor ipv4
HYAS.C2_Attribution.c2_domain String The c2 domain
HYAS.C2_Attribution.c2_ip String The c2 ip
HYAS.C2_Attribution.c2_url String The C2 panel url
HYAS.C2_Attribution.datetime String C2 Attribution datetime
HYAS.C2_Attribution.email String The actor email
HYAS.C2_Attribution.email_domain String The email domain
HYAS.C2_Attribution.referrer_domain String The referrer domain
HYAS.C2_Attribution.referrer_ipv4 String The referrer ipv4
HYAS.C2_Attribution.referrer_url String The referrer url
HYAS.C2_Attribution.sha256 String The sha256 malware hash

Command example

!hyas-get-c2attribution-records-by-indicator indicator_type=domain indicator_value=himionsa.com limit=3

Context Example

{
    "HYAS": {
        "C2_Attribution": {
            "actor_ipv4": "4.4.4.4",
            "c2_domain": "himionsa.com",
            "c2_ip": "89.208.229.55",
            "c2_url": "http://himionsa.com/rich/panel/pvqdq929bsx_a_d_m1n_a.php?mazm=report",
            "datetime": "2020-02-25T16:39:43Z"
        }
    }
}

Human Readable Output

HYAS C2_Attribution records for domain : himionsa.com

Actor IPv4 C2 Domain C2 IP C2 URL Datetime
4.4.4.4 himionsa.com 89.208.229.55 http://himionsa.com/rich/panel/pvqdq929bsx_a_d_m1n_a.php?mazm=report 2020-02-25T21:49:27Z
4.4.4.4 himionsa.com 89.208.229.55 http://himionsa.com/rich/panel/pvqdq929bsx_a_d_m1n_a.php?mazm=report 2020-02-25T16:39:48Z
4.4.4.4 himionsa.com 89.208.229.55 http://himionsa.com/rich/panel/pvqdq929bsx_a_d_m1n_a.php?mazm=report 2020-02-25T16:39:43Z

hyas-get-passive-hash-records-by-indicator


Return passive hash records for the provided indicator value.

Base Command

hyas-get-passive-hash-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ipv4, domain. Required
indicator_value Indicator Value. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.Passive_Hash.domain String The domain of the passive hash information requested
HYAS.Passive_Hash.md5_count String The passive dns count

Command example

!hyas-get-passive-hash-records-by-indicator indicator_type="domain" indicator_value="edubolivia.org" limit="3"

Context Example

{
    "HYAS": {
        "Passive_Hash": [
            {
                "domain": "edubolivia.org",
                "md5_count": 457
            },
            {
                "domain": "juliusdobos.com",
                "md5_count": 457
            },
            {
                "domain": "ogsrealestate.com",
                "md5_count": 457
            }
        ]
    }
}

Human Readable Output

HYAS Passive_Hash records for domain : edubolivia.org

Domain MD5 Count
edubolivia.org 457
juliusdobos.com 457
ogsrealestate.com 457

hyas-get-ssl-certificate-records-by-indicator


Return SSL certificate records for the provided indicator value.

Base Command

hyas-get-ssl-certificate-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ip, domain, hash. Required
indicator_value Indicator Value. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.SSL_Certificate.ssl_certs.ip String The ip address associated with certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.cert_key String The certificate key (sha1)
HYAS.SSL_Certificate.ssl_certs.ssl_cert.expire_date String The expiry date of the certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issue_date String The issue date of the certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issuer_commonName String The common name that the certificate was issued from
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issuer_countryName String The country ISO the certificate was issued from
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issuer_localityName String The city where the issuer company is legally located
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issuer_organizationName String The organization name that issued the certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issuer_organizationalUnitName String The organization unit name that issued the certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.issuer_stateOrProvinceName String The issuer state or province
HYAS.SSL_Certificate.ssl_certs.ssl_cert.md5 String The certificate MD5
HYAS.SSL_Certificate.ssl_certs.ssl_cert.serial_number String The certificate serial number
HYAS.SSL_Certificate.ssl_certs.ssl_cert.sha1 String The certificate sha1
HYAS.SSL_Certificate.ssl_certs.ssl_cert.sha_256 String The certificate sha256
HYAS.SSL_Certificate.ssl_certs.ssl_cert.sig_algo String The certificate signature algorithm
HYAS.SSL_Certificate.ssl_certs.ssl_cert.signature String The certificate signature. Signature split into multiple lines
HYAS.SSL_Certificate.ssl_certs.ssl_cert.ssl_version String The SSL version
HYAS.SSL_Certificate.ssl_certs.ssl_cert.subject_commonName String The subject name that the certificate was issued to
HYAS.SSL_Certificate.ssl_certs.ssl_cert.subject_countryName String The country the certificate was issued to
HYAS.SSL_Certificate.ssl_certs.ssl_cert.subject_localityName String The city where the subject company is legally located
HYAS.SSL_Certificate.ssl_certs.ssl_cert.subject_organizationName String The organization name that recieved the certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.subject_organizationalUnitName String The organization unit name that recieved the certificate
HYAS.SSL_Certificate.ssl_certs.ssl_cert.timestamp String The certificate date and time

hyas-get-opensource-indicator-records-by-indicator


Return Open Source intel records for the provided indicator value.

Base Command

hyas-get-opensource-indicator-records-by-indicator

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ipv4, ipv6, domain, sha1, sha256, md5. Required
indicator_value Indicator Value. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.OS_Indicators.context String Additional information about source.
HYAS.OS_Indicators.data Unknown A json blob with raw data.
HYAS.OS_Indicators.datetime String A date-time string in RFC 3339 format.
HYAS.OS_Indicators.domain String A domain.
HYAS.OS_Indicators.domain_2tld String A domain_2tld.
HYAS.OS_Indicators.first_seen String A date-time string in RFC 3339 format.
HYAS.OS_Indicators.ipv4 String The ipv4 address. Can be a cidr.
HYAS.OS_Indicators.ipv6 String The ipv6 address. Can be a cidr.
HYAS.OS_Indicators.last_seen String A date-time string in RFC 3339 format.
HYAS.OS_Indicators.md5 String The md5 value.
HYAS.OS_Indicators.sha1 String The sha1 value.
HYAS.OS_Indicators.sha256 String The sha256 value.
HYAS.OS_Indicators.source_name String The source name
HYAS.OS_Indicators.source_url String The source url
HYAS.OS_Indicators.uri String The source uri value.

Command example

!hyas-get-opensource-indicator-records-by-indicator indicator_type=domain indicator_value=kidd16.blinn.edu limit="3"

Human Readable Output

HYAS OS_Indicators records for domain : kidd16.blinn.edu

No entries.

hyas-get-device-geo-records-by-ip-address


Returns a list of mobile geolocation information

Base Command

hyas-get-device-geo-records-by-ip-address

Input

Argument Name Description Required
indicator_type Indicator Type. Possible values are: ipv4, ipv6. Required
indicator_value Indicator Value. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.Device_Geo.datetime String A date-time string in RFC 3339 format.
HYAS.Device_Geo.device_user_agent String The user agent string for the device.
HYAS.Device_Geo.geo_country_alpha_2 String The ISO 3316 alpha-2 code for the country associated with the lat/long reported.
HYAS.Device_Geo.geo_horizontal_accuracy String The GPS horizontal accuracy.
HYAS.Device_Geo.ipv4 String The ipv4 address assigned to the device. A device may have either or ipv4 and ipv6.
HYAS.Device_Geo.ipv6 String The ipv6 address assigned to the device. A device may have either or ipv4 and ipv6.
HYAS.Device_Geo.latitude Number Units are degrees on the WGS 84 spheroid.
HYAS.Device_Geo.longitude Number Units are degrees on the WGS 84 spheroid.
HYAS.Device_Geo.wifi_bssid String The BSSID (MAC address) of the wifi router that the device communicated through.

Command example

!hyas-get-device-geo-records-by-ip-address indicator_type=ipv4 indicator_value=4.4.4.4 limit="3"

Context Example

{
    "HYAS": {
        "Device_Geo": [
            {
                "datetime": "2022-03-01T16:07:07Z",
                "device_geo_id": "9120a69e-cc23-451a-a55d-4223e0cec88b",
                "device_user_agent": "15.3.1",
                "geo_country_alpha_2": "AU",
                "geo_horizontal_accuracy": 20,
                "ipv4": "4.4.4.4",
                "latitude": -33.805888,
                "longitude": 150.781879
            },
            {
                "datetime": "2022-03-01T15:46:10Z",
                "device_geo_id": "c6d36363-c966-4c94-9163-cff050fc2257",
                "device_user_agent": "15.3.1",
                "geo_country_alpha_2": "AU",
                "geo_horizontal_accuracy": 15.6,
                "ipv4": "4.4.4.4",
                "latitude": -33.805855,
                "longitude": 150.781918
            },
            {
                "datetime": "2022-03-01T15:07:46Z",
                "device_geo_id": "44442ff1-3b71-406a-963c-3ece950e11f5",
                "device_user_agent": "15.3.1",
                "geo_country_alpha_2": "AU",
                "geo_horizontal_accuracy": 15.6,
                "ipv4": "4.4.4.4",
                "latitude": -33.805855,
                "longitude": 150.781918
            }
        ]
    }
}

Human Readable Output

HYAS Device_Geo records for ipv4 : 4.4.4.4

Date Time Device User Agent Geo Country Alpha 2 Geo Horizontal Accuracy IPV4 Latitude Longitude
2022-03-01T16:07:07Z 15.3.1 AU 20.0 4.4.4.4 -33 150
2022-03-01T15:46:10Z 15.3.1 AU 15.6 4.4.4.4 -33 150
2022-03-01T15:07:46Z 15.3.1 AU 15.6 4.4.4.4 -33 150

hyas-get-sinkhole-records-by-ipv4-address


Returns sinkhole information.

Base Command

hyas-get-sinkhole-records-by-ipv4-address

Input

Argument Name Description Required
ipv4 The ipv4 address value to query. Required
limit The maximum number of results to return. Optional

Context Output

Path Type Description
HYAS.Sinkhole.count String The sinkhole count
HYAS.Sinkhole.country_name String The country of the ip
HYAS.Sinkhole.data_port String The data port
HYAS.Sinkhole.datetime String The first seen date of the sinkhole
HYAS.Sinkhole.ipv4 String The ipv4 of the sinkhole
HYAS.Sinkhole.last_seen String The last seen date of the sinkhole
HYAS.Sinkhole.organization_name String The isp organization for the ip
HYAS.Sinkhole.sink_source String The ipv4 of the sink source

Command example

!hyas-get-sinkhole-records-by-ipv4-address ipv4=4.4.4.4 limit="3"

Context Example

{
    "HYAS": {
        "Sinkhole": [
            {
                "count": 18,
                "country_code": "GB",
                "country_name": "United Kingdom",
                "data_port": 5552,
                "datetime": "2020-12-23T14:06:56Z",
                "ipv4": "4.4.4.4",
                "last_seen": "2020-12-23T14:06:56Z",
                "organization_name": "Shahkar Towse'e Tejarat Mana PJSC",
                "sink_source": "4.4.4.4"
            },
            {
                "count": 157,
                "country_code": "GB",
                "country_name": "United Kingdom",
                "data_port": 5552,
                "datetime": "2020-12-23T13:59:28Z",
                "ipv4": "4.4.4.4",
                "last_seen": "2020-12-23T13:59:28Z",
                "organization_name": "Shahkar Towse'e Tejarat Mana PJSC",
                "sink_source": "4.4.4.4"
            },
            {
                "count": 160,
                "country_code": "GB",
                "country_name": "United Kingdom",
                "data_port": 5552,
                "datetime": "2020-12-23T12:59:44Z",
                "ipv4": "4.4.4.4",
                "last_seen": "2020-12-23T12:59:44Z",
                "organization_name": "Shahkar Towse'e Tejarat Mana PJSC",
                "sink_source": "4.4.4.4"
            }
        ]
    }
}

Human Readable Output

HYAS Sinkhole records for ipv4 : 4.4.4.4

Count Country Name Data Port Date Time IPV4 Last Seen Organization Name Sink Source
18 United Kingdom 5552 2020-12-23T14:06:56Z 4.4.4.4 2020-12-23T14:06:56Z Shahkar Towse’e Tejarat Mana PJSC 4.4.4.4
157 United Kingdom 5552 2020-12-23T13:59:28Z 4.4.4.4 2020-12-23T13:59:28Z Shahkar Towse’e Tejarat Mana PJSC 4.4.4.4
160 United Kingdom 5552 2020-12-23T12:59:44Z 4.4.4.4 2020-12-23T12:59:44Z Shahkar Towse’e Tejarat Mana PJSC 4.4.4.4

hyas-get-malware-sample-information-by-hash


Returns malware information.

Base Command

hyas-get-malware-sample-information-by-hash

Input

Argument Name Description Required
hash The hash value to query. Required

Context Output

Path Type Description
HYAS.Malware_Information.avscan_score String AV scan score
HYAS.Malware_Information.md5 String MD5 Hash
HYAS.Malware_Information.scan_results.av_name String The AV Name
HYAS.Malware_Information.scan_results.def_time String The AV datetime
HYAS.Malware_Information.scan_results.threat_found String The source
HYAS.Malware_Information.scan_time String The datetime of the scan
HYAS.Malware_Information.sha1 String The sha1 hash
HYAS.Malware_Information.sha256 String The sha256 hash
HYAS.Malware_Information.sha512 String The sha512 hash

Command example

!hyas-get-malware-sample-information-by-hash hash=1d0a97c41afe5540edd0a8c1fb9a0f1c limit="3"

Context Example

{
    "HYAS": {
        "Malware_Information": {
            "avscan_score": "1/9",
            "md5": "1d0a97c41afe5540edd0a8c1fb9a0f1c",
            "scan_results": [
                {
                    "av_name": "Cyren",
                    "def_time": "2023-02-13T09:49:00Z",
                    "threat_found": "abc"
                }
            ],
            "scan_time": "2023-02-21T07:36:35Z",
            "sha1": "9f3ae27d3d071b1cd0a220ec2d5944cde44af91a",
            "sha256": "3e3f900e6ab9e03f93fee334d357336f8ae67633420a462d0662fd51bc5004ab",
            "sha512": "956ab65f8119e9060cc955db31284bc99e6bf82bcd1b0dfcf29457cdf61acacf884209191692f8173970c6b28128e3c79d3126fd9f50df8c71612ee9b47710f9"
        }
    }
}

Human Readable Output

HYAS Malware_Information records for hash : 1d0a97c41afe5540edd0a8c1fb9a0f1c

AV Scan Score MD5 AV Name AV DateTime Source Scan Time SHA1 SHA256 SHA512
1/9 1d0a97c41afe5540edd0a8c1fb9a0f1c Cyren 2023-02-13T09:49:00Z abc 2023-02-21T07:36:35Z 9f3ae27d3d071b1cd0a220ec2d5944cde44af91a 3e3f900e6ab9e03f93fee334d357336f8ae67633420a462d0662fd51bc5004ab 956ab65f8119e9060cc955db31284bc99e6bf82bcd1b0dfcf29457cdf61acacf884209191692f8173970c6b28128e3c79d3126fd9f50df8c71612ee9b47710f9

hyas-get-associated-ips-by-hash


Returns associated IP’s for the provided hash value.

Base Command

hyas-get-associated-ips-by-hash

Input

Argument Name Description Required
md5 The md5 value to query. Required

Context Output

Path Type Description
HYAS.HASH-IP.md5 String The provided MD5 value
HYAS.HASH-IP.ips Unknown Associated IPS for the provided MD5 value

Command example

!hyas-get-associated-ips-by-hash md5="1d0a97c41afe5540edd0a8c1fb9a0f1c"

Context Example

{
    "HYAS": {
        "HASH-IP": {
            "ips": [
                "106.187.43.98"
            ],
            "md5": "1d0a97c41afe5540edd0a8c1fb9a0f1c"
        }
    }
}

Human Readable Output

HYAS HASH-IP records for md5 : 1d0a97c41afe5540edd0a8c1fb9a0f1c

Associated IPs
106.187.43.98

hyas-get-associated-domains-by-hash


Returns associated Domain’s for the provided hash value.

Base Command

hyas-get-associated-domains-by-hash

Input

Argument Name Description Required
md5 The md5 value to query. Required

Context Output

Path Type Description
HYAS.HASH-DOMAIN.domains Unknown Associated Domains for the provided MD5 value
HYAS.HASH-DOMAIN.md5 String The provided MD5 value

Command example

!hyas-get-associated-domains-by-hash md5="1d0a97c41afe5540edd0a8c1fb9a0f1c"

Context Example

{
    "HYAS": {
        "HASH-DOMAIN": {
            "domains": [
                "qwertasdfg.sinip.es",
                "butterfly.bigmoney.biz",
                "butterfly.sinip.es"
            ],
            "md5": "1d0a97c41afe5540edd0a8c1fb9a0f1c"
        }
    }
}

Human Readable Output

HYAS HASH-DOMAIN records for md5 : 1d0a97c41afe5540edd0a8c1fb9a0f1c

Associated Domains
qwertasdfg.sinip.es
butterfly.bigmoney.biz
butterfly.sinip.es

Configuration parameters

  • X-API-Key — HYAS Insight Api Key (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (14)

  • hyas-get-associated-domains-by-hash

    Returns associated Domain's for the provided hash value.

  • hyas-get-associated-ips-by-hash

    Returns associated IP's for the provided hash value.

  • hyas-get-c2attribution-records-by-indicator

    Return C2 Attribution records for the provided indicator value.

  • hyas-get-device-geo-records-by-ip-address

    Returns a list of mobile geolocation information.

  • hyas-get-dynamic-dns-records-by-indicator

    Returns DynamicDNS records for the provided indicator value.

  • hyas-get-malware-sample-information-by-hash

    Returns malware information.

  • hyas-get-malware-samples-records-by-indicator

    Returns Malware Sample records for the provided indicator value.

  • hyas-get-opensource-indicator-records-by-indicator

    Return Open Source intel records for the provided indicator value.

  • hyas-get-passive-dns-records-by-indicator

    Returns PassiveDNS records for the provided indicator value.

  • hyas-get-passive-hash-records-by-indicator

    Return passive hash records for the provided indicator value.

  • hyas-get-sinkhole-records-by-ipv4-address

    Returns sinkhole information.

  • hyas-get-ssl-certificate-records-by-indicator

    Return SSL certificate records for the provided indicator value.

  • hyas-get-whois-current-records-by-domain

    Returns WHOIS Current records for the provided indicator value.

  • hyas-get-whois-records-by-indicator

    Returns WHOIS records for the provided indicator value.

from collections.abc import Callable  # noqa:F401

from CommonServerPython import *
from urllib3 import disable_warnings

# Disable insecure warnings
disable_warnings()

# CORTEX XSOAR COMMAND CONSTANTS
INTEGRATION_NAME = "HYAS INSIGHT"
INTEGRATION_COMMAND_NAME = "hyas"
INTEGRATION_CONTEXT_NAME = "HYAS"
PASSIVE_DNS_SUB_CONTEXT = "PassiveDNS"
DYNAMIC_DNS_SUB_CONTEXT = "DynamicDNS"
WHOIS_SUB_CONTEXT = "WHOIS"
WHOIS_CURRENT_SUB_CONTEXT = "WHOISCurrent"
MALWARE_SUB_CONTEXT = "MalwareSamples"
HASH_IP_SUB_CONTEXT = "HASH-IP"
HASH_DOMAIN_SUB_CONTEXT = "HASH-DOMAIN"
C2_ATTRIBUTION_SUB_CONTEXT = "C2_Attribution"
PASSIVE_HASH_SUB_CONTEXT = "Passive_Hash"
SSL_CERTIFICATE_SUB_CONTEXT = "SSL_Certificate"
OS_INDICATORS_SUB_CONTEXT = "OS_Indicators"
DEVICE_GEO_SUB_CONTEXT = "Device_Geo"
SINKHOLE_SUB_CONTEXT = "Sinkhole"
MALWARE_INFO_SUB_CONTEXT = "Malware_Information"
# HYAS API BASE URL
HYAS_API_BASE_URL = "https://apps.hyas.com/api/ext/"
WHOIS_CURRENT_BASE_URL = "https://api.hyas.com/"
TIMEOUT = 60

# HYAS API endpoints
PASSIVE_DNS_ENDPOINT = "passivedns"
DYNAMIC_DNS_ENDPOINT = "dynamicdns"
WHOIS_ENDPOINT = "whois"
MALWARE_ENDPOINT = "sample"
WHOIS_CURRENT_ENDPOINT = "whois/v1"
C2_ATTRIBUTION_ENDPOINT = "c2attribution"
PASSIVE_HASH_ENDPOINT = "passivehash"
SSL_CERTIFICATE_ENDPOINT = "ssl_certificate"
OS_INDICATORS_ENDPOINT = "os_indicators"
DEVICE_GEO_ENDPOINT = "device_geo"
SINKHOLE_ENDPOINT = "sinkhole"
MALWARE_INFO_ENDPOINT = "sample/information"

# HYAS API INPUT PARAMETERS
PASSIVE_DNS_QUERY_PARAMS = ["domain", "ipv4"]
DYNAMIC_DNS_QUERY_PARAMS = ["ip", "domain", "email"]
WHOIS_QUERY_PARAMS = ["domain", "email", "phone"]
MALWARE_QUERY_PARAMS = ["domain", "ipv4", "md5"]
C2_ATTRIBUTION_QUERY_PARAMS = ["domain", "ip", "email", "sha256"]
PASSIVE_HASH_QUERY_PARAMS = ["domain", "ipv4"]
SSL_CERTIFICATE_QUERY_PARAMS = ["domain", "ip", "sha1"]
OS_INDICATORS_QUERY_PARAMS = ["domain", "ipv4", "ipv6", "sha1", "sha256", "md5"]
DEVICE_GEO_QUERY_PARAMS = ["ipv4", "ipv6"]
SINKHOLE_QUERY_PARAMS = ["ipv4"]
MALWARE_INFO_QUERY_PARAMS = ["hash"]

DOMAIN_PARAM = "domain"
IP_PARAM = "ip"
IPV4_PARAM = "ipv4"
IPV6_PARAM = "ipv6"
EMAIL_PARAM = "email"
PHONE_PARAM = "phone"
MD5_PARAM = "md5"
SHA1_PARAM = "sha1"
SHA256_PARAM = "sha256"
SHA512_PARAM = "sha512"
HASH_PARAM = "hash"


class Client(BaseClient):
    def __init__(self, base_url: str, apikey: str, verify=None, proxy=None):
        BaseClient.__init__(
            self,
            base_url,
            verify=verify,
            headers={"Content-type": "application/json", "X-API-Key": apikey, "User-Agent": "Cortex XSOAR"},
            proxy=proxy,
            ok_codes=(200,),
        )
        self.apikey = apikey

    def fetch_data_from_hyas_api(
        self, end_point: str, ind_type: str, ind_value: str, current: bool, req_method: str, limit=0
    ) -> list[Dict]:
        """

        :param limit: "limit the number of records returned, default to 50"
        :param end_point: HYAS endpoint
        :param ind_type: indicator_type provided in the command
        :param ind_value: indicator_value provided in the command
        :param current: boolean for whois endpoint
        :param req_method: request method POST,GET
        :return: return the raw api response from HYAS API.
        """
        return self.query(end_point, ind_type, ind_value, current, req_method, limit)

    def query(self, end_point: str, ind_type: str, ind_value: str, current: bool, method: str, limit: int) -> list[Dict]:
        """

        :param limit: "limit the number of records returned, default to 50"
        :param end_point: HYAS endpoint
        :param ind_type: indicator_type provided in the command
        :param ind_value: indicator_value provided in the command
        :param current: boolean for whois endpoint
        :param method: request method POST,GET
        :return: return the raw api response from HYAS API.

        """
        response = []
        if method == "GET":
            url_path = f"{end_point}/search?{ind_type}={ind_value}"
            response = self._http_request("GET", url_suffix=url_path, timeout=TIMEOUT)
        elif method == "POST":
            url_path = f"{end_point}"
            req_body = self.request_body(ind_type, ind_value, current)
            response = self._http_request("POST", url_suffix=url_path, json_data=req_body, timeout=TIMEOUT)
        if limit != 0:
            return response[:limit]
        return response

    @staticmethod
    def request_body(query_param: str, query_input: str, current: bool) -> Dict[str, Any]:
        """
        This Method returns the request body for specific endpoint.
        """

        if current:
            return {"applied_filters": {query_param: query_input, "current": True}}
        else:
            return {"applied_filters": {query_param: query_input}}

    def test_module(self, domain: str, value: str) -> str:
        """
        :param domain: hard coded domain type
        :param value: hard coded domain value
        :return: connection ok

        """

        try:
            self.query(DYNAMIC_DNS_ENDPOINT, domain, value, False, "POST", 2)
        except DemistoException as e:
            if "401" in str(e):
                return "Authorization Error: Provided apikey is not valid"
            else:
                raise e
        return "ok"


def flatten_json(y: Dict) -> Dict[str, Any]:
    """
    :param y: raw_response from HYAS api
    :return: Flatten json response

    """
    out = {}

    def flatten(x, name=""):
        # If the Nested key-value
        # pair is of dict type
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + "_")
        else:
            out[name[:-1]] = x

    flatten(y)
    return out


def check_valid_indicator_type(indicator_type: str, api_query_params: list) -> bool:
    """
    :param indicator_type: indicator type provided in the command
    :param api_query_params: HYAS API Endpoint query params constant defined
    :return: True if the indicator type is valid

    """
    if indicator_type not in api_query_params:
        raise ValueError(f"Invalid indicator_type: {indicator_type}, Valid indicator_type are {api_query_params}")
    return True


def check_valid_hash_type(hash_type: list, hash_value: str, check_all: bool = False):
    """
    :param hash_type: hash_type
    :param hash_value: hash_value
    :param check_all: test all the values
    :return: true if the hash value is valid

    """
    if not check_all:
        if MD5_PARAM in hash_type:
            if not re.match(md5Regex, hash_value):
                raise ValueError(f"Invalid indicator_value: {hash_value} for indicator_type {MD5_PARAM}")
        elif SHA1_PARAM in hash_type:
            if not re.match(sha1Regex, hash_value):
                raise ValueError(f"Invalid indicator_value: {hash_value} for indicator_type {SHA1_PARAM}")
        elif SHA256_PARAM in hash_type:
            if not re.match(sha256Regex, hash_value):
                raise ValueError(f"Invalid indicator_value: {hash_value} for indicator_type {SHA256_PARAM}")
        elif SHA512_PARAM in hash_type and not re.match(sha512Regex, hash_value):
            raise ValueError(f"Invalid indicator_value: {hash_value} for indicator_type {SHA512_PARAM}")
    else:
        if (
            re.match(md5Regex, hash_value)
            or re.match(sha1Regex, hash_value)
            or re.match(sha256Regex, hash_value)
            or re.match(sha512Regex, hash_value)
        ):
            pass
        else:
            raise ValueError(f"Invalid indicator_value: {hash_value} for indicator_type {HASH_PARAM}")


def check_valid_indicator_value(indicator_type: str, indicator_value: str) -> bool:
    """

    :param indicator_type: Indicator type provided in the command
    :param indicator_value: Indicator value provided in the command
    :return: true if the indicator value provided for the indicator type is valid

    """

    phone_regex = re.compile(r"^\+?[1-9]\d{1,14}$")

    if indicator_type == IPV4_PARAM:
        if not re.match(ipv4Regex, indicator_value):
            raise ValueError(f"Invalid indicator_value: {indicator_value} for indicator_type {indicator_type}")
    elif indicator_type == IPV6_PARAM:
        if not re.match(ipv6Regex, indicator_value):
            raise ValueError(f"Invalid indicator_value: {indicator_value} for indicator_type {indicator_type}")
    elif indicator_type == DOMAIN_PARAM:
        if not re.match(domainRegex, indicator_value):
            raise ValueError(f"Invalid indicator_value: {indicator_value} for indicator_type {indicator_type}")
    elif indicator_type == IP_PARAM:
        if not is_ip_valid(indicator_value, accept_v6_ips=True):  # check IP's validity
            raise ValueError(f"Invalid indicator_value: {indicator_value} for indicator_type {indicator_type}")
    elif indicator_type == EMAIL_PARAM:
        if not re.match(emailRegex, indicator_value):
            raise ValueError(f"Invalid indicator_value: {indicator_value} for indicator_type {indicator_type}")
    elif indicator_type == PHONE_PARAM:
        if not re.match(phone_regex, indicator_value):
            raise ValueError(f"Invalid indicator_value: {indicator_value} for indicator_type {indicator_type}")
    elif indicator_type == MD5_PARAM:
        check_valid_hash_type([MD5_PARAM], indicator_value)
    elif indicator_type == SHA1_PARAM:
        check_valid_hash_type([SHA1_PARAM], indicator_value)
    elif indicator_type == SHA256_PARAM:
        check_valid_hash_type([SHA256_PARAM], indicator_value)
    elif indicator_type == SHA512_PARAM:
        check_valid_hash_type([SHA512_PARAM], indicator_value)
    elif indicator_type == HASH_PARAM:
        check_valid_hash_type([MD5_PARAM, SHA1_PARAM, SHA256_PARAM, SHA512_PARAM], indicator_value, True)

    return True


def get_command_title_string(sub_context: str, indicator_type: str, indicator_value: str) -> str:
    """

    :param sub_context: Commands sub_context
    :param indicator_type: Indicator type provided in the command
    :param indicator_value: Indicator value provided in the command
    :return: returns the title for the readable output

    """
    return INTEGRATION_CONTEXT_NAME + " " + sub_context + " records for " + indicator_type + " : " + indicator_value


def get_flatten_json_response(raw_api_response: list[Dict], endpoint: str) -> list[Dict]:
    """

    :param raw_api_response: raw_api response from the API
    :param endpoint: Endpoint
    :return: Flatten Json response

    """
    flatten_json_response = []
    if raw_api_response:
        for obj in raw_api_response:
            if endpoint == OS_INDICATORS_ENDPOINT:
                data = json.loads(obj.get("data", "{}"))
                obj = {**obj, **data}
            flatten_json_response.append(flatten_json(obj))

    return flatten_json_response


@logger
def passive_dns_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Count", "count", str),
        ("Domain", "domain", str),
        ("First seen", "first_seen", str),
        ("City Name", "ip_geo_city_name", str),
        ("Country Code", "ip_geo_country_iso_code", str),
        ("Country Name", "ip_geo_country_name", str),
        ("Latitude", "ip_geo_location_latitude", str),
        ("Longitude", "ip_geo_location_longitude", str),
        ("Postal Code", "ip_geo_postal_code", str),
        ("IP", "ip_ip", str),
        ("ISP ASN", "ip_isp_autonomous_system_number", str),
        ("ISP ASN Organization", "ip_isp_autonomous_system_organization", str),
        ("ISP IP Address", "ip_isp_ip_address", str),
        ("ISP", "ip_isp_isp", str),
        ("ISP Organization", "ip_isp_organization", str),
        ("IPV4", "ipv4", str),
        ("Last Seen", "last_seen", str),
        ("Sources", "sources", list),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def dynamic_dns_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("A Record", "a_record", str),
        ("Account", "account", str),
        ("Created Date", "created", str),
        ("Account Holder IP Address", "created_ip", str),
        ("Domain", "domain", str),
        ("Domain Creator IP Address", "domain_creator_ip", str),
        ("Email Address", "email", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def whois_historic_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Address", "address", list),
        ("City", "city", list),
        ("Country", "country", list),
        ("Domain", "domain", str),
        ("Domain_2tld", "domain_2tld", str),
        ("Domain Created Time", "domain_created_datetime", str),
        ("Domain Expires Time", "domain_expires_datetime", str),
        ("Domain Updated Time", "domain_updated_datetime", str),
        ("Email Address", "email", list),
        ("IDN Name", "idn_name", str),
        ("Nameserver", "nameserver", list),
        ("Phone Info", "phone", list),
        ("Privacy_punch", "privacy_punch", bool),
        ("Registrar", "registrar", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def whois_current_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Abuse Emails", "abuse_emails", list),
        ("Address", "address", list),
        ("City", "city", list),
        ("Country", "country", list),
        ("Domain", "domain", str),
        ("Domain_2tld", "domain_2tld", str),
        ("Domain Created Time", "domain_created_datetime", str),
        ("Domain Expires Time", "domain_expires_datetime", str),
        ("Domain Updated Time", "domain_updated_datetime", str),
        ("Email Address", "email", list),
        ("IDN Name", "idn_name", str),
        ("Nameserver", "nameserver", list),
        ("Organization", "organization", list),
        ("Phone Info", "phone", list),
        ("Registrar", "registrar", str),
        ("State", "state", list),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def malware_samples_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Datetime", "datetime", str),
        ("Domain", "domain", str),
        ("IPV4 Address", "ipv4", str),
        ("IPV6 Address", "ipv6", str),
        ("MD5 Value", "md5", str),
        ("SHA1 Value", "sha1", str),
        ("SHA256 Value", "sha256", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def associated_ips_lookup_to_markdown(results: list, title: str) -> str:
    headers = "Associated IPs"
    out = results
    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def associated_domains_lookup_to_markdown(results: list[Dict], title: str) -> str:
    headers = "Associated Domains"
    out = results
    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def c2_attribution_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Actor IPv4", "actor_ipv4", str),
        ("C2 Domain", "c2_domain", str),
        ("C2 IP", "c2_ip", str),
        ("C2 URL", "c2_url", str),
        ("Datetime", "datetime", str),
        ("Email", "email", str),
        ("Email Domain", "email_domain", str),
        ("Referrer Domain", "referrer_domain", str),
        ("Referrer IPv4", "referrer_ipv4", str),
        ("Referrer URL", "referrer_url", str),
        ("SHA256", "sha256", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def passive_hash_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys: list[tuple[str, str, Callable]] = [("Domain", "domain", str), ("MD5 Count", "md5_count", str)]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def ssl_certificate_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Geo City Name", "geo_geo_city_name", str),
        ("Geo Country ISO code", "geo_geo_country_iso_code", str),
        ("Geo Country Name", "geo_geo_country_name", str),
        ("Latitude", "geo_geo_location_latitude", str),
        ("Longitude", "geo_geo_location_longitude", str),
        ("Postal Code", "geo_geo_postal_code", str),
        ("ISP Autonomous System Number", "geo_isp_autonomous_system_number", str),
        ("ISP Autonomous System Organization", "geo_isp_autonomous_system_organization", str),
        ("Geo ISP", "geo_isp_isp", str),
        ("Geo ISP Organization", "geo_isp_organization", str),
        ("IP", "ip", str),
        ("SSL Certificate Key", "ssl_cert_cert_key", str),
        ("Expire Date", "ssl_cert_expire_date", str),
        ("Issue Date", "ssl_cert_issue_date", str),
        ("Issuer Common Name", "ssl_cert_issuer_commonName", str),
        ("Issuer Country Name", "ssl_cert_issuer_countryName", str),
        ("Issuer Locality Name", "ssl_cert_issuer_localityName", str),
        ("Issuer Organization Name", "ssl_cert_issuer_organizationName", str),
        ("Issuer Organizational UnitName", "ssl_cert_issuer_organizationalUnitName", str),
        ("Issuer State/Province Name", "ssl_cert_issuer_stateOrProvinceName", str),
        ("Certificate MD5", "ssl_cert_md5", str),
        ("Certificate Serial Number", "ssl_cert_serial_number", str),
        ("Certificate SHA1", "ssl_cert_sha1", str),
        ("Certificate SHA256", "ssl_cert_sha_256", str),
        ("Certificate Signature Algo", "ssl_cert_sig_algo", str),
        ("Certificate SSL Version", "ssl_cert_ssl_version", str),
        ("Certificate Subject Common Name", "ssl_cert_subject_commonName", str),
        ("Certificate Subject Country Name", "ssl_cert_subject_countryName", str),
        ("Certificate Subject Locality Name", "ssl_cert_subject_localityName", str),
        ("Certificate Subject Organization Name", "ssl_cert_subject_organizationName", str),
        ("Certificate Subject Organizational Unit Name", "ssl_cert_subject_organizationalUnitName", str),
        ("Certificate Subject State/Province Name", "ssl_cert_subject_stateOrProvinceName", str),
        ("Certificate Timestamp", "ssl_cert_timestamp", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def open_source_indicators_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []
    # print(results)
    keys = [  # type: ignore[name-defined]
        ("Correlation Score", "map_correlation_score", float),
        ("Host IP", "map_host_ips_myArrayList", list),
        ("Nameserver", "map_nameservers_myArrayList", list),
        ("Stub Count", "map_stub_count", int),
        ("Type", "map_type", str),
        ("Context", "context", str),
        ("Date Time", "datetime", str),
        ("Domain", "domain", str),
        ("Domain 2TLD", "domain_2tld", str),
        ("First Seen", "first_seen", str),
        ("IPV4", "ipv4", str),
        ("IPV6", "ipv6", str),
        ("Last Seen", "last_seen", str),
        ("MD5", "md5", str),
        ("SHA1", "sha1", str),
        ("SHA256", "sha256", str),
        ("Source Name", "source_name", str),
        ("Source Url", "source_url", str),
        ("URI", "uri", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def device_geo_indicators_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys: list[tuple[str, str, Callable]] = [
        ("Date Time", "datetime", str),
        ("Device User Agent", "device_user_agent", str),
        ("Geo Country Alpha 2", "geo_country_alpha_2", str),
        ("Geo Horizontal Accuracy", "geo_horizontal_accuracy", str),
        ("IPV4", "ipv4", str),
        ("IPV6", "ipv6", str),
        ("Latitude", "latitude", int),
        ("Longitude", "longitude", int),
        ("WiFi BSSID", "wifi_bssid", str),
    ]

    headers = [k[0] for k in keys]
    for result in results:
        row: dict[str, Any] = {}
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def sinkhole_indicators_lookup_to_markdown(results: list[Dict], title: str) -> str:
    out = []

    keys = [  # type: ignore[name-defined]
        ("Count", "count", str),
        ("Country Name", "country_name", str),
        ("Data Port", "data_port", str),
        ("Date Time", "datetime", str),
        ("IPV4", "ipv4", str),
        ("Last Seen", "last_seen", str),
        ("Organization Name", "organization_name", str),
        ("Sink Source", "sink_source", str),
    ]  # type: List[Tuple[str, str, Callable]]

    headers = [k[0] for k in keys]
    for result in results:
        row = {}  # type: Dict[str, Any]
        for ckey, rkey, f in keys:
            if rkey in result:
                row[ckey] = f(result[rkey])
        out.append(row)

    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def malware_info_lookup_to_markdown(results: Dict, title: str) -> str:
    scan_results = results.get("scan_results", [])
    out = []
    if scan_results:
        for res in scan_results:
            malware_info_data = {
                "AV Scan Score": results.get("avscan_score", ""),
                "MD5": results.get("md5", ""),
                "AV Name": res.get("av_name", ""),
                "AV DateTime": res.get("def_time", ""),
                "Source": res.get("threat_found", ""),
                "Scan Time": results.get("scan_time", ""),
                "SHA1": results.get("sha1", ""),
                "SHA256": results.get("sha256", ""),
                "SHA512": results.get("sha512", ""),
            }
            out.append(malware_info_data)
    else:
        malware_info_data = {
            "AV Scan Score": results.get("avscan_score", ""),
            "MD5": results.get("md5", ""),
            "AV Name": "",
            "AV DateTime": "",
            "Source": "",
            "Scan Time": results.get("scan_time", ""),
            "SHA1": results.get("sha1", ""),
            "SHA256": results.get("sha256", ""),
            "SHA512": results.get("sha512", ""),
        }
        out.append(malware_info_data)

    headers = out[0]
    headers = list(headers.keys())
    return tableToMarkdown(title, out, headers=headers, removeNull=True)


@logger
def get_malware_sample_information_by_hash(client, args):
    hash_value = args.get("hash")
    check_valid_indicator_type(HASH_PARAM, MALWARE_INFO_QUERY_PARAMS)
    check_valid_indicator_value(HASH_PARAM, hash_value)
    title = get_command_title_string(MALWARE_INFO_SUB_CONTEXT, HASH_PARAM, hash_value)
    end_point = MALWARE_INFO_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, HASH_PARAM, hash_value, False, "POST")
    lookup_result: str = ""
    if raw_api_response:
        lookup_result = malware_info_lookup_to_markdown(raw_api_response, title)
    return CommandResults(
        readable_output=lookup_result,
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{MALWARE_INFO_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_sinkhole_records_by_ipv4_address(client, args):
    flatten_json_response = []
    ipv4_value = args.get("ipv4")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(IPV4_PARAM, SINKHOLE_QUERY_PARAMS)
    check_valid_indicator_value(IPV4_PARAM, ipv4_value)
    title = get_command_title_string(SINKHOLE_SUB_CONTEXT, IPV4_PARAM, ipv4_value)
    end_point = SINKHOLE_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, IPV4_PARAM, ipv4_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=sinkhole_indicators_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{SINKHOLE_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_device_geo_records_by_ip_address(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, DEVICE_GEO_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(DEVICE_GEO_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = DEVICE_GEO_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=device_geo_indicators_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{DEVICE_GEO_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_opensource_indicator_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, OS_INDICATORS_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(OS_INDICATORS_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = OS_INDICATORS_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=open_source_indicators_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{OS_INDICATORS_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_ssl_certificate_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, SSL_CERTIFICATE_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(SSL_CERTIFICATE_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = SSL_CERTIFICATE_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", 0)
    if raw_api_response:
        raw_api_response = raw_api_response["ssl_certs"]
        if limit and limit > 0:
            raw_api_response = raw_api_response[:limit]
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=ssl_certificate_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{SSL_CERTIFICATE_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_passive_hash_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, PASSIVE_HASH_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(PASSIVE_HASH_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = PASSIVE_HASH_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=passive_hash_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{PASSIVE_HASH_SUB_CONTEXT}",
        outputs_key_field="domain",
        outputs=raw_api_response,
    )


@logger
def get_c2attribution_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, C2_ATTRIBUTION_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(C2_ATTRIBUTION_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = C2_ATTRIBUTION_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)
    outputs_key_field = {"ip": "actor_ipv4", "domain": "c2_domain", "email": "email", "sha256": "sha256"}

    return CommandResults(
        readable_output=c2_attribution_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{C2_ATTRIBUTION_SUB_CONTEXT}",
        outputs_key_field=outputs_key_field.get(indicator_type),
        outputs=raw_api_response,
    )


@logger
def get_passive_dns_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, PASSIVE_DNS_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(PASSIVE_DNS_SUB_CONTEXT, indicator_type, indicator_value)

    end_point = PASSIVE_DNS_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=passive_dns_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{PASSIVE_DNS_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_dynamic_dns_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, DYNAMIC_DNS_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(DYNAMIC_DNS_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = DYNAMIC_DNS_ENDPOINT
    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=dynamic_dns_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{DYNAMIC_DNS_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_whois_records_by_indicator(client, args):
    flatten_json_response = []
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, WHOIS_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(WHOIS_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = WHOIS_ENDPOINT

    raw_api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)
    if raw_api_response:
        flatten_json_response = get_flatten_json_response(raw_api_response, end_point)

    return CommandResults(
        readable_output=whois_historic_lookup_to_markdown(flatten_json_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{WHOIS_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=raw_api_response,
    )


@logger
def get_whois_current_records_by_domain(client, args):
    whois_current_record: list[Any] = []
    indicator_type = DOMAIN_PARAM
    indicator_value = args.get("domain")
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(WHOIS_CURRENT_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = WHOIS_CURRENT_ENDPOINT

    api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, True, "POST")
    if api_response:
        whois_current_record = api_response.get("items", [])

    return CommandResults(
        readable_output=whois_current_lookup_to_markdown(whois_current_record, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{WHOIS_CURRENT_SUB_CONTEXT}",
        outputs_key_field="domain",
        outputs=api_response,
    )


@logger
def get_malware_samples_records_by_indicator(client, args):
    indicator_type = args.get("indicator_type")
    indicator_value = args.get("indicator_value")
    limit = arg_to_number(args.get("limit", 0), arg_name="limit")
    check_valid_indicator_type(indicator_type, MALWARE_QUERY_PARAMS)
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(MALWARE_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = MALWARE_ENDPOINT

    api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST", limit)

    return CommandResults(
        readable_output=malware_samples_lookup_to_markdown(api_response, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{MALWARE_SUB_CONTEXT}",
        outputs_key_field="",
        outputs=api_response,
    )


@logger
def get_associated_ips_by_hash(client, args):
    indicator_type = MD5_PARAM
    indicator_value = args.get("md5")
    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(HASH_IP_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = MALWARE_ENDPOINT
    api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST")

    associated_ips = [str(obj["ipv4"]) for obj in api_response if "ipv4" in obj]
    outputs = {"md5": indicator_value, "ips": associated_ips}
    return CommandResults(
        readable_output=associated_ips_lookup_to_markdown(associated_ips, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{HASH_IP_SUB_CONTEXT}",
        outputs_key_field="md5",
        outputs=outputs,
    )


@logger
def get_associated_domains_by_hash(client, args):
    indicator_type = MD5_PARAM
    indicator_value = args.get("md5")

    check_valid_indicator_value(indicator_type, indicator_value)
    title = get_command_title_string(HASH_DOMAIN_SUB_CONTEXT, indicator_type, indicator_value)
    end_point = MALWARE_ENDPOINT
    api_response = client.fetch_data_from_hyas_api(end_point, indicator_type, indicator_value, False, "POST")
    associated_domains: list[str] = [str(obj["domain"]) for obj in api_response if "domain" in obj]
    outputs = {"md5": indicator_value, "domains": associated_domains}
    return CommandResults(
        readable_output=associated_domains_lookup_to_markdown(associated_domains, title),
        outputs_prefix=f"{INTEGRATION_CONTEXT_NAME}.{HASH_DOMAIN_SUB_CONTEXT}",
        outputs_key_field="md5",
        outputs=outputs,
    )


@logger
def test_module(client):
    return client.test_module("domain", "www.hyas.com")


def main():
    """
    PARSE AND VALIDATE INTEGRATION PARAMS
    """

    apikey = demisto.params().get("X-API-Key")
    verify_certificate = not demisto.params().get("insecure", False)
    proxy = demisto.params().get("proxy", False)

    try:
        command = demisto.command()
        if command == f"{INTEGRATION_COMMAND_NAME}-get-whois-current-records-by-domain":
            base_url = WHOIS_CURRENT_BASE_URL
        else:
            base_url = HYAS_API_BASE_URL
        client = Client(base_url, apikey, verify=verify_certificate, proxy=proxy)
        LOG(f"Command being called is {command}")
        if command == "test-module":
            # This is the call made when pressing the integration Test button.
            return_results(test_module(client))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-passive-dns-records-by-indicator":
            return_results(get_passive_dns_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-dynamic-dns-records-by-indicator":
            return_results(get_dynamic_dns_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-whois-records-by-indicator":
            return_results(get_whois_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-whois-current-records-by-domain":
            return_results(get_whois_current_records_by_domain(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-malware-samples-records-by-indicator":
            return_results(get_malware_samples_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-associated-ips-by-hash":
            return_results(get_associated_ips_by_hash(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-associated-domains-by-hash":
            return_results(get_associated_domains_by_hash(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-c2attribution-records-by-indicator":
            return_results(get_c2attribution_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-passive-hash-records-by-indicator":
            return_results(get_passive_hash_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-ssl-certificate-records-by-indicator":
            return_results(get_ssl_certificate_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-opensource-indicator-records-by-indicator":
            return_results(get_opensource_indicator_records_by_indicator(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-device-geo-records-by-ip-address":
            return_results(get_device_geo_records_by_ip_address(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-sinkhole-records-by-ipv4-address":
            return_results(get_sinkhole_records_by_ipv4_address(client, demisto.args()))
        elif command == f"{INTEGRATION_COMMAND_NAME}-get-malware-sample-information-by-hash":
            return_results(get_malware_sample_information_by_hash(client, demisto.args()))
            # Log exceptions
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        err_msg = f"Error in {INTEGRATION_NAME} Integration [{e}]"
        return_error(err_msg, error=e)


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