Whois

Provides data enrichment for domains.

Data Enrichment & Threat Intelligence · Whois

Details

IDWhois
ProviderOpen Source
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/ippysocks-py3:1.0.0.11195141
Supported ModulesAgentix XSIAM

README

Provides data enrichment for domains.
This integration was integrated and tested with version 1.0 of Whois

Configure Whois in Cortex

Parameter Description Required
Return Errors If set, failed command results will be returned as warnings instead of errors. False
Proxy URL Supports socks4/socks5/http connect proxies (e.g. socks5h://host:1080). Will effect all commands except for the `ip` command. False
Use system proxy settings Effect the `ip` command and the other commands only if the Proxy URL is not set. False
Use legacy context Indicates whether to use the previous/legacy implementation of the integration commands and their outputs or the new ones. False
Source Reliability Reliability of the source providing the intelligence data. True
Rate Limit Retry Count The number of times to try when getting a Rate Limit response. False
Rate Limit Wait Seconds The number of seconds to wait between each iteration when getting a Rate Limit response. False
Suppress Rate Limit errors Whether Rate Limit errors should be supressed or not. 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.

whois


Provides data enrichment for domains.
This pack relies on free services for WHOIS information. As with many free services, the availability is not guaranteed. Free WHOIS providers may block or be reject queries.

Base Command

whois

Input

Argument Name Description Required
query The domain to enrich. Required
recursive Whether to get the raw response from the whois servers recursively. Default value is True. Optional
verbose Whether to add the raw response as a dictionary to the context. Optional

Context Output

Path Type Description
DBotScore.Score string The actual score.
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.Reliability String Reliability of the source providing the intelligence data.
Domain.Name string The domain name.
Domain.DomainStatus string The domain status.
Domain.Dnssec string The domain name system security extension (DNSSEC).
Domain.NameServers string The name servers.
Domain.Country string The domain country.
Domain.State string The domain state.
Domain.City string The domain city.
Domain.CreationDate date The date that the domain was created (UTC).
Domain.UpdatedDate date The date that the domain was last updated (UTC).
Domain.ExpirationDate date The date that the domain expires (UTC).
Domain.Registrar.Name string The name of the registrar.
Domain.Registrar.Address string The address of the registrar.
Domain.Registrar.Email string The email of the registrar.
Domain.Registrar.Id string The ID of the registrar.
Domain.Registrar.Phone string The phone number of the registrar.
Domain.Registrar.Url string The URL of the registrar.
Domain.Registrar.AbuseEmail string The email address of the contact for reporting abuse.
Domain.Emails string The abuse emails.
Domain.Address string The abuse address.
Domain.Organization string The organization domain name.
Domain.WhoisServer string The whois server name.
Domain.Phone string The phone number of the tech administrator.
Domain.Admin object Administrator information.
Domain.Admin.Address string The address of the administrator.
Domain.Admin.ApplicationPurpose string The application purpose of the administrator.
Domain.Admin.C string The C field of the administrator.
Domain.Admin.City string The city of the administrator.
Domain.Admin.Country string The country of the administrator.
Domain.Admin.Email string The email address of the administrator.
Domain.Admin.Fax string The fax number of the administrator.
Domain.Admin.FaxExt string The fax extension of the administrator.
Domain.Admin.Id string The ID of the administrator.
Domain.Admin.Name string The name of the administrator.
Domain.Admin.Org string The organization of the administrator.
Domain.Admin.Phone string The phone number of the administrator.
Domain.Admin.PhoneExt string The phone extension of the administrator.
Domain.Admin.PostalCode string The postal code of the administrator.
Domain.Admin.State string The state of the administrator.
Domain.Admin.StateProvince string The state or province of the administrator.
Domain.Admin.Street string The street of the administrator.
Domain.Registrant.Name string The name of the registrant.
Domain.Registrant.Email string The email address of the registrant.
Domain.Registrant.Country string The country of the registrant.
Domain.Registrant.State string The state of the registrant.
Domain.Registrant.Org string The organization of the registrant.
Domain.Registrant.PostalCode string The postal code of the registrant.
Domain.Registrant.Street string The street of the registrant.
Domain.Registrant.Phone string The phone number of the registrant.
Domain.Registrant.City string The city of the registrant.
Domain.Registrant.Address string The address of the registrant.
Domain.Registrant.ContactName string The contact name of the registrant.
Domain.Registrant.Fax string The fax of the registrant.
Domain.Registrant.Id string The ID of the registrant.
Domain.Registrant.Number string The number of the registrant.
Domain.Registrant.StateProvince string The state province of the registrant.
Domain.Raw string The raw output from python-whois lib.
Domain.Administrator string The country of the domain administrator.
Domain.Tech.Name string The name of the tech contact.
Domain.Tech.Address string The address of the tech contact.
Domain.Tech.City string The city of the tech contact.
Domain.Tech.Country string The country of the tech contact.
Domain.Tech.Email string The email address of the tech contact.
Domain.Tech.Fax string The fax number of the tech contact.
Domain.Tech.ID string The ID of the tech contact.
Domain.Tech.Organization string The organization of the tech contact.
Domain.Tech.Phone string The phone number of the tech contact.
Domain.Tech.PostalCode string The postal code of the tech contact.
Domain.Tech.State string The state of the tech contact.
Domain.Tech.StateProvince string The state/province of the tech contact.
Domain.Tech.Street string The street of the tech contact.
Domain.ID string The ID of the domain.
Domain.WHOIS.Name string The domain name.
Domain.WHOIS.DomainStatus string The domain status.
Domain.WHOIS.Dnssec string The domain name system security extension (DNSSEC).
Domain.WHOIS.NameServers string The name servers.
Domain.WHOIS.Country string The domain country.
Domain.WHOIS.State string The domain state.
Domain.WHOIS.City string The domain city.
Domain.WHOIS.CreationDate date The date that the domain was created (UTC).
Domain.WHOIS.UpdatedDate date The date that the domain was last updated (UTC).
Domain.WHOIS.ExpirationDate date The date that the domain expires (UTC).
Domain.WHOIS.Registrar.Name string The name of the registrar.
Domain.WHOIS.Registrar.Address string The address of the registrar.
Domain.WHOIS.Registrar.Email string The email of the registrar.
Domain.WHOIS.Registrar.Id string The ID of the registrar.
Domain.WHOIS.Registrar.Phone string The phone number of the registrar.
Domain.WHOIS.Registrar.Url string The URL of the registrar.
Domain.WHOIS.Registrar.AbuseEmail string The email address of the contact for reporting abuse.
Domain.WHOIS.Emails string The abuse emails.
Domain.WHOIS.Address string The abuse address.
Domain.WHOIS.Organization string The organization domain name.
Domain.WHOIS.WhoisServer string The whois server name.
Domain.WHOIS.Phone string The phone number of the tech administrator.
Domain.WHOIS.Admin object Administrator information.
Domain.WHOIS.Admin.Address string The address of the administrator.
Domain.WHOIS.Admin.ApplicationPurpose string The application purpose of the administrator.
Domain.WHOIS.Admin.C string The C field of the administrator.
Domain.WHOIS.Admin.City string The city of the administrator.
Domain.WHOIS.Admin.Country string The country of the administrator.
Domain.WHOIS.Admin.Email string The email address of the administrator.
Domain.WHOIS.Admin.Fax string The fax number of the administrator.
Domain.WHOIS.Admin.FaxExt string The fax extension of the administrator.
Domain.WHOIS.Admin.Id string The ID of the administrator.
Domain.WHOIS.Admin.Name string The name of the administrator.
Domain.WHOIS.Admin.Org string The organization of the administrator.
Domain.WHOIS.Admin.Phone string The phone number of the administrator.
Domain.WHOIS.Admin.PhoneExt string The phone extension of the administrator.
Domain.WHOIS.Admin.PostalCode string The postal code of the administrator.
Domain.WHOIS.Admin.State string The state of the administrator.
Domain.WHOIS.Admin.StateProvince string The state or province of the administrator.
Domain.WHOIS.Admin.Street string The street of the administrator.
Domain.WHOIS.Registrant.Name string The name of the registrant.
Domain.WHOIS.Registrant.Email string The email address of the registrant.
Domain.WHOIS.Registrant.Country string The country of the registrant.
Domain.WHOIS.Registrant.State string The state of the registrant.
Domain.WHOIS.Registrant.Org string The organization of the registrant.
Domain.WHOIS.Registrant.PostalCode string The postal code of the registrant.
Domain.WHOIS.Registrant.Street string The street of the registrant.
Domain.WHOIS.Registrant.Phone string The phone number of the registrant.
Domain.WHOIS.Registrant.City string The city of the registrant.
Domain.WHOIS.Registrant.Address string The address of the registrant.
Domain.WHOIS.Registrant.ContactName string The contact name of the registrant.
Domain.WHOIS.Registrant.Fax string The fax of the registrant.
Domain.WHOIS.Registrant.Id string The ID of the registrant.
Domain.WHOIS.Registrant.Number string The number of the registrant.
Domain.WHOIS.Registrant.StateProvince string The state province of the registrant.
Domain.WHOIS.Raw string The raw output from python-whois lib.
Domain.WHOIS.Administrator string The country of the domain administrator.
Domain.WHOIS.Tech.Name string The name of the tech contact.
Domain.WHOIS.Tech.Address string The address of the tech contact.
Domain.WHOIS.Tech.City string The city of the tech contact.
Domain.WHOIS.Tech.Country string The country of the tech contact.
Domain.WHOIS.Tech.Email string The email address of the tech contact.
Domain.WHOIS.Tech.Fax string The fax number of the tech contact.
Domain.WHOIS.Tech.ID string The ID of the tech contact.
Domain.WHOIS.Tech.Org string The organization of the tech contact.
Domain.WHOIS.Tech.Phone string The phone number of the tech contact.
Domain.WHOIS.Tech.PostalCode string The postal code of the tech contact.
Domain.WHOIS.Tech.State string The state of the tech contact.
Domain.WHOIS.Tech.StateProvince string The state/province of the tech contact.
Domain.WHOIS.Tech.Street string The street of the tech contact.
Domain.WHOIS.ID string The ID of the domain.
Domain.FeedRelatedIndicators.Type String Indicators that are associated with the domain.
Domain.FeedRelatedIndicators.Value String The type of the indicators that are associated with the domain.
Domain.WHOIS.FeedRelatedIndicators.Type String Indicators that are associated with the domain.
Domain.WHOIS.FeedRelatedIndicators.Value String The type of the indicators that are associated with the domain.
Domain.FeedRelatedIndicators.type String (Legacy output) Indicators that are associated with the domain.
Domain.FeedRelatedIndicators.value String (Legacy output) The type of the indicators that are associated with the domain.
Domain.Whois.Name string (Legacy output) The domain name.
Domain.Whois.DomainStatus string (Legacy output) The domain status.
Domain.Whois.DNSSec string (Legacy output) The domain name system security extension (DNSSEC).
Domain.Whois.NameServers string (Legacy output) The name servers.
Domain.Whois.CreationDate date (Legacy output) The date that the domain was created (UTC).
Domain.Whois.UpdatedDate date (Legacy output)The date that the domain was last updated (UTC).
Domain.Whois.ExpirationDate date (Legacy output)The date that the domain expires (UTC).
Domain.Whois.Registrar.Name string (Legacy output)The name of the registrar.
Domain.Whois.Emails string (Legacy output)The abuse emails.
Domain.Whois.Registrar.AbuseEmail string (Legacy output) The email address of the contact for reporting abuse.
Domain.Whois.Registrant.name string (Legacy output) The name of the registrant.
Domain.Whois.Registrant.email string (Legacy output) The email address of the registrant.
Domain.Whois.Raw string (Legacy output) The raw output.
Domain.Whois.Administrator.country string (Legacy output) The country of the domain administrator.
Domain.Whois.Administrator.name string (Legacy output) The name of the domain administrator.
Domain.Whois.Administrator.state string (Legacy output) The state of the domain administrator.
Domain.Whois.Administrator.email string (Legacy output) The email address of the domain administrator.
Domain.Whois.Administrator.organization string (Legacy output) The organization of the domain administrator.
Domain.Whois.Administrator.postalcode string (Legacy output) The postal code of the domain administrator.
Domain.Whois.Administrator.street string (Legacy output) The street of the the domain admin.
Domain.Whois.Administrator.phone string (Legacy output) The phone number of the domain administrator.
Domain.Whois.Administrator.city string (Legacy output) The city of the domain administrator.
Domain.Whois.TechAdmin.country string (Legacy output) The country of the tech administrator.
Domain.Whois.TechAdmin.name string (Legacy output) The name of the tech administrator.
Domain.Whois.TechAdmin.state string (Legacy output) The state of the tech administrator.
Domain.Whois.TechAdmin.email string (Legacy output) The email address of the tech administrator.
Domain.Whois.TechAdmin.organization string (Legacy output) The organization of the tech administrator.
Domain.Whois.TechAdmin.postalcode string (Legacy output) The postal code of the tech administrator.
Domain.Whois.TechAdmin.street string (Legacy output) The street of the tech administrator.
Domain.Whois.TechAdmin.phone string (Legacy output) The phone number of the tech administrator.
Domain.Whois.TechAdmin.city string (Legacy output) The city of the tech administrator.
Domain.Whois.Registrant.country string (Legacy output) The country of the registrant.
Domain.Whois.Registrant.state string (Legacy output) The state of the registrant.
Domain.Whois.Registrant.organization string (Legacy output) The organization of the registrant.
Domain.Whois.Registrant.postalcode string (Legacy output) The postal code of the registrant.
Domain.Whois.Registrant.street string (Legacy output) The street of the registrant.
Domain.Whois.Registrant.phone string (Legacy output) The phone number of the registrant.
Domain.Whois.Registrant.city string (Legacy output) The city of the registrant.
Domain.Whois.ID string (Legacy output) The ID of the domain.
Domain.Whois.QueryStatus string (Legacy output) The result of the command (“Success” or “Failed”).
Domain.Whois.QueryValue string (Legacy output) The query requested by the user.
Domain.Whois.QueryResult Boolean (Legacy output) Whether the query found a matching result.

Command example

!whois query="paloaltonetworks.com"

Context Example

{
    "DBotScore": {
        "Indicator": "google.com",
        "Type": "domain",
        "Vendor": "Whois",
        "Score": 0,
        "Reliability": "B - Usually reliable"
    },
    "Domain": {
        "WHOIS": {
            "Name": "paloaltonetworks.com",
            "WhoisServer": "whois.markmonitor.com",
            "CreationDate": "21-02-2005",
            "ExpirationDate": "21-02-2026",
            "UpdatedDate": "08-02-2024",
            "Organization": "Palo Alto Networks, Inc.",
            "State": "CA",
            "Country": "US",
            "Dnssec": "signedDelegation",
            "Registrar": {
                "Name": "MarkMonitor, Inc."
            },
            "Emails": [
                "abusecomplaints@markmonitor.com",
                "whoisrequest@markmonitor.com"
            ],
            "NameServers": [
                "a1-184.akam.net",
                "a11-64.akam.net",
                "a12-67.akam.net",
                "a13-66.akam.net",
                "a2-65.akam.net",
                "a4-64.akam.net"
            ],
            "DomainStatus": [
                "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited",
                "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",
                "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited",
                "clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)",
                "clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)",
                "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)"
            ],
            "FeedRelatedIndicators": [
                {
                    "Type": "email",
                    "Value": "abusecomplaints@markmonitor.com"
                },
                {
                    "Type": "email",
                    "Value": "whoisrequest@markmonitor.com"
                }
            ],
            "Raw": "domain_name: ['PALOALTONETWORKS.COM', 'paloaltonetworks.com'], registrar: MarkMonitor, Inc., whois_server: whois.markmonitor.com, referral_url: None, updated_date: [datetime.datetime(2024, 2, 8, 6, 27, 19), datetime.datetime(2024, 2, 8, 6, 27, 19, tzinfo=datetime.timezone.utc)], creation_date: [datetime.datetime(2005, 2, 21, 2, 42, 10), datetime.datetime(2005, 2, 21, 2, 42, 10, tzinfo=datetime.timezone.utc)], expiration_date: [datetime.datetime(2026, 2, 21, 2, 42, 10), datetime.datetime(2026, 2, 21, 0, 0, tzinfo=datetime.timezone.utc)], name_servers: ['A1-184.AKAM.NET', 'A11-64.AKAM.NET', 'A12-67.AKAM.NET', 'A13-66.AKAM.NET', 'A2-65.AKAM.NET', 'A4-64.AKAM.NET', 'a1-184.akam.net', 'a4-64.akam.net', 'a2-65.akam.net', 'a13-66.akam.net', 'a12-67.akam.net', 'a11-64.akam.net'], status: ['clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited', 'clientTransferProhibited https://icann.org/epp#clientTransferProhibited', 'clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited', 'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)', 'clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)', 'clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)'], emails: ['abusecomplaints@markmonitor.com', 'whoisrequest@markmonitor.com'], dnssec: signedDelegation, name: None, org: Palo Alto Networks, Inc., address: None, city: None, state: CA, registrant_postal_code: None, country: US"
        },
        "Name": "paloaltonetworks.com",
        "WhoisServer": "whois.markmonitor.com",
        "CreationDate": "21-02-2005",
        "ExpirationDate": "21-02-2026",
        "UpdatedDate": "08-02-2024",
        "Organization": "Palo Alto Networks, Inc.",
        "State": "CA",
        "Country": "US",
        "Dnssec": "signedDelegation",
        "Registrar": {
            "Name": "MarkMonitor, Inc."
        },
        "Emails": [
            "abusecomplaints@markmonitor.com",
            "whoisrequest@markmonitor.com"
        ],
        "NameServers": [
            "a1-184.akam.net",
            "a11-64.akam.net",
            "a12-67.akam.net",
            "a13-66.akam.net",
            "a2-65.akam.net",
            "a4-64.akam.net"
        ],
        "DomainStatus": [
            "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited",
            "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",
            "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited",
            "clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)",
            "clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)",
            "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)"
        ],
        "FeedRelatedIndicators": [
            {
                "Type": "email",
                "Value": "abusecomplaints@markmonitor.com"
            },
            {
                "Type": "email",
                "Value": "whoisrequest@markmonitor.com"
            }
        ],
        "Raw": "domain_name: ['PALOALTONETWORKS.COM', 'paloaltonetworks.com'], registrar: MarkMonitor, Inc., whois_server: whois.markmonitor.com, referral_url: None, updated_date: [datetime.datetime(2024, 2, 8, 6, 27, 19), datetime.datetime(2024, 2, 8, 6, 27, 19, tzinfo=datetime.timezone.utc)], creation_date: [datetime.datetime(2005, 2, 21, 2, 42, 10), datetime.datetime(2005, 2, 21, 2, 42, 10, tzinfo=datetime.timezone.utc)], expiration_date: [datetime.datetime(2026, 2, 21, 2, 42, 10), datetime.datetime(2026, 2, 21, 0, 0, tzinfo=datetime.timezone.utc)], name_servers: ['A1-184.AKAM.NET', 'A11-64.AKAM.NET', 'A12-67.AKAM.NET', 'A13-66.AKAM.NET', 'A2-65.AKAM.NET', 'A4-64.AKAM.NET', 'a1-184.akam.net', 'a4-64.akam.net', 'a2-65.akam.net', 'a13-66.akam.net', 'a12-67.akam.net', 'a11-64.akam.net'], status: ['clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited', 'clientTransferProhibited https://icann.org/epp#clientTransferProhibited', 'clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited', 'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)', 'clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)', 'clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)'], emails: ['abusecomplaints@markmonitor.com', 'whoisrequest@markmonitor.com'], dnssec: signedDelegation, name: None, org: Palo Alto Networks, Inc., address: None, city: None, state: CA, registrant_postal_code: None, country: US"
    }
}

Human Readable Output

Whois results for paloaltonetworks.com

Name CreationDate ExpirationDate UpdatedDate NameServers Organization Registrar DomainStatus Emails WhoisServer
paloaltonetworks.com 21-02-2005 21-02-2026 08-02-2024 a1-184.akam.net,
a11-64.akam.net,
a12-67.akam.net,
a13-66.akam.net,
a2-65.akam.net,
a4-64.akam.net
Palo Alto Networks, Inc. Name: MarkMonitor, Inc. clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited,
clientTransferProhibited https://icann.org/epp#clientTransferProhibited,
clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited,
clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited),
clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited),
clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)
abusecomplaints@markmonitor.com,
whoisrequest@markmonitor.com
whois.markmonitor.com

domain


Provides data enrichment for domains.

Base Command

domain

Input

Argument Name Description Required
domain The domain to enrich. Required
recursive Whether to get the raw response from the whois servers recursively. Default value is True. Optional

Context Output

Path Type Description
DBotScore.Score string The actual score.
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.Reliability String Reliability of the source providing the intelligence data.
Domain.Name string The domain name.
Domain.DomainStatus String The domain status.
Domain.ExpirationDate Date The date that the domain expires (UTC).
Domain.NameServers String The name servers.
Domain.Organization String The organization name.
Domain.ID string The ID of the domain.
Domain.UpdatedDate Date The date that the domain was last updated (UTC).
Domain.Dnssec string The domain name system security extension (DNSSEC).
Domain.Country string The domain country.
Domain.State string The domain state.
Domain.City string The domain city.
Domain.CreationDate date The date that the domain was created (UTC).
Domain.Registrar.Name string The name of the registrar.
Domain.Registrar.Address string The address of the registrar.
Domain.Registrar.Email string The email of the registrar.
Domain.Registrar.Id string The ID of the registrar.
Domain.Registrar.Phone string The phone number of the registrar.
Domain.Registrar.Url string The URL of the registrar.
Domain.Registrar.AbuseEmail string The email address of the contact for reporting abuse.
Domain.Emails string The abuse emails.
Domain.Address string The abuse address.
Domain.WhoisServer string The whois server name.
Domain.Phone string The phone number of the tech administrator.
Domain.Admin object Administrator information.
Domain.Admin.Address string The address of the administrator.
Domain.Admin.ApplicationPurpose string The application purpose of the administrator.
Domain.Admin.C string The C field of the administrator.
Domain.Admin.City string The city of the administrator.
Domain.Admin.Country string The country of the administrator.
Domain.Admin.Email string The email address of the administrator.
Domain.Admin.Fax string The fax number of the administrator.
Domain.Admin.FaxExt string The fax extension of the administrator.
Domain.Admin.Id string The ID of the administrator.
Domain.Admin.Name string The name of the administrator.
Domain.Admin.Org string The organization of the administrator.
Domain.Admin.Phone string The phone number of the administrator.
Domain.Admin.PhoneExt string The phone extension of the administrator.
Domain.Admin.PostalCode string The postal code of the administrator.
Domain.Admin.State string The state of the administrator.
Domain.Admin.StateProvince string The state or province of the administrator.
Domain.Admin.Street string The street of the administrator.
Domain.Registrant.Name string The name of the registrant.
Domain.Registrant.Email string The email address of the registrant.
Domain.Registrant.Country string The country of the registrant.
Domain.Registrant.State string The state of the registrant.
Domain.Registrant.Org string The organization of the registrant.
Domain.Registrant.PostalCode string The postal code of the registrant.
Domain.Registrant.Street string The street of the registrant.
Domain.Registrant.Phone string The phone number of the registrant.
Domain.Registrant.City string The city of the registrant.
Domain.Registrant.Address string The address of the registrant.
Domain.Registrant.ContactName string The contact name of the registrant.
Domain.Registrant.Fax string The fax of the registrant.
Domain.Registrant.Id string The ID of the registrant.
Domain.Registrant.Number string The number of the registrant.
Domain.Registrant.StateProvince string The state province of the registrant.
Domain.Raw string The raw output from python-whois lib.
Domain.Administrator string The country of the domain administrator.
Domain.Tech.Name string The name of the tech contact.
Domain.Tech.Address string The address of the tech contact.
Domain.Tech.City string The city of the tech contact.
Domain.Tech.Country string The country of the tech contact.
Domain.Tech.Email string The email address of the tech contact.
Domain.Tech.Fax string The fax number of the tech contact.
Domain.Tech.ID string The ID of the tech contact.
Domain.Tech.Org string The organization of the tech contact.
Domain.Tech.Phone string The phone number of the tech contact.
Domain.Tech.PostalCode string The postal code of the tech contact.
Domain.Tech.State string The state of the tech contact.
Domain.Tech.StateProvince string The state/province of the tech contact.
Domain.Tech.Street string The street of the tech contact.
Domain.FeedRelatedIndicators.Type String Indicators that are associated with the domain.
Domain.FeedRelatedIndicators.Value String The type of the indicators that are associated with the domain.
Domain.WHOIS.FeedRelatedIndicators.Type String Indicators that are associated with the domain.
Domain.WHOIS.FeedRelatedIndicators.Value String The type of the indicators that are associated with the domain.
Domain.WHOIS.Name string The domain name.
Domain.WHOIS.ID string The ID of the domain.
Domain.WHOIS.DomainStatus string The domain status.
Domain.WHOIS.Dnssec string The domain name system security extension (DNSSEC).
Domain.WHOIS.NameServers string The name servers.
Domain.WHOIS.Country string The domain country.
Domain.WHOIS.State string The domain state.
Domain.WHOIS.City string The domain city.
Domain.WHOIS.CreationDate date The date that the domain was created (UTC).
Domain.WHOIS.UpdatedDate date The date that the domain was last updated (UTC).
Domain.WHOIS.ExpirationDate date The date that the domain expires (UTC).
Domain.WHOIS.Registrar.Name string The name of the registrar.
Domain.WHOIS.Registrar.Address string The address of the registrar.
Domain.WHOIS.Registrar.Email string The email of the registrar.
Domain.WHOIS.Registrar.Id string The ID of the registrar.
Domain.WHOIS.Registrar.Phone string The phone number of the registrar.
Domain.WHOIS.Registrar.Url string The URL of the registrar.
Domain.WHOIS.Registrar.AbuseEmail string The email address of the contact for reporting abuse.
Domain.WHOIS.Emails string The abuse emails.
Domain.WHOIS.Address string The abuse address.
Domain.WHOIS.Organization string The organization domain name.
Domain.WHOIS.WhoisServer string The whois server name.
Domain.WHOIS.Phone string The phone number of the tech administrator.
Domain.WHOIS.Admin object Administrator information.
Domain.WHOIS.Admin.Address string The address of the administrator.
Domain.WHOIS.Admin.ApplicationPurpose string The application purpose of the administrator.
Domain.WHOIS.Admin.C string The C field of the administrator.
Domain.WHOIS.Admin.City string The city of the administrator.
Domain.WHOIS.Admin.Country string The country of the administrator.
Domain.WHOIS.Admin.Email string The email address of the administrator.
Domain.WHOIS.Admin.Fax string The fax number of the administrator.
Domain.WHOIS.Admin.FaxExt string The fax extension of the administrator.
Domain.WHOIS.Admin.Id string The ID of the administrator.
Domain.WHOIS.Admin.Name string The name of the administrator.
Domain.WHOIS.Admin.Org string The organization of the administrator.
Domain.WHOIS.Admin.Phone string The phone number of the administrator.
Domain.WHOIS.Admin.PhoneExt string The phone extension of the administrator.
Domain.WHOIS.Admin.PostalCode string The postal code of the administrator.
Domain.WHOIS.Admin.State string The state of the administrator.
Domain.WHOIS.Admin.StateProvince string The state or province of the administrator.
Domain.WHOIS.Admin.Street string The street of the administrator.
Domain.WHOIS.Registrant.Name string The name of the registrant.
Domain.WHOIS.Registrant.Email string The email address of the registrant.
Domain.WHOIS.Registrant.Country string The country of the registrant.
Domain.WHOIS.Registrant.State string The state of the registrant.
Domain.WHOIS.Registrant.Org string The organization of the registrant.
Domain.WHOIS.Registrant.PostalCode string The postal code of the registrant.
Domain.WHOIS.Registrant.Street string The street of the registrant.
Domain.WHOIS.Registrant.Phone string The phone number of the registrant.
Domain.WHOIS.Registrant.City string The city of the registrant.
Domain.WHOIS.Registrant.Address string The address of the registrant.
Domain.WHOIS.Registrant.ContactName string The contact name of the registrant.
Domain.WHOIS.Registrant.Fax string The fax of the registrant.
Domain.WHOIS.Registrant.Id string The ID of the registrant.
Domain.WHOIS.Registrant.Number string The number of the registrant.
Domain.WHOIS.Registrant.StateProvince string The state province of the registrant.
Domain.WHOIS.Raw string The raw output from python-whois lib.
Domain.WHOIS.Administrator string The country of the domain administrator.
Domain.WHOIS.Tech.Name string The name of the tech contact.
Domain.WHOIS.Tech.Address string The address of the tech contact.
Domain.WHOIS.Tech.City string The city of the tech contact.
Domain.WHOIS.Tech.Country string The country of the tech contact.
Domain.WHOIS.Tech.Email string The email address of the tech contact.
Domain.WHOIS.Tech.Fax string The fax number of the tech contact.
Domain.WHOIS.Tech.ID string The ID of the tech contact.
Domain.WHOIS.Tech.Org string The organization of the tech contact.
Domain.WHOIS.Tech.Phone string The phone number of the tech contact.
Domain.WHOIS.Tech.PostalCode string The postal code of the tech contact.
Domain.WHOIS.Tech.State string The state of the tech contact.
Domain.WHOIS.Tech.StateProvince string The state/province of the tech contact.
Domain.WHOIS.Tech.Street string The street of the tech contact.
Domain.Whois.Name string (Legacy output) The domain name.
Domain.Whois.DomainStatus string (Legacy output) The domain status.
Domain.Whois.DNSSec string (Legacy output) The domain name system security extension (DNSSEC).
Domain.Whois.NameServers string (Legacy output) The name servers.
Domain.Whois.CreationDate date (Legacy output) The date that the domain was created (UTC).
Domain.Whois.UpdatedDate date (Legacy output) The date that the domain was last updated (UTC).
Domain.Whois.ExpirationDate date (Legacy output) The date that the domain expires (UTC).
Domain.Whois.Registrar.Name string (Legacy output) The name of the registrar.
Domain.Whois.Emails string (Legacy output) The abuse emails.
Domain.Whois.Registrar.AbuseEmail string (Legacy output) The email address of the contact for reporting abuse.
Domain.Whois.Registrant.name string (Legacy output) The name of the registrant.
Domain.Whois.Registrant.email string (Legacy output) The email address of the registrant.
Domain.Whois.Raw string (Legacy output) The raw output.
Domain.Whois.Administrator.country string (Legacy output) The country of the domain administrator.
Domain.Whois.Administrator.name string (Legacy output) The name of the domain administrator.
Domain.Whois.Administrator.state string (Legacy output) The state of the domain administrator.
Domain.Whois.Administrator.email string (Legacy output) The email address of the domain administrator.
Domain.Whois.Administrator.organization string (Legacy output) The organization of the domain administrator.
Domain.Whois.Administrator.postalcode string (Legacy output) The postal code of the domain administrator.
Domain.Whois.Administrator.street string (Legacy output) The street of the domain administrator.
Domain.Whois.Administrator.phone string (Legacy output) The phone number of the domain administrator.
Domain.Whois.Administrator.city string (Legacy output) The city of the domain administrator.
Domain.Whois.TechAdmin.country string (Legacy output) The country of the tech administrator.
Domain.Whois.TechAdmin.name string (Legacy output) The name of the tech administrator.
Domain.Whois.TechAdmin.state string (Legacy output) The state of the tech administrator.
Domain.Whois.TechAdmin.email string (Legacy output) The email address of the tech administrator.
Domain.Whois.TechAdmin.organization string (Legacy output) The organization of the tech administrator.
Domain.Whois.TechAdmin.postalcode string (Legacy output) The postal code of the tech administrator.
Domain.Whois.TechAdmin.street string (Legacy output) The street of the tech administrator.
Domain.Whois.TechAdmin.phone string (Legacy output) The phone number of the tech administrator.
Domain.Whois.TechAdmin.city string (Legacy output) The city of the tech administrator.
Domain.Whois.Registrant.country string (Legacy output) The country of the registrant.
Domain.Whois.Registrant.state string (Legacy output) The state of the registrant.
Domain.Whois.Registrant.organization string (Legacy output) The organization of the registrant.
Domain.Whois.Registrant.postalcode string (Legacy output) The postal code of the registrant.
Domain.Whois.Registrant.street string (Legacy output) The street of the registrant.
Domain.Whois.Registrant.phone string (Legacy output) The phone number of the registrant.
Domain.Whois.Registrant.city string (Legacy output) The city of the registrant.
Domain.Whois.ID string (Legacy output) The ID of the domain.
Domain.Whois.QueryStatus string (Legacy output) The result of the command (“Success” or “Failed”).
Domain.Whois.QueryResult Boolean (Legacy output) Whether the query found a matching result.
Domain.Admin.Country String (Legacy output) The country of the domain administrator.
Domain.Admin.Name String (Legacy output) The name of domain administrator.
Domain.Admin.State String (Legacy output) The state of domain administrator.
Domain.Admin.country String (Legacy output) The country of the domain administrator.
Domain.Admin.name String (Legacy output) The name of domain administrator.
Domain.Admin.state String (Legacy output) The state of domain administrator.
Domain.Registrant.country String (Legacy output) The country of the registrant.
Domain.Registrant.organization String (Legacy output) The organization of the registrant.
Domain.Registrant.state String (Legacy output) The state of the registrant.
Domain.FeedRelatedIndicators.type String (Legacy output) Indicators that are associated with the domain.
Domain.FeedRelatedIndicators.value String (Legacy output) The type of the indicators that are associated with the domain.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.

Command example

!domain domain="google.com"

Context Example

{
    "DBotScore": {
        "Indicator": "google.com",
        "Type": "domain",
        "Vendor": "Whois",
        "Score": 0,
        "Reliability": "B - Usually reliable"
    },
    "Domain": {
        "WHOIS": {
            "Name": "google.com",
            "WhoisServer": "whois.markmonitor.com",
            "CreationDate": "15-09-1997",
            "ExpirationDate": "14-09-2028",
            "UpdatedDate": "09-09-2019",
            "Organization": "Google LLC",
            "State": "CA",
            "Country": "US",
            "Dnssec": "unsigned",
            "Registrar": {
                "Name": "MarkMonitor, Inc."
            },
            "Emails": [
                "abusecomplaints@markmonitor.com",
                "whoisrequest@markmonitor.com"
            ],
            "NameServers": [
                "ns1.google.com",
                "ns2.google.com",
                "ns3.google.com",
                "ns4.google.com"
            ],
            "DomainStatus": [
                "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited",
                "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",
                "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited",
                "serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited",
                "serverTransferProhibited https://icann.org/epp#serverTransferProhibited",
                "serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited",
                "clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)",
                "clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)",
                "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)",
                "serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)",
                "serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)",
                "serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)"
            ],
            "FeedRelatedIndicators": [
                {
                    "Type": "email",
                    "Value": "abusecomplaints@markmonitor.com"
                },
                {
                    "Type": "email",
                    "Value": "whoisrequest@markmonitor.com"
                }
            ],
            "Raw": "domain_name: ['GOOGLE.COM', 'google.com'], registrar: MarkMonitor, Inc., whois_server: whois.markmonitor.com, referral_url: None, updated_date: [datetime.datetime(2019, 9, 9, 15, 39, 4), datetime.datetime(2019, 9, 9, 15, 39, 4, tzinfo=datetime.timezone.utc)], creation_date: [datetime.datetime(1997, 9, 15, 4, 0), datetime.datetime(1997, 9, 15, 7, 0, tzinfo=datetime.timezone.utc)], expiration_date: [datetime.datetime(2028, 9, 14, 4, 0), datetime.datetime(2028, 9, 13, 7, 0, tzinfo=datetime.timezone.utc)], name_servers: ['NS1.GOOGLE.COM', 'NS2.GOOGLE.COM', 'NS3.GOOGLE.COM', 'NS4.GOOGLE.COM', 'ns4.google.com', 'ns3.google.com', 'ns1.google.com', 'ns2.google.com'], status: ['clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited', 'clientTransferProhibited https://icann.org/epp#clientTransferProhibited', 'clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited', 'serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited', 'serverTransferProhibited https://icann.org/epp#serverTransferProhibited', 'serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited', 'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)', 'clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)', 'clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)', 'serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)', 'serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)', 'serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)'], emails: ['abusecomplaints@markmonitor.com', 'whoisrequest@markmonitor.com'], dnssec: unsigned, name: None, org: Google LLC, address: None, city: None, state: CA, registrant_postal_code: None, country: US"
        },
        "Name": "google.com",
        "WhoisServer": "whois.markmonitor.com",
        "CreationDate": "15-09-1997",
        "ExpirationDate": "14-09-2028",
        "UpdatedDate": "09-09-2019",
        "Organization": "Google LLC",
        "State": "CA",
        "Country": "US",
        "Dnssec": "unsigned",
        "Registrar": {
            "Name": "MarkMonitor, Inc."
        },
        "Emails": [
            "abusecomplaints@markmonitor.com",
            "whoisrequest@markmonitor.com"
        ],
        "NameServers": [
            "ns1.google.com",
            "ns2.google.com",
            "ns3.google.com",
            "ns4.google.com"
        ],
        "DomainStatus": [
            "clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited",
            "clientTransferProhibited https://icann.org/epp#clientTransferProhibited",
            "clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited",
            "serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited",
            "serverTransferProhibited https://icann.org/epp#serverTransferProhibited",
            "serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited",
            "clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)",
            "clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)",
            "clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)",
            "serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)",
            "serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)",
            "serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)"
        ],
        "FeedRelatedIndicators": [
            {
                "Type": "email",
                "Value": "abusecomplaints@markmonitor.com"
            },
            {
                "Type": "email",
                "Value": "whoisrequest@markmonitor.com"
            }
        ],
        "Raw": "domain_name: ['GOOGLE.COM', 'google.com'], registrar: MarkMonitor, Inc., whois_server: whois.markmonitor.com, referral_url: None, updated_date: [datetime.datetime(2019, 9, 9, 15, 39, 4), datetime.datetime(2019, 9, 9, 15, 39, 4, tzinfo=datetime.timezone.utc)], creation_date: [datetime.datetime(1997, 9, 15, 4, 0), datetime.datetime(1997, 9, 15, 7, 0, tzinfo=datetime.timezone.utc)], expiration_date: [datetime.datetime(2028, 9, 14, 4, 0), datetime.datetime(2028, 9, 13, 7, 0, tzinfo=datetime.timezone.utc)], name_servers: ['NS1.GOOGLE.COM', 'NS2.GOOGLE.COM', 'NS3.GOOGLE.COM', 'NS4.GOOGLE.COM', 'ns4.google.com', 'ns3.google.com', 'ns1.google.com', 'ns2.google.com'], status: ['clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited', 'clientTransferProhibited https://icann.org/epp#clientTransferProhibited', 'clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited', 'serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited', 'serverTransferProhibited https://icann.org/epp#serverTransferProhibited', 'serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited', 'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)', 'clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)', 'clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)', 'serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)', 'serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)', 'serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)'], emails: ['abusecomplaints@markmonitor.com', 'whoisrequest@markmonitor.com'], dnssec: unsigned, name: None, org: Google LLC, address: None, city: None, state: CA, registrant_postal_code: None, country: US"
    }
}

Human Readable Output

Whois results for google.com

Name CreationDate ExpirationDate UpdatedDate NameServers Organization Registrar DomainStatus Emails WhoisServer
google.com 15-09-1997 14-09-2028 09-09-2019 ns1.google.com,
ns2.google.com,
ns3.google.com,
ns4.google.com
Google LLC Name: MarkMonitor, Inc. clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited,
clientTransferProhibited https://icann.org/epp#clientTransferProhibited,
clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited,
serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited,
serverTransferProhibited https://icann.org/epp#serverTransferProhibited,
serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited,
clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited),
clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited),
clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited),
serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited),
serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited),
serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)
abusecomplaints@markmonitor.com,
whoisrequest@markmonitor.com
whois.markmonitor.com

ip


Provides data enrichment for ips.

Base Command

ip

Input

Argument Name Description Required
ip The IP to enrich. Required

Context Output

Path Type Description
Whois.IP.asn string Globally unique identifier used for routing information exchange with Autonomous Systems.
Whois.IP.asn_cidr string Network routing block assigned to an ASN.
Whois.IP.asn_country_code string ASN assigned country code in ISO 3166-1 format.
Whois.IP.asn_date Date ASN allocation date in ISO 8601 format.
Whois.IP.asn_description string The ASN description
Whois.IP.asn_registry string ASN assigned regional internet registry.
Whois.IP.entities string list of object names referenced by an RIR network. Map these to the objects dictionary keys.
Whois.IP.network.cidr string Network routing block an IP address belongs to.
Whois.IP.network.country string Country code registered with the RIR in ISO 3166-1 format.
Whois.IP.network.end_address string The last IP address in a network block.
Whois.IP.network.events.action string The reason for an event.
Whois.IP.network.events.actor string The identifier for an event initiator (if any).
Whois.IP.network.events.timestamp Date The date an event occurred in ISO 8601 format.
Whois.IP.network.handle string Unique identifier for a registered object.
Whois.IP.network.ip_version string IP protocol version (v4 or v6) of an IP address.
Whois.IP.network.links string HTTP/HTTPS links provided for an RIR object.
Whois.IP.network.name string The identifier assigned to the network registration for an IP address.
Whois.IP.network.notices.description string The description/body of a notice.
Whois.IP.network.notices.links string list of HTTP/HTTPS links provided for a notice.
Whois.IP.network.notices.title string The title/header for a notice.
Whois.IP.network.parent_handle string Unique identifier for the parent network of a registered network.
Whois.IP.network.remarks string List of remark (notice) dictionaries.
Whois.IP.network.start_address string The first IP address in a network block.
Whois.IP.network.status string List indicating the state of a registered object.
Whois.IP.network.type string The RIR classification of a registered network.
Whois.IP.query string The IP address
IP.Address string IP address
IP.ASN string The autonomous system name for the IP address, for example: “AS8948”.
IP.Geo.Country string The country in which the IP address is located.
IP.Organization.Name string The organization name.
IP.feed_related_indicators.value string Indicators that are associated with the IP.
IP.feed_related_indicators.type string The type of the indicators that are associated with the IP
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.

Command example

!ip ip=8.8.8.8

Context Example

{
    "DBotScore": {
        "Indicator": "8.8.8.8",
        "Reliability": "B - Usually reliable",
        "Score": 0,
        "Type": "ip",
        "Vendor": "Whois"
    },
    "IP": {
        "ASN": "15169",
        "Address": "8.8.8.8",
        "FeedRelatedIndicators": [
            {
                "description": null,
                "type": "CIDR",
                "value": "8.8.8.0/24"
            }
        ],
        "Organization": {
            "Name": "LVLT-GOGL-8-8-8"
        }
    },
    "Whois": {
        "IP": {
            "asn": "15169",
            "asn_cidr": "8.8.8.0/24",
            "asn_country_code": "US",
            "asn_date": "1992-12-01",
            "asn_description": "GOOGLE, US",
            "asn_registry": "arin",
            "entities": [
                "GOGL"
            ],
            "network": {
                "cidr": "8.8.8.0/24",
                "country": null,
                "end_address": "8.8.8.255",
                "events": [
                    {
                        "action": "last changed",
                        "actor": null,
                        "timestamp": "2014-03-14T16:52:05-04:00"
                    },
                    {
                        "action": "registration",
                        "actor": null,
                        "timestamp": "2014-03-14T16:52:05-04:00"
                    }
                ],
                "handle": "NET-8-8-8-0-1",
                "ip_version": "v4",
                "links": [
                    "https://rdap.arin.net/registry/ip/8.8.8.0",
                    "https://whois.arin.net/rest/net/NET-8-8-8-0-1",
                    "https://rdap.arin.net/registry/ip/8.0.0.0/9"
                ],
                "name": "LVLT-GOGL-8-8-8",
                "notices": [
                    {
                        "description": "By using the ARIN RDAP/Whois service, you are agreeing to the RDAP/Whois Terms of Use",
                        "links": [
                            "https://www.arin.net/resources/registry/whois/tou/"
                        ],
                        "title": "Terms of Service"
                    },
                    {
                        "description": "If you see inaccuracies in the results, please visit: ",
                        "links": [
                            "https://www.arin.net/resources/registry/whois/inaccuracy_reporting/"
                        ],
                        "title": "Whois Inaccuracy Reporting"
                    },
                    {
                        "description": "Copyright 1997-2022, American Registry for Internet Numbers, Ltd.",
                        "links": null,
                        "title": "Copyright Notice"
                    }
                ],
                "parent_handle": "NET-8-0-0-0-1",
                "raw": null,
                "remarks": null,
                "start_address": "8.8.8.0",
                "status": [
                    "active"
                ],
                "type": "ALLOCATION"
            },
            "nir": null,
            "objects": {
                "ABUSE5250-ARIN": {
                    "contact": {
                        "address": [
                            {
                                "type": null,
                                "value": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUnited States"
                            }
                        ],
                        "email": [
                            {
                                "type": null,
                                "value": "network-abuse@google.com"
                            }
                        ],
                        "kind": "group",
                        "name": "Abuse",
                        "phone": [
                            {
                                "type": [
                                    "work",
                                    "voice"
                                ],
                                "value": "+1-650-253-0000"
                            }
                        ],
                        "role": null,
                        "title": null
                    },
                    "entities": null,
                    "events": [
                        {
                            "action": "last changed",
                            "actor": null,
                            "timestamp": "2018-10-24T11:23:55-04:00"
                        },
                        {
                            "action": "registration",
                            "actor": null,
                            "timestamp": "2015-11-06T15:36:35-05:00"
                        }
                    ],
                    "events_actor": null,
                    "handle": "ABUSE5250-ARIN",
                    "links": [
                        "https://rdap.arin.net/registry/entity/ABUSE5250-ARIN",
                        "https://whois.arin.net/rest/poc/ABUSE5250-ARIN"
                    ],
                    "notices": [
                        {
                            "description": "By using the ARIN RDAP/Whois service, you are agreeing to the RDAP/Whois Terms of Use",
                            "links": [
                                "https://www.arin.net/resources/registry/whois/tou/"
                            ],
                            "title": "Terms of Service"
                        },
                        {
                            "description": "If you see inaccuracies in the results, please visit: ",
                            "links": [
                                "https://www.arin.net/resources/registry/whois/inaccuracy_reporting/"
                            ],
                            "title": "Whois Inaccuracy Reporting"
                        },
                        {
                            "description": "Copyright 1997-2022, American Registry for Internet Numbers, Ltd.",
                            "links": null,
                            "title": "Copyright Notice"
                        }
                    ],
                    "raw": null,
                    "remarks": [
                        {
                            "description": "Please note that the recommended way to file abuse complaints are located in the following links.\n\nTo report abuse and illegal activity: https://www.google.com/contact/\n\nFor legal requests: http://support.google.com/legal \n\nRegards,\nThe Google Team",
                            "links": null,
                            "title": "Registration Comments"
                        },
                        {
                            "description": "ARIN has attempted to validate the data for this POC, but has received no response from the POC since 2019-10-24",
                            "links": null,
                            "title": "Unvalidated POC"
                        }
                    ],
                    "roles": [
                        "abuse"
                    ],
                    "status": null
                },
                "GOGL": {
                    "contact": {
                        "address": [
                            {
                                "type": null,
                                "value": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUnited States"
                            }
                        ],
                        "email": null,
                        "kind": "org",
                        "name": "Google LLC",
                        "phone": null,
                        "role": null,
                        "title": null
                    },
                    "entities": [
                        "ABUSE5250-ARIN",
                        "ZG39-ARIN"
                    ],
                    "events": [
                        {
                            "action": "last changed",
                            "actor": null,
                            "timestamp": "2019-10-31T15:45:45-04:00"
                        },
                        {
                            "action": "registration",
                            "actor": null,
                            "timestamp": "2000-03-30T00:00:00-05:00"
                        }
                    ],
                    "events_actor": null,
                    "handle": "GOGL",
                    "links": [
                        "https://rdap.arin.net/registry/entity/GOGL",
                        "https://whois.arin.net/rest/org/GOGL"
                    ],
                    "notices": null,
                    "raw": null,
                    "remarks": [
                        {
                            "description": "Please note that the recommended way to file abuse complaints are located in the following links. \n\nTo report abuse and illegal activity: https://www.google.com/contact/\n\nFor legal requests: http://support.google.com/legal \n\nRegards, \nThe Google Team",
                            "links": null,
                            "title": "Registration Comments"
                        }
                    ],
                    "roles": [
                        "registrant"
                    ],
                    "status": null
                },
                "ZG39-ARIN": {
                    "contact": {
                        "address": [
                            {
                                "type": null,
                                "value": "1600 Amphitheatre Parkway\nMountain View\nCA\n94043\nUnited States"
                            }
                        ],
                        "email": [
                            {
                                "type": null,
                                "value": "arin-contact@google.com"
                            }
                        ],
                        "kind": "group",
                        "name": "Google LLC",
                        "phone": [
                            {
                                "type": [
                                    "work",
                                    "voice"
                                ],
                                "value": "+1-650-253-0000"
                            }
                        ],
                        "role": null,
                        "title": null
                    },
                    "entities": null,
                    "events": [
                        {
                            "action": "last changed",
                            "actor": null,
                            "timestamp": "2021-11-10T10:26:54-05:00"
                        },
                        {
                            "action": "registration",
                            "actor": null,
                            "timestamp": "2000-11-30T13:54:08-05:00"
                        }
                    ],
                    "events_actor": null,
                    "handle": "ZG39-ARIN",
                    "links": [
                        "https://rdap.arin.net/registry/entity/ZG39-ARIN",
                        "https://whois.arin.net/rest/poc/ZG39-ARIN"
                    ],
                    "notices": [
                        {
                            "description": "By using the ARIN RDAP/Whois service, you are agreeing to the RDAP/Whois Terms of Use",
                            "links": [
                                "https://www.arin.net/resources/registry/whois/tou/"
                            ],
                            "title": "Terms of Service"
                        },
                        {
                            "description": "If you see inaccuracies in the results, please visit: ",
                            "links": [
                                "https://www.arin.net/resources/registry/whois/inaccuracy_reporting/"
                            ],
                            "title": "Whois Inaccuracy Reporting"
                        },
                        {
                            "description": "Copyright 1997-2022, American Registry for Internet Numbers, Ltd.",
                            "links": null,
                            "title": "Copyright Notice"
                        }
                    ],
                    "raw": null,
                    "remarks": null,
                    "roles": [
                        "technical",
                        "administrative"
                    ],
                    "status": [
                        "validated"
                    ]
                }
            },
            "query": "8.8.8.8",
            "raw": null
        }
    }
}

Human Readable Output

Whois results

asn asn_cidr asn_date country_code network_name query
15169 8.8.8.0/24 1992-12-01   LVLT-GOGL-8-8-8 8.8.8.8

Troubleshooting

  • Bad Gateway (502) error when using a firewall or proxy.
    • This occurs when the WHOIS Top-Level Domain (TLD) provider is not reachable through the configured firewall or proxy.
    • Resolution: Add the relevant WHOIS TLD provider to your firewall or proxy allowlist.
  • Connection timeout errors when running in a FedRAMP High environment.
    • The Whois integration connects to external WHOIS servers over TCP port 43. On FedRAMP High tenants, outbound traffic from engines is only permitted on port 443, so port 43 connections are blocked and the integration times out. For more information, refer to the documentation on outbound engine IPs for Cortex XSOAR SaaS and Cortex XSIAM.
    • Resolution: Configure a SOCKS5 proxy in the Proxy URL field (for example, socks5h://your-proxy-host:1080) that is reachable on port 443 and can forward traffic to external WHOIS servers on port 43. Note that this proxy setting affects all commands except the ip command. A standard HTTP proxy is not sufficient, as most HTTP proxies do not support the CONNECT method on non-standard ports such as port 43.
  • Rate-limiting or IP blocking errors when querying WHOIS servers.
    • This can occur when multiple users or systems make requests from the same IP address, causing the WHOIS server to block or throttle queries.
    • Resolution: Use a dedicated engine or a SOCKS5 proxy for WHOIS queries to provide a unique outbound IP address and avoid shared-IP blocking.

Known limitations

  • The IP lookup has a rate limit of 1 lookup per second.

Configuration parameters

  • with_error — Return Errors
  • proxy_url — Proxy URL
  • proxy — Use system proxy settings
  • old-version — Use legacy context
  • integrationReliability — Source Reliability (required)
  • rate_limit_retry_count — Rate Limit Retry Count
  • rate_limit_wait_seconds — Rate Limit Wait Seconds
  • rate_limit_errors_suppressed — Suppress Rate Limit errors

Commands (3)

  • domain

    Provides data enrichment for domains.

  • ip

    Provides data enrichment for ips.

  • whois

    Provides data enrichment for domains using free resources. Availability of those services may be limited.

import datetime
import json
import pathlib
import pickle
import socket
from typing import Any

import demistomock as demisto
import ipwhois
import pytest
import Whois
from CommonServerPython import DBotScoreReliability, EntryType, ErrorTypes, ExecutionMetrics
from pytest_mock import MockerFixture
from Whois import (
    WhoisInvalidDomain,
    domain_command,
    get_domain_from_query,
    get_root_server,
    increment_metric,
    ip_command,
    ipwhois_exception_mapping,
    whois_command,
    whois_exception_mapping,
    WhoisException,
)

INTEGRATION_NAME = "Whois"


@pytest.fixture(autouse=True)
def handle_calling_context(mocker: MockerFixture):
    mocker.patch.object(demisto, "callingContext", {"context": {"IntegrationBrand": INTEGRATION_NAME}})


def load_test_data(json_path):
    with open(json_path) as f:
        return json.load(f)


def assert_results_ok():
    assert demisto.results.call_count == 1  # type: ignore
    # call_args is tuple (args list, kwargs). we only need the first one
    results = demisto.results.call_args[0]  # type: ignore
    assert len(results) == 1
    assert results[0] == "ok"


def test_test_command_successful(mocker: MockerFixture):
    """Test that test_command returns 'ok' when nameservers are found."""
    # Mock whois result with expected nameserver
    mock_whois_result = {"nameservers": ["ns1.google.com", "ns2.google.com"], "raw": ["Normal whois response"]}

    mocker.patch("Whois.get_whois", return_value=mock_whois_result)
    mocker.patch.object(demisto, "debug")

    # Import the function after patching to ensure the mock is in place
    from Whois import test_command

    result = test_command()
    assert result == "ok"


def test_test_command_rate_limit_exception(mocker: MockerFixture):
    """Test that test_command raises WhoisException when rate limit pattern is found in whois result."""
    # Mock whois result with rate limit message that matches the RATE_LIMIT_PATTERN
    mock_whois_result = {
        "raw": ["Error for 'google.co.uk'. the WHOIS query quota for 35.225.156.101 has been exceeded"],
        "nameservers": [],
    }

    # Mock get_whois to return our mock result
    mocker.patch("Whois.get_whois", return_value=mock_whois_result)
    mocker.patch.object(demisto, "debug")
    mocker.patch.object(demisto, "results")
    mocker.patch.object(demisto, "command", return_value="test-module")

    # Import the function after patching to ensure the mock is in place
    from Whois import test_command

    # Test that WhoisException is raised (since WhoisRateLimit gets caught and re-raised as WhoisException)
    with pytest.raises(WhoisException) as exc_info:
        test_command()

    # Verify the exception message contains information about the WhoisRateLimit
    exception_message = str(exc_info.value)
    assert "WhoisRateLimit" in exception_message
    assert "Test completed but encountered rate limiting" in exception_message
    assert "Consider using an engine to avoid IP-based rate limits" in exception_message


@pytest.mark.parametrize(
    "query,expected",
    [
        ("app.paloaltonetwork.com", "paloaltonetwork.com"),
        ("test.this.google.co.il", "google.co.il"),
        ("app.XSOAR.test", "app.XSOAR.test"),
        ("https://hello.world.io/", "world.io"),
        ("https://hello.world.io?", "world.io"),
        ("https://hello.world.io#", "world.io"),
        ("https://hello.world.io/a?b=c&d", "world.io"),
        ("https://hello.world.io#a?b=c&d", "world.io"),
        ("https://hello.world.io?a=b&c=d", "world.io"),
    ],
)
def test_get_domain_from_query(query, expected):
    assert get_domain_from_query(query) == expected


def test_socks_proxy_fail(mocker: MockerFixture, capfd: pytest.CaptureFixture):
    mocker.patch.object(demisto, "params", return_value={"proxy_url": "socks5://localhost:1180"})
    mocker.patch.object(demisto, "command", return_value="test-module")
    mocker.patch.object(demisto, "results")

    with capfd.disabled():
        with pytest.raises(SystemExit) as err:
            Whois.main()
        assert err.type is SystemExit
        assert demisto.results.call_count == 1  # type: ignore
        # call_args is tuple (args list, kwargs). we only need the first one
        results = demisto.results.call_args[0]  # type: ignore
        assert len(results) == 1
        assert "Exception thrown calling command" in results[0]["Contents"]


TEST_QUERY_RESULT_INPUT = [
    (
        {
            "contacts": {"admin": None, "billing": None, "registrant": None, "tech": None},
            "raw": ["NOT FOUND\n>>> Last update of WHOIS database: 2020-05-07T13:55:34Z <<<"],
        },
        "rsqupuo.info",
        DBotScoreReliability.B,
        False,
    ),
    (
        {
            "contacts": {"admin": None, "billing": None, "registrant": None, "tech": None},
            "raw": ['No match for "BLABLA43213422342AS.COM".>>> Last update of whois database: 2020-05-20T08:39:17Z <<<'],
        },
        "BLABLA43213422342AS.COM",
        DBotScoreReliability.B,
        False,
    ),
    (
        {
            "status": ["clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)"],
            "updated_date": [datetime.datetime(2019, 9, 9, 8, 39, 4)],
            "contacts": {
                "admin": {"country": "US", "state": "CA", "name": "Google LLC"},
                "tech": {"organization": "Google LLC", "state": "CA", "country": "US"},
                "registrant": {"organization": "Google LLC", "state": "CA", "country": "US"},
                "billing": None,
            },
            "nameservers": ["ns1.google.com", "ns4.google.com", "ns3.google.com", "ns2.google.com"],
            "expiration_date": [datetime.datetime(2028, 9, 13, 0, 0), datetime.datetime(2028, 9, 13, 0, 0)],
            "emails": ["abusecomplaints@markmonitor.com", "whoisrequest@markmonitor.com"],
            "raw": ["Domain Name: google.com\nRegistry Domain ID: 2138514_DOMAIN_COM-VRSN"],
            "creation_date": [datetime.datetime(1997, 9, 15, 0, 0)],
            "id": ["2138514_DOMAIN_COM-VRSN"],
        },
        "google.com",
        DBotScoreReliability.B,
        True,
    ),
    (
        {"contacts": {"admin": None, "billing": None, "registrant": None, "tech": None}},
        "rsqupuo.info",
        DBotScoreReliability.B,
        False,
    ),
    (
        {
            "status": ["clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)"],
            "updated_date": [datetime.datetime(2019, 9, 9, 8, 39, 4)],
            "contacts": {
                "admin": {"country": "US", "state": "CA", "name": "Google LLC"},
                "tech": {"organization": "Google LLC", "state": "CA", "country": "US"},
                "registrant": {"organization": "Google LLC", "state": "CA", "country": "US"},
                "billing": None,
            },
            "nameservers": ["ns1.google.com", "ns4.google.com", "ns3.google.com", "ns2.google.com"],
            "expiration_date": [datetime.datetime(2028, 9, 13, 0, 0), datetime.datetime(2028, 9, 13, 0, 0)],
            "emails": ["abusecomplaints@markmonitor.com", "whoisrequest@markmonitor.com"],
            "raw": "Domain Name: google.com\nRegistry Domain ID: 2138514_DOMAIN_COM-VRSN",
            "creation_date": [datetime.datetime(1997, 9, 15, 0, 0)],
            "id": ["2138514_DOMAIN_COM-VRSN"],
        },
        "google.com",
        DBotScoreReliability.B,
        True,
    ),
    (
        {
            "status": ["clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)"],
            "updated_date": [datetime.datetime(2019, 9, 9, 8, 39, 4)],
            "contacts": {
                "admin": {"country": "US", "state": "CA", "name": "Google LLC"},
                "tech": {"organization": "Google LLC", "state": "CA", "country": "US"},
                "registrant": {"organization": "Google LLC", "state": "CA", "country": "US"},
                "billing": None,
            },
            "nameservers": ["ns1.google.com", "ns4.google.com", "ns3.google.com", "ns2.google.com"],
            "expiration_date": [datetime.datetime(2028, 9, 13, 0, 0), datetime.datetime(2028, 9, 13, 0, 0)],
            "emails": ["abusecomplaints@markmonitor.com", "whoisrequest@markmonitor.com"],
            "raw": {"data": "Domain Name: google.com\nRegistry Domain ID: 2138514_DOMAIN_COM-VRSN"},
            "creation_date": [datetime.datetime(1997, 9, 15, 0, 0)],
            "id": ["2138514_DOMAIN_COM-VRSN"],
        },
        "google.com",
        DBotScoreReliability.B,
        True,
    ),
    (
        {
            "contacts": {"admin": None, "billing": None, "registrant": None, "tech": None},
            "raw": {"data": "Domain Name: google.com\nRegistry Domain ID: 2138514_DOMAIN_COM-VRSN"},
        },
        "rsqupuo.info",
        DBotScoreReliability.B,
        True,
    ),
]


@pytest.mark.parametrize("whois_result, domain, reliability, expected", TEST_QUERY_RESULT_INPUT)
def test_query_result(whois_result, domain, reliability, expected):
    from Whois import create_outputs

    md, standard_ec, dbot_score = create_outputs(whois_result, domain, reliability)
    assert standard_ec["Whois"]["QueryResult"] == expected
    assert (
        dbot_score.get(
            "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)"
        ).get("Reliability")
        == "B - Usually reliable"
    )


def test_ip_command(mocker: MockerFixture):
    """
    Given:
        - IP addresses

    When:
        - running the IP command

    Then:
        - Verify the result is as expected
        - Verify support list of IPs
    """
    mocker.patch.object(ExecutionMetrics, "is_supported", return_value=True)
    response = load_test_data("./test_data/ip_output.json")
    mocker.patch.object(Whois, "get_whois_ip", return_value=response)
    mocker.patch.object(demisto, "args", return_value={"ip": "4.4.4.4,8.8.8.8"})
    result = ip_command(reliability=DBotScoreReliability.B, should_error=False)
    assert len(result) == 3
    assert result[0].outputs_prefix == "Whois.IP"
    assert result[0].outputs.get("query") == "4.4.4.4"  # type: ignore
    assert result[0].indicator.to_context() == {  # type: ignore
        "IP(val.Address && val.Address == obj.Address)": {
            "Organization": {"Name": "LVLT-STATIC-4-4-16"},
            "FeedRelatedIndicators": [{"type": "CIDR", "description": None, "value": "4.4.0.0/16"}],
            "ASN": "3356",
            "Address": "4.4.4.4",
        },
        "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": {
            "Reliability": "B - Usually reliable",
            "Vendor": "Whois",
            "Indicator": "4.4.4.4",
            "Score": 0,
            "Type": "ip",
        },
    }


def test_get_whois_ip_proxy_param(mocker: MockerFixture):
    """
    Given:
        - proxy address

    When:
        - running the get_whois_ip function

    Then:
        - Verify the function doesn't fail due to type errors
    """
    from Whois import get_whois_ip

    mocker.patch.object(demisto, "params", return_value={"proxy": True})
    mocker.patch("ipwhois.IPWhois.lookup_rdap", return_value={"raw": None})
    result = get_whois_ip("1.1.1.1")
    assert result


def test_indian_tld():
    """
    Given:
        - indian domain

    When:
        - running the get_root_server function

    Then:
        - Verify the function returns the correct Whois server
    """
    from Whois import get_root_server

    result = get_root_server("google.in")
    assert result == "whois.nixiregistry.in"


def test_ph_tld():
    """
    Given:
        - A domain that its extension (tld) is '.ph'

    When:
        - running the get_root_server function

    Then:
        - Verify the function returns the correct Whois server
    """
    from Whois import get_root_server

    host = get_root_server("test.com.ph")
    assert host == "whois.iana.org"


def test_parse_raw_whois():
    with open("test_data/EU domains.text") as f:
        raw_data = f.read()
    result = Whois.parse_raw_whois([raw_data], [], never_query_handles=False, handle_server="whois.eu")
    assert result["registrar"] == ["IONOS SE"]


def test_parse_raw_whois_empty_nameserver():
    with open("test_data/EU domains_empty_nameservers.text") as f:
        raw_data = f.read()
    result = Whois.parse_raw_whois([raw_data], [], never_query_handles=False, handle_server="whois.eu")
    assert result["nameservers"] == ["ns1060.ui-dns.biz"]


@pytest.mark.parametrize(
    "input, expected_result",
    [
        (["2024-05-09T00:00:00Z"], datetime.datetime(2024, 5, 9, 0, 0, 0)),
        (["0000-00-00T00:00:00Z"], Whois.InvalidDateHandler(year=0, month=0, day=0)),
        (["0000-01-02T11:22:33Z"], datetime.datetime(2000, 1, 2, 11, 22, 33)),
        (["0000-00-02T00:00:00Z"], Whois.InvalidDateHandler(year=0, month=0, day=2)),
    ],
)
def test_parse_dates_invalid_time(input, expected_result):
    assert type(Whois.parse_dates(input)[0]) is type(expected_result)


@pytest.mark.parametrize(
    "input, expected_result",
    [
        (["2024-05-09T00:00:00Z"], datetime.datetime(2024, 5, 9, 0, 0, 0)),
        (["2024-20-09T00:00:00Z"], datetime.datetime(2024, 9, 20, 0, 0, 0)),
    ],
)
def test_swap_month_day_in_parse_dates(input, expected_result):
    assert Whois.parse_dates(input)[0] == expected_result


@pytest.mark.parametrize(
    "updated_date, expected_res",
    [
        ({"updated_date": [Whois.InvalidDateHandler(0, 0, 0)]}, "0-0-0"),
        ({"updated_date": [datetime.datetime(2025, 6, 8, 0, 0, 0)]}, "08-06-2025"),
    ],
)
def test_create_outputs_invalid_time(updated_date, expected_res):
    res = Whois.create_outputs(updated_date, "test_domain", DBotScoreReliability.A)
    assert res[0]["Updated Date"] == expected_res


@pytest.mark.parametrize(
    "args, expected_res",
    [
        ({"query": "cnn.com", "is_recursive": "true", "verbose": "true", "should_error": "false"}, 2),
        ({"query": "cnn.com", "is_recursive": "true", "should_error": "false"}, 2),
    ],
)
def test_whois_with_verbose(args, expected_res, mocker: MockerFixture):
    """
    Given:
        - The args for the whois command with or without the verbose arg.
    When:
        - calling the whois command.
    Then:
        - validate that another context path is added for the raw-response if verbose arg is true.
    """
    mocker.patch.object(ExecutionMetrics, "is_supported", return_value=True)
    mocker.patch.object(demisto, "command", "whois")
    mocker.patch.object(demisto, "args", return_value=args)
    mocker.patch("Whois.get_domain_from_query", return_value="cnn.com")
    with open("test_data/cnn_pickled", "rb") as f:
        get_whois_ret_value = pickle.load(f)  # guardrails-disable-line
    mocker.patch("Whois.get_whois", return_value=get_whois_ret_value)

    result = Whois.whois_command(reliability="B - Usually reliable")
    assert len(result) == expected_res


def test_parse_nic_contact():
    with open("./test_data/whois_response.txt") as f:
        data = [f.read()]

    res = Whois.parse_nic_contact(data)

    expected = [
        {
            "handle": "GIHU100-FRNIC",
            "type": "ORGANIZATION",
            "name": "Google Ireland Holdings Unlimited Company",
            "street1": "Google Ireland Holdings Unlimited Company",
            "street2": "70 Sir John Rogerson's Quay",
            "street3": "2 Dublin",
            "country": "IE",
            "phone": "+353.14361000",
            "fax": None,
            "email": "email@google.com",
            "changedate": "2022-10-15T05:41:14.918179Z",
            "registrar": "MARKMONITOR Inc.",
            "street4": None,
        },
        {
            "handle": "MI3669-FRNIC",
            "type": "ORGANIZATION",
            "name": "MarkMonitor Inc.",
            "street1": "2150 S. Bonito Way, Suite 150",
            "street2": "83642 Meridian",
            "street3": None,
            "street4": None,
            "phone": "+1.2083895740",
            "fax": "+1.2083895771",
            "email": "email@markmonitor.com",
            "changedate": "2023-09-07T07:32:23.899353Z",
            "country": "US",
            "registrar": "MARKMONITOR Inc.",
        },
        {
            "handle": "GIHU101-FRNIC",
            "type": "ORGANIZATION",
            "name": "Google Ireland Holdings Unlimited Company",
            "street1": "70 Sir John Rogerson's Quay",
            "street2": "2 Dublin",
            "street3": None,
            "street4": None,
            "phone": "+353.14361000",
            "fax": None,
            "email": "email@google.com",
            "changedate": None,
            "country": "IE",
            "registrar": "MARKMONITOR Inc.",
        },
    ]

    assert res == expected


def test_get_raw_response_with_non_recursive_data_query(mocker: MockerFixture):
    """
    Given:
        - A domain to query, non-recursive data query and a mock response which simulates a
          Whois server response that includes a name of a refer server.
    When:
        - running the Whois.get_whois_raw(domain, server) function

    Then:
        - Verify that the final response of the get_whois_raw() includes only the response of the first server which was
          queried, without the response of the refer server.
    """
    import socket

    from Whois import get_whois_raw

    def connect_mocker(curr_server):
        """
        This function is a mocker for the function socket.connect()
        """
        return

    mock_response1 = "Domain Name: test.plus\n WHOIS Server: whois.test.com/\n"
    mock_response2 = "Domain Name: test_refer_server\n"

    mocker.patch.object(socket.socket, "connect", side_effect=connect_mocker)
    mocker.patch("Whois.whois_request_get_response", side_effect=[mock_response1, mock_response2])

    domain = "test.plus"
    response = get_whois_raw(domain=domain, is_recursive=False)
    assert response == [mock_response1]


@pytest.mark.parametrize(
    "param_key, param_value, arg_key, arg_value, expected_res",
    [
        ("param_key", "param_value", "arg_key", "arg_value", "param_value"),
        ("param_key", None, "arg_key", "arg_value", "arg_value"),
        ("param_key", "param_value", "arg_key", None, "param_value"),
        ("param_key", None, "arg_key", None, None),
    ],
)
def test_get_param_or_arg(param_key, param_value, arg_key, arg_value, expected_res, mocker: MockerFixture):
    """
    Given:
        - Demisto params and args.
    When:
        - Getting a value.
    Then:
        - validate that param override an arg.
    """
    mocker.patch.object(demisto, "args", return_value={arg_key: arg_value})
    mocker.patch.object(demisto, "params", return_value={param_key: param_value})

    assert expected_res == Whois.get_param_or_arg(param_key, arg_key)


@pytest.mark.parametrize(
    "args,execution_metrics_supported,expected_entries",
    [
        ({"query": "google.com"}, True, 2),
        ({"query": "127.0.0.1"}, True, 2),
        ({"query": "google.com,amazon.com"}, True, 3),
        ({"query": "google.com"}, False, 1),
    ],
)
def test_execution_metrics_appended(
    args: dict[str, str], execution_metrics_supported: bool, expected_entries: int, mocker: MockerFixture, capfd
):
    """
    Test whether the metrics entry is appended to the list of results according to the XSOAR version.
    API Execution Metrics is only supported for 6.8+.

    Given: Arguments passed to the `whois` command.

    When:
        - Case A: 1 valid domain is passed to v > 6.8.0.
        - Case B: 1 invalid domain is passed to v > 6.8.0.
        - Case C: 2 valid domains are passed to v > 6.8.0.
        - Case D: 1 valid domain is passed to v < 6.8.0.

    Then:
        - Case A: 2 entries are expected (1 for query, 1 for execution metrics).
        - Case B: 2 entries are expected (1 for query, 1 for execution metrics).
        - Case C: 3 entries are expected (2 for queries, 1 for execution metrics).
        - Case D: 1 entries are expected (1 for query, no execution metrics since it's not supported).

    """
    mocker.patch.object(demisto, "command", "whois")
    mocker.patch.object(demisto, "args", return_value=args)
    mocker.patch.object(ExecutionMetrics, "is_supported", return_value=execution_metrics_supported)
    mocker.patch.object(Whois, "get_whois_raw", return_value=load_test_data("./test_data/whois_raw_response.json")["result"])
    with capfd.disabled():
        results = whois_command(reliability=DBotScoreReliability.B)
        assert len(results) == expected_entries


@pytest.mark.parametrize(
    "args,entry_type",
    [
        ({"query": "1.1.1.1", "is_recursive": "true", "with_error": True}, EntryType.ERROR),
        ({"query": "1.1.1.1", "is_recursive": "true", "with_error": False}, EntryType.WARNING),
    ],
)
def test_error_entry_type(args: dict[str, str], entry_type: EntryType, mocker: MockerFixture, capfd: pytest.CaptureFixture):
    mocker.patch.object(demisto, "command", "whois")
    mocker.patch.object(demisto, "args", return_value=args)
    mocker.patch.object(Whois, "get_whois_raw", return_value=load_test_data("./test_data/whois_raw_response.json")["result"])
    with capfd.disabled(), pytest.raises(Exception) as exc:
        results = Whois.whois_command(reliability=DBotScoreReliability.B)
        assert results[0].entry_type == entry_type
        assert "caught performing whois lookup with domain" in exc.value


@pytest.mark.parametrize(
    "em,mapping,exception_caught,expected",
    [
        (
            ExecutionMetrics(success=100, general_error=6),
            ipwhois_exception_mapping,
            ipwhois.exceptions.WhoisLookupError,
            (ErrorTypes.GENERAL_ERROR, 7),
        ),
        (
            ExecutionMetrics(service_error=12),
            ipwhois_exception_mapping,
            ipwhois.exceptions.BlacklistError,
            (ErrorTypes.SERVICE_ERROR, 13),
        ),
        (
            ExecutionMetrics(success=100, general_error=6),
            ipwhois_exception_mapping,
            ipwhois.exceptions.NetError,
            (ErrorTypes.CONNECTION_ERROR, 1),
        ),
        (ExecutionMetrics(), ipwhois_exception_mapping, BaseException, (ErrorTypes.GENERAL_ERROR, 1)),
        (ExecutionMetrics(), whois_exception_mapping, BaseException, (ErrorTypes.GENERAL_ERROR, 1)),
        (ExecutionMetrics(success=100, general_error=6), whois_exception_mapping, socket.error, (ErrorTypes.CONNECTION_ERROR, 1)),
        (ExecutionMetrics(), whois_exception_mapping, TypeError, (ErrorTypes.GENERAL_ERROR, 1)),
        (ExecutionMetrics(), whois_exception_mapping, WhoisInvalidDomain, (ErrorTypes.GENERAL_ERROR, 1)),
    ],
)
def test_exception_type_to_metrics(
    em: ExecutionMetrics, mapping: dict[type, str], exception_caught: type, expected: tuple[str, int]
):
    """
    Test whether the caught `ipwhois.exception` type results in the expected API execution metric being incremented.

    Given: The exception type and the expected metric.

    When:
        - Case A:
            - ExecutionMetrics with success and general error set.
            - `ipwhois` exception mapping provided.
            - `WhoisLookupError` exception thrown.
        - Case B:
            - ExecutionMetrics with service error set.
            - `ipwhois` exception mapping provided.
            - `BlacklistError` exception thrown.
        - Case C:
            - ExecutionMetrics with success and general error set.
            - `ipwhois` exception mapping provided.
            - `NetError` exception thrown.
        - Case D:
            - Empty ExecutionMetrics.
            - `ipwhois` exception mapping provided.
            - `BaseException` thrown.
        - Case E:
            - Empty ExecutionMetrics.
            - `whois` exception mapping provided.
            - `BaseException` thrown.
        - Case F:
            - ExecutionMetrics with success and general error set.
            - `whois` exception mapping provided.
            - `socket.error|OSError` thrown.
       - Case G:
            - Empty ExecutionMetrics.
            - `whois` exception mapping provided.
            - `TypeError` thrown.
        - Case H:
            - Empty ExecutionMetrics.
            - `whois` exception mapping provided.
            - `WhoisInvalidDomain` thrown.


    Then:
        - Case A: ErrorTypes.GENERAL_ERROR is incremented and equal to 7.
        - Case B: ErrorTypes.SERVICE_ERROR is incremented and equal to 13.
        - Case C: ErrorTypes.CONNECTION_ERROR is incremented and equal to 1.
        - Cases D/E/G/H: ErrorTypes.GENERAL_ERROR is incremented and equal to 1.
        - Case F: ErrorTypes.CONNECTION_ERROR is incremented and equal to 1.

    """
    actual: ExecutionMetrics = increment_metric(execution_metrics=em, mapping=mapping, caught_exception=exception_caught)

    for metrics in actual.metrics.execution_metrics:  # type: ignore
        if (metrics["Type"], metrics["APICallsCount"]) == expected:
            actual_type = metrics["Type"]
            actual_count = metrics["APICallsCount"]
            break

    assert actual_type == expected[0]
    assert actual_count == expected[1]


@pytest.mark.parametrize("domain,expected", [("google.com", "whois.verisign-grs.com")])
def test_get_root_server(domain: str, expected: str):
    """
    Test to get the root server from the domain. The root server resolution is handled inside
    ``Whois`` by `tlds` and `dble_ext` dictionaries.

    Given: a domain.

    When: The domain is google.com.

    Then: The root server is whois.verisign-grs.com.

    """
    assert expected == get_root_server(domain)


@pytest.mark.parametrize(
    "domain",
    [
        ("com"),
        ("1.1.1.1"),
    ],
)
def test_get_root_server_invalid_domain(domain: str, capfd: pytest.CaptureFixture):
    """
    Test to get the root server from the domain when an invalid domain is supplied.

    Given: a domain.

    When:
        - Case A: An `str` that has no '.' in it.
        - Case B: An IP address.

    Then:
        - `WhoisInvalidDomain` expected

    """
    with capfd.disabled(), pytest.raises(WhoisInvalidDomain):
        get_root_server(domain)


@pytest.mark.parametrize(
    "args, expected_res",
    [
        ({"domain": "cnn.com", "is_recursive": "true", "verbose": "true", "should_error": "false"}, 2),
        ({"domain": "cnn.com", "is_recursive": "true", "should_error": "false"}, 2),
    ],
)
def test_domain_command(args: dict[str, Any], expected_res, mocker: MockerFixture):
    """
    Given:
        - The args for the domain command.
    When:
        - calling the whois command.
    Then:
        - validate that another context path is added for the raw-response if verbose arg is true.
    """
    mocker.patch.object(ExecutionMetrics, "is_supported", return_value=True)
    mocker.patch.object(demisto, "command", "domain")
    mocker.patch.object(demisto, "args", return_value=args)
    mocker.patch("Whois.get_domain_from_query", return_value="cnn.com")
    with open("test_data/cnn_pickled", "rb") as f:
        get_whois_ret_value = pickle.load(f)  # guardrails-disable-line
    mocker.patch("Whois.get_whois", return_value=get_whois_ret_value)

    result = domain_command(reliability="B - Usually reliable")
    assert len(result) == expected_res


def test_parse_nic_contact_new_regex():
    """
    Given:
        - Data fetched from the API.
    When:
        - calling the whois/domain command.
    Then:
        - validate that the data extracted without timeout.
    """
    from Whois import parse_nic_contact

    data = pathlib.Path("test_data/whois_response_text.txt").read_text()
    res = parse_nic_contact([data])
    assert len(res) == 2
    assert any(entry.get("email") == "test@test.net" for entry in res)
    assert any(entry.get("country") == "TEST" for entry in res)


@pytest.mark.parametrize(
    "raw_data, domain, expected",
    [
        (
            load_test_data("test_data/test-arrange-data.json")["raw"]["google"],
            "google.com",
            load_test_data("test_data/test-arrange-data.json")["res"]["google"],
        ),  # noqa: E501
        (
            load_test_data("test_data/test-arrange-data.json")["raw"]["ansa"],
            "ansa.it",
            load_test_data("test_data/test-arrange-data.json")["res"]["ansa"],
        ),  # noqa: E501
        (
            load_test_data("test_data/test-arrange-data.json")["raw"]["jp"],
            "nhk.or.jp",
            load_test_data("test_data/test-arrange-data.json")["res"]["jp"],
        ),  # noqa: E501
        (
            load_test_data("test_data/test-arrange-data.json")["raw"]["microsoft"],
            "microsoft.com",
            load_test_data("test_data/test-arrange-data.json")["res"]["microsoft"],
        ),  # noqa: E501
        (
            load_test_data("test_data/test-arrange-data.json")["raw"]["apple"],
            "apple.com",
            load_test_data("test_data/test-arrange-data.json")["res"]["apple"],
        ),  # noqa: E501
    ],
)
def test_arrange_raw_to_context(raw_data, domain, expected):
    """
    Given:
        - 'raw_data': Raw data dictionary from a whois lookup.
        - 'domain': Domain name associated with the raw data.

    When:
        - Calling arrange_raw_whois_data_to_context with 'raw_data' and 'domain'.

    Then:
        - Assert that the returned context dictionary 'res' matches the expected 'expected'.
    """
    from Whois import arrange_raw_whois_data_to_context

    res = arrange_raw_whois_data_to_context(raw_data, domain)
    assert res == expected


@pytest.mark.parametrize(
    "servers, expected",
    [
        (None, []),
        ("example.com", ["example.com"]),
        ("example.com\nexample.net", ["example.com", "example.net"]),
        (["EXAMPLE.COM", "example.com", "example.NET"], ["example.com", "example.net"]),
        (["server1.com", "server2.com", "server1.com"], ["server1.com", "server2.com"]),
        ([], []),
    ],
)
def test_extract_name_servers(servers, expected):
    """
    Given:
        - 'servers': Input to the extract_name_servers function.

    When:
        - Calling extract_name_servers with the input 'servers'.

    Then:
        - Assert that the output matches the expected 'expected'.
    """
    from Whois import extract_name_servers

    assert extract_name_servers(servers) == expected


@pytest.mark.parametrize(
    "domain_data, prefix, expected",
    [
        # Test case for registrar prefix
        (
            {"registrar": "Namecheap", "registrar_url": "https://www.namecheap.com"},
            "registrar",
            {"Name": "Namecheap", "Url": "https://www.namecheap.com"},
        ),
        # Test case for admin prefix
        (
            {
                "admin_name": "John Doe",
                "admin_email": "john@example.com",
                "admin_phone": None,
            },
            "admin",
            {"Name": "John Doe", "Email": "john@example.com"},
        ),
        # Test case for tech prefix with some None values
        (
            {
                "tech_name": "Jane Smith",
                "tech_email": None,
                "tech_phone": "+1234567890",
            },
            "tech",
            {"Name": "Jane Smith", "Phone": "+1234567890"},
        ),
        # Test case for billing prefix (empty result)
        ({"domain_name": "example.com", "creation_date": "2020-01-01"}, "billing", {}),
        # Test case for mixed prefixes
        (
            {
                "registrar": "GoDaddy",
                "admin_name": "Alice",
                "tech_email": "tech@example.com",
            },
            "registrar",
            {"Name": "GoDaddy"},
        ),
        # Test case for non-existent prefix
        ({"registrar": "Namecheap", "admin_name": "Bob"}, "invalid_prefix", {}),
        # Test case for empty input
        ({}, "any_prefix", {}),
        # Test case for registrar prefix with underscore in key
        (
            {"registrar": "Domain.com", "registrar_abuse_email": "abuse@domain.com"},
            "registrar",
            {"Name": "Domain.com", "AbuseEmail": "abuse@domain.com"},
        ),
        # Test case for multi-word key
        (
            {"admin_first_name": "John", "admin_last_name": "Doe"},
            "admin",
            {"FirstName": "John", "LastName": "Doe"},
        ),
    ],
)
def test_get_info_by_prefix(domain_data, prefix, expected):
    """
    Given:
        - `domain_data` containing domain information.
        - `prefix` specifying the filter criterion.
    When:
        - `get_info_by_prefix(domain_data, prefix)` is called.
    Then:
        - Ensure the returned dictionary matches `expected`,
          verifying correct filtering based on the prefix.
    """
    from Whois import get_info_by_prefix

    assert get_info_by_prefix(domain_data, prefix) == expected


@pytest.mark.parametrize(
    "date, expected",
    [
        (["2023-05-17"], "17-05-2023"),
        ("2023-05-17", "17-05-2023"),
        ([], ""),
        (None, ""),
        ({}, ""),
        (["invalid-date"], "invalid-date"),
    ],
)
def test_extract_date(date, expected, mocker):
    """
    Given:
        - `raw_data` containing the raw data to extract date from.
        - `date_requested` specifying the key to extract the date value from `raw_data`.
        - `mocker` for mocking `demisto.debug` function.
    When:
        - `extract_date(raw_data, date_requested)` is called.
    Then:
        - Ensure the returned date string matches `expected`, handling various scenarios
          such as valid date formats, empty list, None, empty dictionary, and invalid date format.
    """
    from Whois import extract_date

    mocker.patch.object(demisto, "debug")
    assert extract_date(date) == expected


@pytest.mark.parametrize(
    "input_date, expected_output",
    [
        ("[接続年月日]                    09-04-2013", "09-04-2013"),
        ("[接続年月日]                    04/09/2013", "04/09/2013"),
        ("[接続年月日]                    04-09/2013", "04-09/2013"),
        ("[接続年月日]                    2013/043-09", None),
        ("[接続年月日]                    04/09-013", None),
        ("[接続年月日]                    abc/def/ghi", None),
        ("[接続年月日]                    123/456/789", None),
        ("[接続年月日]                    123-456-789", None),
        ("", None),
    ],
)
def test_extract_hard_date(input_date, expected_output):
    """
    Given:
        - Various input date strings representing different formats.
    When:
        - `extract_hard_date(input_date)` is called.
    Then:
        - Ensure the returned formatted date string matches `expected_output`,
          handling different valid date formats and scenarios where the input
          does not match expected formats and returns None.
    """
    from Whois import extract_hard_date

    assert extract_hard_date(input_date) == expected_output


@pytest.mark.parametrize(
    "input_dict, key_mapping, expected_output",
    [
        ({"a": 1, "b": 2, "c": 3}, {"a": "A", "b": "B"}, {"A": 1, "B": 2, "c": 3}),
        ({"a": 1, "b": 2, "c": 3}, {"d": "D"}, {"a": 1, "b": 2, "c": 3}),
        ({}, {"a": "A"}, {}),
    ],
)
def test_rename_keys(input_dict, key_mapping, expected_output):
    from Whois import rename_keys

    assert rename_keys(input_dict, key_mapping) == expected_output


def test_new_test_command(mocker: MockerFixture):
    import whois

    mocker.patch.object(demisto, "results")
    mocker.patch.object(demisto, "params", return_value={"old-version": "false"})
    mocker.patch.object(demisto, "command", return_value="test-module")
    mocker.patch.object(
        whois,
        "whois",
        return_value=load_test_data("test_data/test-arrange-data.json")["raw"]["google"],
    )
    mocker.patch.object(
        Whois,
        "arrange_raw_whois_data_to_context",
        return_value=load_test_data("test_data/test-arrange-data.json")["res"]["google"],
    )
    Whois.main()
    assert_results_ok()


def test_whois_and_domain_command(mocker: MockerFixture):
    """
    Test the new whois/domain command.

    Given:
    - Mock response for WHOIS call.

    When:
    - 2 results are returned.

    Then:
    - The first result raw response is JSON.
    """

    import whois
    from Whois import whois_and_domain_command

    mocker.patch.object(demisto, "debug")
    mocker.patch.object(demisto, "args", return_value={"domain": "google.com"})
    mocker.patch.object(ExecutionMetrics, "is_supported", return_value=True)
    mocker.patch.object(
        whois,
        "whois",
        return_value=load_test_data("test_data/test-arrange-data.json")["raw"]["google"],
    )
    res = whois_and_domain_command("domain", DBotScoreReliability.B)
    assert len(res) == 2
    assert isinstance(res[0].raw_response, dict)


def test_whois_and_domain_command_with_exception(mocker: MockerFixture):
    """
    Given:
    - an unknown domain
    - The "with_error" param is set to True

    When:
    - executing whois_and_domain_command function

    Then:
    - Ensure an informative message in the readable output (regarding the unknown domain)
    - Ensure entry_type is 4 which means EntryType.ERROR (since we mocked "with_error" param as True)
    - Ensure no exception or error was thrown
    """

    import whois
    from Whois import whois_and_domain_command
    from whois.exceptions import PywhoisError

    mocker.patch.object(demisto, "debug")
    mocker.patch.object(demisto, "args", return_value={"domain": "raw.githubusercontent.com"})
    mocker.patch.object(demisto, "params", return_value={"with_error": True})
    mocker.patch.object(ExecutionMetrics, "is_supported", return_value=True)
    mocker.patch.object(whois, "whois", side_effect=PywhoisError)
    res = whois_and_domain_command("domain", DBotScoreReliability.B)

    assert len(res) == 2
    assert (
        res[0].readable_output
        == "Exception of type PywhoisError was caught while performing whois lookup with the domain 'raw.githubusercontent.com': "
    )
    assert res[0].entry_type == 4


@pytest.mark.parametrize(
    "domain_info, expected_output, expected_domain_info",
    [
        ({"contact": "abuse@domain.com", "support": "support@domain.com"}, "abuse@domain.com", {"support": "support@domain.com"}),
        ({"emails": ["abuse@domain.com", "infoabuse@domain.com"]}, ["abuse@domain.com", "infoabuse@domain.com"], {"emails": []}),
        (
            {"contact": "admin@domain.com", "emails": ["abuse@domain.com", "info@domain.com"]},
            "abuse@domain.com",
            {"contact": "admin@domain.com", "emails": ["info@domain.com"]},
        ),
        (
            {"contact": "admin@domain.com", "support": "support@domain.com"},
            [],
            {"contact": "admin@domain.com", "support": "support@domain.com"},
        ),
    ],
)
def test_check_and_remove_abuse(domain_info, expected_output, expected_domain_info):
    from Whois import check_and_remove_abuse

    assert check_and_remove_abuse(domain_info) == expected_output
    assert domain_info == expected_domain_info


@pytest.mark.parametrize(
    "time_sensitive, expected_timeout",
    [
        (True, Whois.WHOIS_SOCKET_TIMEOUT_TIME_SENSITIVE),  # War Room inline enrichment
        (False, Whois.WHOIS_SOCKET_TIMEOUT_DEFAULT),  # Playbook context
    ],
)
def test_whois_request_socket_timeout_always_set(mocker: MockerFixture, time_sensitive: bool, expected_timeout: int):
    """
    Given:
        - The Whois integration is executing whois_request_get_response().
        - Case A: is_time_sensitive() returns True (War Room inline enrichment).
        - Case B: is_time_sensitive() returns False (playbook task execution).

    When:
        - whois_request_get_response() opens a TCP socket to the whois server.

    Then:
        - Case A: sock.settimeout(10) is called — fast fail for interactive use.
        - Case B: sock.settimeout(30) is called — prevents indefinite OS-level hang
          (~127s on Linux) when the whois server is unreachable.
    """
    from Whois import whois_request_get_response

    mocker.patch("Whois.is_time_sensitive", return_value=time_sensitive)

    mock_sock = mocker.MagicMock()
    mock_sock.recv.return_value = b""
    mock_sock.__enter__ = lambda s: s
    mock_sock.__exit__ = mocker.MagicMock(return_value=False)
    mocker.patch("socket.socket", return_value=mock_sock)

    whois_request_get_response("example.com", "whois.iana.org")

    mock_sock.settimeout.assert_called_once_with(expected_timeout)