CensysV2
Built on the industry’s most comprehensive Internet Map, the Censys Platform delivers unmatched visibility into global internet assets, adversary infrastructure, and evolving threats.
Data Enrichment & Threat Intelligence · Censys
Details
| ID | CensysV2 |
|---|---|
| Provider | Censys |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Built on the industry’s most comprehensive Internet Map, the Censys Platform delivers unmatched visibility into global internet assets, adversary infrastructure, and evolving threats.
This integration was integrated and tested with version 2.0 of Censys.
Some changes have been made that might affect your existing content.
If you are upgrading from a previous of this integration, see Breaking Changes.
Configure Censys v2 in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL | The URL of the Censys API server. | True |
| API Token | Personal Access Token from Censys Platform | True |
| Organization ID | The unique identifier for your Censys organization. | True |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False | |
| Determine IP score by labels (for paid subscribers) | Censys API provides reputation data exclusively to paid subscribers. When set to True, the integration will use labels to determine the IP score. |
False |
| IP Malicious labels | Used only when `Determine IP score by labels` is set. Labels to classify IP as Malicious. Input can be an array or comma-separated values. |
False |
| IP Suspicious labels | Used when `Determine IP score by labels` is set. Labels to classify IP as Suspicious. Input can be an array or comma-separated values. |
False |
| Malicious labels threshold | Determines the minimum number of labels returned that are classified as malicious for IP. | False |
| Suspicious labels threshold | Determines the minimum number of labels returned that are classified as suspicious for IP. | False |
| Source Reliability | Reliability of the source providing the intelligence data. |
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.
cen-view
Returns detailed information for an IP address or SHA256 within the specified index.
Base Command
cen-view
Input
| Argument Name | Description | Required |
|---|---|---|
| query | The IP address of the requested host. | Required |
| index | The index from which to retrieve data. Possible values are: ipv4, certificates. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.View.autonomous_system.asn | Number | The autonomous system number (ASN) that the host is in. |
| Censys.View.autonomous_system.bgp_prefix | String | The autonomous system’s CIDR. |
| Censys.View.autonomous_system.country_code | String | The autonomous system’s two-letter, ISO 3166-1 alpha-2 country code (e.g., US, CN, GB, RU). |
| Censys.View.autonomous_system.description | String | A brief description of the autonomous system. |
| Censys.View.autonomous_system.name | String | The friendly name of the autonomous system. |
| Censys.View.dns.names | String | DNS Names. |
| Censys.View.ip | String | The host’s IP address. |
| Censys.View.location.continent | String | The continent of the host’s detected location (e.g., North America, Europe, Asia, South America, Africa, Oceania). |
| Censys.View.location.coordinates | Unknown | The estimated coordinates of the host’s detected location. |
| Censys.View.location.country | String | The name of the country of the host’s detected location. |
| Censys.View.location.country_code | String | The two-letter ISO 3166-1 alpha-2 country code of the host’s detected location (e.g., US, CN, GB, RU). |
| Censys.View.location.postal_code | String | The postal code (if applicable) of the host’s detected location. |
| Censys.View.location.timezone | String | The IANA time zone database name of the host’s detected location. |
| Censys.View.services.dns | Unknown | DNS information. |
| Censys.View.services.port | Number | The port the service was reached at. |
| Censys.View.services.protocol | String | The name of the service on the port. This is typically the L7 protocol (e.g., “HTTP”); however, in the case that a more specific HTTP-based protocol is found (e.g., Kubernetes or Prometheus), the field will show that. This field indicates where protocol-specific data will be located. |
| Censys.View.services.transport_protocol | String | The transport protocol (known in OSI model as L4) used to contact this service (i.e., UDP or TCP). |
| Censys.View.services.banner | String | The banner as a part of the protocol scan. That field will be nested in the protocol-specific data under the service_name field. |
| Censys.View.services.cert | Unknown | A subset of the parsed details of the certificate, including the issuer, subject, fingerprint, names, public keys, and signature. |
| Censys.View.fingerprint_sha256 | String | The SHA2-256 digest over the DER encoding of the certificate. |
| Censys.View.fingerprint_md5 | String | The MD5 digest over the DER encoding of the certificate. |
| Censys.View.fingerprint_sha1 | String | The SHA1 digest over the DER encoding of the certificate. |
| Censys.View.fingerprint_sha256 | String | The SHA2-256 digest over the DER encoding of the certificate. |
| Censys.View.parsed.issuer.common_name | String | Common name. |
| Censys.View.parsed.issuer.country | String | Country name. |
| Censys.View.parsed.issuer.organization | String | Organization name. |
| Censys.View.parsed.issuer_dn | String | Information about the certificate authority that issued the certificate. |
| Censys.View.parsed.serial_number | String | The issuer-specific identifier of the certificate. |
| Censys.View.parsed.signature.signature_algorithm.name | String | Name of signature algorithm, e.g., SHA1-RSA or ECDSA-SHA512. Unknown algorithms get an integer ID. |
| Censys.View.parsed.signature.signature_algorithm.oid | String | The object identifier of the signature algorithm, in dotted-decimal notation. |
| Censys.View.parsed.subject.common_name | String | Common name. |
| Censys.View.parsed.subject.country | String | Country name. |
| Censys.View.parsed.subject.locality | String | Locality name. |
| Censys.View.parsed.subject.organization | String | The name of the organization to which the certificate was issued, if available. |
| Censys.View.parsed.subject.province | String | State of province name. |
| Censys.View.parsed.subject_dn | String | Information about the entity that was issued the certificate. |
| Censys.View.parsed.subject_key_info.fingerprint_sha256 | String | The SHA2-256 digest calculated over the certificate’s DER encoding. |
| Censys.View.parsed.subject_key_info.key_algorithm.name | String | Name of public key type, e.g., RSA or ECDSA. |
| IP.Address | String | IP address. |
| IP.ASN | String | The autonomous system name for the IP address, for example: “AS8948”. |
| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. |
| IP.Geo.Country | String | The country in which the IP address is located. |
| IP.Geo.Description | String | Additional information about the location. |
| IP.ASOwner | String | The autonomous system owner of 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. |
Command example
!cen-view index=ipv4 query=8.8.8.8
Context Example
{
"Censys": {
"View": {
"autonomous_system": {
"asn": 15169,
"bgp_prefix": "8.8.8.0/24",
"country_code": "US",
"description": "GOOGLE - Google LLC",
"name": "GOOGLE - Google LLC"
},
"dns": {
"forward_dns": {
"2.fangji123.xyz": {
"name": "2.fangji123.xyz",
"record_type": "a",
"resolve_time": "2026-01-28T02:58:34Z"
}
}
}
}
}
}
cen-search
Return previews of hosts matching a specified search query or a list of certificates that match the given query.
Base Command
cen-search
Input
| Argument Name | Description | Required |
|---|---|---|
| query | Query used to search for hosts with matching attributes. Uses the Censys Search Language. | Required |
| page_size | The maximum number of hits to return in each response (minimum of 0, maximum of 100). (Applies for the host search.). Default is 50. | Optional |
| limit | The number of results to return. Default is 50. | Optional |
| index | The index from which to retrieve data. Possible values are: ipv4, certificates. | Required |
| fields | The fields to return. (Applies for the certificates search.). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.Search.autonomous_system.asn | Number | The autonomous system number (ASN) that the host is in. |
| Censys.Search.autonomous_system.bgp_prefix | String | The autonomous system’s CIDR. |
| Censys.Search.autonomous_system.country_code | String | The autonomous system’s two-letter, ISO 3166-1 alpha-2 country code (e.g., US, CN, GB, RU). |
| Censys.Search.autonomous_system.description | String | A brief description of the autonomous system. |
| Censys.Search.autonomous_system.name | String | The friendly name of the autonomous system. |
| Censys.Search.ip | String | The host’s IP address. |
| Censys.Search.location.continent | String | The continent of the host’s detected location (e.g., North America, Europe, Asia, South America, Africa, Oceania). |
| Censys.Search.location.coordinates | Unknown | The estimated coordinates of the host’s detected location. |
| Censys.Search.location.country | String | The country of the host’s detected location. |
| Censys.Search.location.country_code | String | The two-letter ISO 3166-1 alpha-2 country code of the host’s detected location (e.g., US, CN, GB, RU). |
| Censys.Search.location.timezone | String | The IANA time zone database name of the host’s detected location. |
| Censys.Search.services.port | Number | The port the service was reached at. |
| Censys.Search.services.protocol | String | The name of the service on the port. This is typically the L7 protocol (e.g., “HTTP”); however, in case a more specific HTTP-based protocol is found (e.g., Kubernetes or Prometheus), the field will show that. This field indicates where protocol-specific data will be located. |
| Censys.Search.services.transport_protocol | String | The transport protocol (known in OSI model as L4) used to contact this service (i.e., UDP or TCP). |
| Censys.Search.fingerprint_sha256 | String | SHA 256 fingerprint. |
| Censys.Search.parsed.issuer.organization | Unknown | The organization name. |
| Censys.Search.names | Unknown | Common names for the entity. |
| Censys.Search.parsed.subject_dn | String | Distinguished name of the entity that the certificate belongs to. |
| Censys.Search.parsed.validity_period.not_after | Date | Timestamp of when the certificate expires. Time zone is UTC. |
| Censys.Search.parsed.validity_period.not_before | Date | Timestamp of when the certificate is first valid. Time zone is UTC. |
| Censys.Search.parsed.issuer_dn | String | Distinguished name of the entity that has signed and issued the certificate. |
| Censys.Search.parsed.subject.common_name | String | Common name(s) from the certificate subject. |
| Censys.Search.parsed.signature.self_signed | Boolean | Whether the certificate is self-signed. |
| Censys.Search.valid_to | String | Timestamp of when the certificate is valid to. |
| Censys.Search.self_signed | Boolean | Whether the certificate is self-signed. |
Command example
!cen-search index=certificates query="cert.parsed.issuer.common_name: \"Let's Encrypt\"" limit=1
Context Example
{
"Censys": {
"Search": {
"fingerprint_sha256": "0003da4aee3b252097bfc7f871ab6fbe3e08eb94c34ff5cea91aaa29248d3c8b",
"parsed": {
"issuer": {
"organization": [
"Let's Encrypt"
]
},
"issuer_dn": "C=US, ST=Let's Encrypt, O=Let's Encrypt, CN=Let's Encrypt Authority X3",
"subject_dn": "C=AU, ST=Some-State, O=Internet Widgits Pty Ltd",
"validity_period": {
"not_after": "2026-04-15T00:50:59Z",
"not_before": "2025-04-15T00:50:59Z"
}
}
}
}
}
Human Readable Output
Search results for query “cert.parsed.issuer.common_name: “Let’s Encrypt””
Issuer Issuer DN SHA256 Subject DN Validity not after Validity not before Let’s Encrypt C=US, ST=Let’s Encrypt, O=Let’s Encrypt, CN=Let’s Encrypt Authority X3 0003da4aee3b252097bfc7f871ab6fbe3e08eb94c34ff5cea91aaa29248d3c8b C=AU, ST=Some-State, O=Internet Widgits Pty Ltd 2026-04-15T00:50:59Z 2025-04-15T00:50:59Z
Command example
!cen-search index=ipv4 query="host.services.protocol:HTTP" limit=1
Context Example
{
"Censys": {
"Search": {
"autonomous_system": {
"asn": 4766,
"bgp_prefix": "10.0.0.0/12",
"country_code": "KR",
"description": "KIXS-AS-KR Korea Telecom",
"name": "KIXS-AS-KR Korea Telecom"
},
"dns": {
}
}
}
}
domain
Return all related IPs as relationships.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | A comma-separated list of domains to check. | Required |
| port | A comma-separated list of ports associated with the domain. Default is 80,443. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.Domain.location.postal_code | String | The postal code of the location associated with the domain. |
| Censys.Domain.location.province | String | The province name of the location associated with the domain. |
| Censys.Domain.location.country_code | String | The country code of the location associated with the domain. |
| Censys.Domain.location.timezone | String | The time zone of the location associated with the domain. |
| Censys.Domain.location.country | String | The country name of the location associated with the domain. |
| Censys.Domain.location.coordinates.longitude | Number | The longitude coordinate of the location associated with the domain. |
| Censys.Domain.location.coordinates.latitude | Number | The latitude coordinate of the location associated with the domain. |
| Censys.Domain.location.continent | String | The continent name of the location associated with the domain. |
| Censys.Domain.location.city | String | The city name of the location associated with the domain. |
| Censys.Domain.autonomous_system.country_code | String | The country code of the autonomous system associated with the domain. |
| Censys.Domain.autonomous_system.asn | Number | The Autonomous System Number (ASN) associated with the domain. |
| Censys.Domain.autonomous_system.name | String | The name of the autonomous system associated with the domain. |
| Censys.Domain.autonomous_system.bgp_prefix | String | The BGP prefix of the autonomous system associated with the domain. |
| Censys.Domain.autonomous_system.description | String | The description of the autonomous system associated with the domain. |
| Censys.Domain.services.transport_protocol | String | The transport protocol used by the service associated with the domain. |
| Censys.Domain.services.port | Number | The port number associated with the service associated with the domain. |
| Censys.Domain.services.protocol | String | The name of the service associated with the domain. |
| Censys.Domain.services.cert | String | The SSL/TLS certificate associated with the service associated with the domain. |
| Censys.Domain.ip | String | The IP address associated with the domain. |
| Censys.Domain.dns.reverse_dns.names | String | The reverse DNS names associated with the domain. |
| Censys.Domain.hostname | String | The hostname of the web property associated with the domain. |
| Censys.Domain.port | Number | The port number of the web property associated with the domain. |
| Censys.Domain.labels.value | String | Labels associated with the web property. |
| Censys.Domain.threats.name | String | Threat names associated with the web property. |
| Censys.Domain.vulns.id | String | Vulnerability IDs associated with the web property. |
| Censys.Domain.vulns.cvss | Number | CVSS scores for vulnerabilities associated with the web property. |
| Censys.Domain.vulns.severity | String | Severity levels for vulnerabilities associated with the web property. |
| Censys.Domain.software.vendor | String | Software vendors detected on the web property. |
| Censys.Domain.software.product | String | Software products detected on the web property. |
| Censys.Domain.software.version | String | Software versions detected on the web property. |
| Censys.Domain.cert.fingerprint_sha256 | String | SHA-256 fingerprint of the certificate associated with the web property. |
| Censys.Domain.cert.parsed.subject_dn | String | Subject DN of the certificate associated with the web property. |
| Censys.Domain.cert.parsed.issuer_dn | String | Issuer DN of the certificate associated with the web property. |
| Censys.Domain.tls.version_selected | String | TLS version selected for the web property. |
| Censys.Domain.tls.cipher_selected | String | Cipher suite selected for the web property. |
| Censys.Domain.endpoints.endpoint_type | String | Endpoint types associated with the web property. |
| Censys.Domain.endpoints.path | String | Endpoint paths associated with the web property. |
| Censys.Domain.jarm.fingerprint | String | JARM fingerprint of the web property. |
| Censys.Domain.scan_time | String | Scan time for the web property. |
| Domain.Name | string | The domain. |
| Domain.Relationships.EntityA | string | The domain name. |
| Domain.Relationships.EntityAType | string | The entity type. |
| Domain.Relationships.EntityB | string | The entity B. |
| Domain.Relationships.EntityBType | string | The entity B type. |
| Domain.Relationships.Relationship | string | The relationship type. |
| DBotScore.Indicator | unknown | The indicator that was tested. |
| DBotScore.Type | unknown | The indicator type. |
| DBotScore.Score | unknown | The actual score. |
| DBotScore.Vendor | unknown | The vendor used to calculate the score. |
Command example
!domain domain=amazon.com,google.com
Context Example
{
"Censys": {
"Domain": [
{
"autonomous_system": {
"asn": 14618,
"bgp_prefix": "10.0.0.0/13",
"country_code": "US",
"description": "AMAZON-AES - Amazon.com, Inc.",
"name": "AMAZON-AES - Amazon.com, Inc."
},
"dns": {
"forward_dns": {
"amazon.com": {
"name": "amazon.com",
"record_type": "a",
"resolve_time": "2026-01-27T20:29:15Z"
}
},
"names": [
"amazon.com"
],
"reverse_dns": {
"names": [
"ec2-192-0-2-1.compute-1.amazonaws.com"
],
"resolve_time": "2026-01-13T16:21:30Z"
}
},
"ip": "192.0.2.1",
"location": {
"city": "Ashburn",
"continent": "North America",
"coordinates": {
"latitude": 39.04372,
"longitude": -77.48749
},
"country": "United States",
"country_code": "US",
"postal_code": "20147",
"province": "Virginia",
"timezone": "America/New_York"
},
"service_count": 2,
"services": [
{
"port": 80,
"protocol": "HTTP",
"transport_protocol": "tcp"
},
{
"banner": "HTTP/1.1 400 Bad Request\r\nServer: Server\r\nDate: <REDACTED>\r\nContent-Type: text/html\r\nTransfer-Encoding: chunked\r\nConnection: close\r\n",
"banner_hash_sha256": "0269a8a467d7591227ba20e7be6f0992ff31791f5235e31a60fc5ff168a4c921",
"cert": {
"added_at": "2025-11-06T17:17:35Z",
"ct": {
"entries": {
"cloudflare_nimbus_2026": {
"added_to_ct_at": "2025-11-06T17:48:17Z",
"ct_to_censys_at": "2025-11-06T18:54:38Z",
"index": 846730169
},
"google_argon_2026_h2": {
"added_to_ct_at": "2025-11-06T17:41:18Z",
"ct_to_censys_at": "2025-11-06T17:45:17Z",
"index": 189639680
},
"google_xenon_2026_h2": {
"added_to_ct_at": "2025-11-06T17:41:18Z",
"ct_to_censys_at": "2025-11-06T17:51:37Z",
"index": 143726358
},
"letsencrypt_ct_oak_2026_h2": {
"added_to_ct_at": "2025-11-06T17:41:18Z",
"ct_to_censys_at": "2025-11-06T17:49:49Z",
"index": 117540704
},
"letsencrypt_ct_sycamore_2026_h2": {
"added_to_ct_at": "2025-11-06T17:45:49Z",
"ct_to_censys_at": "2025-12-12T18:19:25Z",
"index": 22212155
},
"letsencrypt_ct_willow_2026_h2": {
"added_to_ct_at": "2025-11-06T17:46:09Z",
"ct_to_censys_at": "2025-12-12T19:58:13Z",
"index": 22208638
},
"trustasia_log_2026_a": {
"added_to_ct_at": "2025-11-17T04:30:41Z",
"ct_to_censys_at": "2025-11-17T18:18:36Z",
"index": 88656657
},
"trustasia_log_2026_b": {
"added_to_ct_at": "2025-11-10T06:27:14Z",
"ct_to_censys_at": "2025-11-10T06:32:24Z",
"index": 86980442
}
}
},
"ever_seen_in_scan": true,
"fingerprint_md5": "3a20cd834e379eb01e8fca18625a095b",
"fingerprint_sha1": "3152b1059fa057395743ea0ca8068c6dccd133c5",
"fingerprint_sha256": "8c062771b98a854ef04f86bc5e3a97366a927c6c3fcc2647c67b988aceea3092",
"modified_at": "2025-12-12T19:58:13Z",
"names": [
"*.aa.peg.a2z.com",
"*.ab.peg.a2z.com",
"*.ac.peg.a2z.com",
"*.bz.peg.a2z.com",
"*.peg.a2z.com",
"amazon.co.jp",
"amazon.co.uk",
"amazon.com",
"amazon.com.au",
"amazon.de",
"amazon.jp",
"amzn.com",
"buckeye-retail-website.amazon.com",
"buybox.amazon.com",
"corporate.amazon.com",
"edgeflow-dp.aero.04f01a85e-frontier.amazon.com.au",
"edgeflow-dp.aero.47cf2c8c9-frontier.amazon.com",
"edgeflow-dp.aero.4d5ad1d2b-frontier.amazon.co.jp",
"edgeflow-dp.aero.abe2c2f23-frontier.amazon.de",
"edgeflow-dp.aero.bfbdc3ca1-frontier.amazon.co.uk",
"edgeflow.aero.04f01a85e-frontier.amazon.com.au",
"edgeflow.aero.47cf2c8c9-frontier.amazon.com",
"edgeflow.aero.4d5ad1d2b-frontier.amazon.co.jp",
"edgeflow.aero.abe2c2f23-frontier.amazon.de",
"edgeflow.aero.bfbdc3ca1-frontier.amazon.co.uk",
"home.amazon.com",
"huddles.amazon.com",
"iphone.amazon.com",
"origin-www.amazon.co.jp",
"origin-www.amazon.co.uk",
"origin-www.amazon.com",
"origin-www.amazon.com.au",
"origin-www.amazon.de",
"origin2-www.amazon.co.jp",
"origin2-www.amazon.com",
"uedata.amazon.co.uk",
"uedata.amazon.com",
"us.amazon.com",
"www.amazon.co.jp",
"www.amazon.co.uk",
"www.amazon.com",
"www.amazon.com.au",
"www.amazon.de",
"www.amazon.jp",
"www.amzn.com",
"yp.amazon.com"
],
"parent_spki_fingerprint_sha256": "a0f06408dfb8d5e0095d4a968536efd3ecdc75025691b142170e7eb66c85b39a",
"parent_spki_subject_fingerprint_sha256": "a0f06408dfb8d5e0095d4a968536efd3ecdc75025691b142170e7eb66c85b39a",
"parse_status": "success",
"parsed": {
"extensions": {
"authority_info_access": {
"issuer_urls": [
"http://example.com/cacerts/DigiCertGlobalCAG2.crt"
],
"ocsp_urls": [
"http://example.com/ocsp"
]
},
"authority_key_id": "246e2b2dd06a925151256901aa9a47a689e74020",
"basic_constraints": {},
"certificate_policies": [
{
"cps": [
"http://example.com/CPS"
],
"id": "1.2.3.4.5.6.7"
}
],
"crl_distribution_points": [
"http://example.com/crl/DigiCertGlobalCAG2.crl",
"http://example.com/crl2/DigiCertGlobalCAG2.crl"
],
"extended_key_usage": {
"client_auth": true,
"server_auth": true
},
"key_usage": {
"digital_signature": true,
"key_encipherment": true,
"value": 5
},
"signed_certificate_timestamps": [
{
"log_id": "d809553b944f7affc816196f944f85abb0f8fc5e8755260f15d12e72bb454b14",
"signature": {
"hash_algorithm": "SHA256",
"signature": "304402203a1a41e357a63d9b599cadecafc2215d60f6b884187b02df237bb196c262d4dd02201431d3cca905bc2ba7bdbc5891269976330bd6696fcc6e4509ace0c82a5b80d8",
"signature_algorithm": "ECDSA"
},
"timestamp": "2025-11-06T16:37:35Z"
},
{
"log_id": "c2317e574519a345ee7f38deb29041ebc7c2215a22bf7fd5b5ad769ad90e52cd",
"signature": {
"hash_algorithm": "SHA256",
"signature": "3045022100fd699c45d2e93df414102920a416677928078dd171201f18250ada49aecf84f202204f3f00142c85bb1e2973c106b856c7b9ec2af1958acfbdcc8c6aedf3e5d00d64",
"signature_algorithm": "ECDSA"
},
"timestamp": "2025-11-06T16:37:35Z"
},
{
"log_id": "944e4387faecc1ef81f3192426a8186501c7d35f3802013f72677d55372e19d8",
"signature": {
"hash_algorithm": "SHA256",
"signature": "30440220432960ef2fde72dab8edc759403700640c61392d80df91c3688876a43b9d24f2022013695dd7abbe84eac82469bb7a6c37afd8a8999eac07d1ed330e41e1495b186d",
"signature_algorithm": "ECDSA"
},
"timestamp": "2025-11-06T16:37:35Z"
}
],
"subject_alt_name": {
"dns_names": [
"amazon.co.uk",
"uedata.amazon.co.uk",
"www.amazon.co.uk",
"origin-www.amazon.co.uk",
"*.peg.a2z.com",
"amazon.com",
"amzn.com",
"uedata.amazon.com",
"us.amazon.com",
"www.amazon.com",
"www.amzn.com",
"corporate.amazon.com",
"buybox.amazon.com",
"iphone.amazon.com",
"yp.amazon.com",
"home.amazon.com",
"origin-www.amazon.com",
"origin2-www.amazon.com",
"buckeye-retail-website.amazon.com",
"huddles.amazon.com",
"amazon.de",
"www.amazon.de",
"origin-www.amazon.de",
"amazon.co.jp",
"amazon.jp",
"www.amazon.jp",
"www.amazon.co.jp",
"origin-www.amazon.co.jp",
"*.aa.peg.a2z.com",
"*.ab.peg.a2z.com",
"*.ac.peg.a2z.com",
"origin-www.amazon.com.au",
"www.amazon.com.au",
"*.bz.peg.a2z.com",
"amazon.com.au",
"origin2-www.amazon.co.jp",
"edgeflow.aero.4d5ad1d2b-frontier.amazon.co.jp",
"edgeflow.aero.04f01a85e-frontier.amazon.com.au",
"edgeflow.aero.47cf2c8c9-frontier.amazon.com",
"edgeflow.aero.abe2c2f23-frontier.amazon.de",
"edgeflow.aero.bfbdc3ca1-frontier.amazon.co.uk",
"edgeflow-dp.aero.4d5ad1d2b-frontier.amazon.co.jp",
"edgeflow-dp.aero.04f01a85e-frontier.amazon.com.au",
"edgeflow-dp.aero.47cf2c8c9-frontier.amazon.com",
"edgeflow-dp.aero.bfbdc3ca1-frontier.amazon.co.uk",
"edgeflow-dp.aero.abe2c2f23-frontier.amazon.de"
]
},
"subject_key_id": "aaf8a5eaec987c7117d41fbd39c95f7b71020a1e"
},
"issuer": {
"common_name": [
"DigiCert Global CA G2"
],
"country": [
"US"
],
"organization": [
"DigiCert Inc"
]
},
"issuer_dn": "C=US, O=DigiCert Inc, CN=DigiCert Global CA G2",
"ja4x": "a373a9f83c6b_7022c563de38_2cdf432ec278",
"serial_number": "1377932119697704108067612670015473867",
"serial_number_hex": "0109614c77ec09ea900f923281c688cb",
"signature": {
"signature_algorithm": {
"name": "SHA256-RSA",
"oid": "1.2.840.113549.1.1.11"
},
"valid": true,
"value": "8fcff8d419d57562f4f719a070ea5a2c02083c40f966aab18848094b6cc9b76156f887193adfe5a09f3f384f060dfd0b31acfdd0c0cb7e86d51e681940044fb2f116f59b58c2d962b7796e9727c029f695b5790c2ed398b3f8129088a30327951477e11df26c7eb3675edf61051e9f64b97d85d58ee3d5b411cf17be2fd9431edfa0a32c4a1f5672465a0bb5c0f60f995c68a743bc4db9fb58e3c975a50055a92edc81ae9da05609de2dc49870f4ccb1f52f772aff214190a8ac9c3dda583ce7e0b5deb5157d583a2a0dfb4e8f80f07cd6cf8e3ddd18aff99660740f32cb45c4d2ec1ef30db280ae0de0ef77e12f5637bf4bef8e1cc245a3f29855a81bd466f5"
},
"subject": {
"common_name": [
"*.peg.a2z.com"
]
},
"subject_dn": "CN=*.peg.a2z.com",
"subject_key_info": {
"fingerprint_sha256": "325f1c87dc001e02a27de95ec7774bfb6d4b2ccf9ef5d5161696ff9936410fba",
"key_algorithm": {
"name": "RSA",
"oid": "1.2.840.113549.1.1.1"
},
"rsa": {
"exponent": 65537,
"length": 2048,
"modulus": "b865ad75cfa6bc86c43f193a00b6c712d249f7a0c2d8410dbd65a7480333439802acae4eed23ef679fd90931caa55b8949faf283d76b8767e983cde784d3c5ec860361165458fbbb24989b1abff67129eeba7d33f808a68b518641a05839ec5f87846863e3ba9379c230d23091a8d6c758b486d19a2d11ae97c5c06e951d5d3ecf927fc162b42fd00cfc623f2fa886cd8f14448fc155cd12e48bbe571fbafb532299fc9e816683953d254865fafe657097195a205dd53bcf400dc65c7b2960e46a02ec48534e517c1cb3f211cc75ca70166bba67d4587420cc0c2083aba4f0858dcbb2bc74f2f7ac14e9dd4d24516bd53037559263fd5a50656f39940aba6ce3"
}
},
"validity_period": {
"length_seconds": 27648000,
"not_after": "2026-09-21T23:59:59Z",
"not_before": "2025-11-06T00:00:00Z"
},
"version": 3
},
"revocation": {
"crl": {
"reason": "unspecified"
},
"ocsp": {
"reason": "unspecified"
}
},
"spki_fingerprint_sha256": "395a16ab1bc812de8784405859a631ac6519e85543fd9e7dbc8c52b33f865dc8",
"spki_subject_fingerprint_sha256": "395a16ab1bc812de8784405859a631ac6519e85543fd9e7dbc8c52b33f865dc8",
"tbs_fingerprint_sha256": "9cd2c97a60d07862c482661096c0239fcc60a689fd86db77133908a4dc562c4d",
"tbs_no_ct_fingerprint_sha256": "34752e5613070cd06115be2c4a2b8df47a53faef804055febc682db29a889f64",
"validated_at": "2026-01-27T19:29:18Z",
"validation": {
"apple": {
"chains": [
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"6523c34f1e879add7603cb2048a898a5e2f0c6c4b512c0d22782b85d43ae3371",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"79d57b15dfa65c2870eafe11b637765909cfe937b49c15ce7f194030cab395ad",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"a0d609a7e3c434e878a9a1c1bd065b8dcf33aa7efee1b11bc75cce5e5a042080",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"caf8ad697f7bda712ab127a8ad8b83f74a91a0de1784a1b483fef9ac79b67513",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
}
],
"ever_valid": true,
"had_trusted_path": true,
"has_trusted_path": true,
"is_valid": true,
"parents": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b"
],
"type": "leaf"
},
"chrome": {
"chains": [
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"6523c34f1e879add7603cb2048a898a5e2f0c6c4b512c0d22782b85d43ae3371",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"79d57b15dfa65c2870eafe11b637765909cfe937b49c15ce7f194030cab395ad",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"a0d609a7e3c434e878a9a1c1bd065b8dcf33aa7efee1b11bc75cce5e5a042080",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"caf8ad697f7bda712ab127a8ad8b83f74a91a0de1784a1b483fef9ac79b67513",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
}
],
"ever_valid": true,
"had_trusted_path": true,
"has_trusted_path": true,
"is_valid": true,
"parents": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b"
],
"type": "leaf"
},
"microsoft": {
"chains": [
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"0ba8c0d459b76abc0825294f565e24f4f169d4a4819d0692d371522d297724b8",
"2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"6523c34f1e879add7603cb2048a898a5e2f0c6c4b512c0d22782b85d43ae3371",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"79d57b15dfa65c2870eafe11b637765909cfe937b49c15ce7f194030cab395ad",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"a0d609a7e3c434e878a9a1c1bd065b8dcf33aa7efee1b11bc75cce5e5a042080",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
}
],
"ever_valid": true,
"had_trusted_path": true,
"has_trusted_path": true,
"is_valid": true,
"parents": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b"
],
"type": "leaf"
},
"nss": {
"chains": [
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"6523c34f1e879add7603cb2048a898a5e2f0c6c4b512c0d22782b85d43ae3371",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"79d57b15dfa65c2870eafe11b637765909cfe937b49c15ce7f194030cab395ad",
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"a0d609a7e3c434e878a9a1c1bd065b8dcf33aa7efee1b11bc75cce5e5a042080",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
},
{
"sha256fp": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"caf8ad697f7bda712ab127a8ad8b83f74a91a0de1784a1b483fef9ac79b67513",
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf"
]
}
],
"ever_valid": true,
"had_trusted_path": true,
"has_trusted_path": true,
"is_valid": true,
"parents": [
"8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b"
],
"type": "leaf"
}
},
"validation_level": "dv",
"zlint": {
"failed_lints": [
"n_subject_common_name_included"
],
"notices_present": true,
"timestamp": "2025-11-06T17:17:34Z",
"version": 3
}
},
"endpoints": [
{
"banner": "HTTP/1.1 400 Bad Request\r\nServer: Server\r\nDate: <REDACTED>\r\nContent-Type: text/html\r\nTransfer-Encoding: chunked\r\nConnection: close\r\n",
"banner_hash_sha256": "0269a8a467d7591227ba20e7be6f0992ff31791f5235e31a60fc5ff168a4c921",
"endpoint_type": "HTTP",
"hostname": "192.0.2.1",
"http": {
"body": "<!DOCTYPE html><html><head><title>x</title></head><body></body></html>\n",
"body_hash_sha1": "e441bba8b691ad0fff0bccb75974880018ab41d6",
"body_hash_sha256": "73f8ae8c11daa6ad905107970e55c3c64cd7133561e9e91e650aab092ba7245e",
"body_size": 71,
"headers": {
"Connection": {
"headers": [
"close"
]
},
"Content-Type": {
"headers": [
"text/html"
]
},
"Date": {
"headers": [
"<REDACTED>"
]
},
"Server": {
"headers": [
"Server"
]
},
"Transfer-Encoding": {
"headers": [
"chunked"
]
}
},
"html_tags": [
"<title>x</title>"
],
"html_title": "x",
"protocol": "HTTP/1.1",
"status_code": 400,
"status_reason": "Bad Request",
"supported_versions": [
"HTTP/1.1"
],
"uri": "https://192.0.2.1/"
},
"ip": "192.0.2.1",
"path": "/",
"port": 443,
"scan_time": "2026-01-27T21:48:42Z",
"transport_protocol": "tcp"
}
],
"ip": "8.8.8.8",
"ja4tscan": {
"fingerprint": "62643_2-4-8-1-3_1460_7_1-2-4-9-17",
"scan_time": "2026-01-27T04:00:58Z"
},
"port": 443,
"protocol": "HTTP",
"scan_time": "2026-01-27T21:48:42Z",
"tls": {
"cipher_selected": "TLS_AES_128_GCM_SHA256",
"fingerprint_sha256": "8c062771b98a854ef04f86bc5e3a97366a927c6c3fcc2647c67b988aceea3092",
"ja3s": "f4febc55ea12b31ae17cfb7e614afda8",
"ja4s": "t130200_1301_a56c5b993250",
"presented_chain": [
{
"fingerprint_sha256": "8fac576439c9fd3ef153b51f9edd0d381b5df7b87559cebeca04297dd44a639b",
"issuer_dn": "C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2",
"subject_dn": "C=US, O=DigiCert Inc, CN=DigiCert Global CA G2"
},
{
"fingerprint_sha256": "aadadd5a879d2eb8c41a89597291292709d42052f5b6399541c694c3b7353cd1",
"issuer_dn": "C=US, O=VeriSign\\, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign\\, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5",
"subject_dn": "C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2"
}
],
"version_selected": "tlsv1_3",
"versions": [
{
"ja3s": "f4febc55ea12b31ae17cfb7e614afda8",
"ja4s": "t130200_1301_a56c5b993250",
"version": "tlsv1_3"
},
{
"ja3s": "2b1f517a72b7346c86d59ef328167d49",
"ja4s": "t120300_c02f_cbb8871a0652",
"version": "tlsv1_2"
},
{
"ja3s": "24abcc4acb0869d8e569d403dfe55a99",
"ja4s": "t110300_c013_cbb8871a0652",
"version": "tlsv1_1"
},
{
"ja3s": "7ac2b84fdf4dcd940d5099b55a649c04",
"ja4s": "t100300_c013_cbb8871a0652",
"version": "tlsv1_0"
}
]
},
"transport_protocol": "tcp"
}
],
"whois": {
"network": {
"allocation_type": "REALLOCATION",
"cidrs": [
"10.0.0.0/13"
],
"created": "2024-02-21T00:00:00Z",
"handle": "AMAZON-IAD",
"name": "Amazon Data Services Northern Virginia",
"updated": "2024-02-21T00:00:00Z"
},
"organization": {
"abuse_contacts": [
{
"email": "abuse@example.com",
"handle": "AEA8-ARIN",
"name": "Amazon EC2 Abuse"
}
],
"admin_contacts": [
{
"email": "admin@example.com",
"handle": "IPMAN40-ARIN",
"name": "IP Management"
}
],
"city": "Herndon",
"country": "US",
"handle": "ADSN-1",
"name": "Amazon Data Services Northern Virginia",
"postal_code": "20171",
"state": "VA",
"street": "13200 Woodland Park Road",
"tech_contacts": [
{
"email": "noc@example.com",
"handle": "ANO24-ARIN",
"name": "Amazon EC2 Network Operations"
}
]
}
}
}
]
},
"DBotScore": [
{
"Indicator": "amazon.com",
"Reliability": "C - Fairly reliable",
"Score": 0,
"Type": "domain",
"Vendor": "CensysV2"
},
{
"Indicator": "google.com",
"Reliability": "C - Fairly reliable",
"Score": 3,
"Type": "domain",
"Vendor": "CensysV2"
}
],
"Domain": [
{
"Name": "amazon.com",
"Relationships": [
{
"EntityA": "amazon.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.1",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "amazon.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.2",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "amazon.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.3",
"EntityBType": "IP",
"Relationship": "related-to"
}
]
},
{
"Malicious": {
"Description": "Matched malicious labels: IPV6",
"Vendor": "CensysV2"
},
"Name": "google.com",
"Relationships": [
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::1",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::2",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::3",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::4",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::5",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::6",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::7",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::8",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::9",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "2001:db8::10",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.10",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.11",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.12",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.13",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.14",
"EntityBType": "IP",
"Relationship": "related-to"
},
{
"EntityA": "google.com",
"EntityAType": "Domain",
"EntityB": "192.0.2.15",
"EntityBType": "IP",
"Relationship": "related-to"
}
]
}
]
}
Human Readable Output
Censys results for Domain amazon.com
Enriched Web Property Data
Hostname Port Scan Time Endpoint Types Endpoint Paths Labels Threat Names Vulns Names Vendors Products Versions sha256 Subject DN Issuer DN Common Names Not Before Not After amazon.com 443 2026-03-10T07:52:06Z HTTP / WEB_SERVER, HTTPS OUTDATED_SOFTWARE CVE-2024-11111 f5 nginx 1.18.0 0000000000000000000000000000000000000000000000000000000000000001 CN=example.com C=US, O=Let’s Encrypt, CN=R11 example.com 2025-01-03T04:11:45Z 2025-04-03T04:11:44Z Information for IP 8.8.8.8
ASN Network Protocols Routing Whois Last Updated 15169 GOOGLE - Google LLC 53/DNS, 443/UNKNOWN, 443/HTTP, 853/UNKNOWN 8.8.8.0/24 2023-12-28T00:00:00Z
Command example
!cen-view index=certificates query=9d3b51a6b80daf76e074730f19dc01e643ca0c3127d8f48be64cf3302f6622cc limit=1
Context Example
{
"Censys": {
"View": {
"added_at": "1970-01-01T00:00:00Z",
"ct": {
"entries": {
"digicert_ct1": {
"added_to_ct_at": "2015-09-29T19:55:46Z",
"ct_to_censys_at": "2018-07-30T04:49:40Z",
"index": 165790
},
"google_aviator": {
"index": 8713649
},
"google_pilot": {
"added_to_ct_at": "2015-09-29T19:55:45Z",
"ct_to_censys_at": "2018-07-30T15:23:48Z",
"index": 9498499
},
"google_rocketeer": {
"added_to_ct_at": "2015-09-29T19:55:45Z",
"ct_to_censys_at": "2018-07-30T15:17:12Z",
"index": 6663198
},
"nordu_ct_plausible": {
"added_to_ct_at": "2015-10-19T23:17:33Z",
"ct_to_censys_at": "2018-07-30T19:53:59Z",
"index": 5744025
},
"symantec_ws_ct": {
"added_to_ct_at": "2015-09-29T19:55:46Z",
"ct_to_censys_at": "2018-07-30T04:22:53Z",
"index": 6913
}
}
},
"ever_seen_in_scan": true,
"fingerprint_md5": "0f263d5e56288c37ade29f7b9977f38d",
"fingerprint_sha1": "8740f09afc54752b26b295cdc6393c6b8ffd9e6a",
"fingerprint_sha256": "9d3b51a6b80daf76e074730f19dc01e643ca0c3127d8f48be64cf3302f6622cc",
"modified_at": "2024-01-23T12:12:35Z",
"names": [
"*.android.com",
"*.appengine.google.com",
"*.cloud.google.com",
"*.google-analytics.com",
"*.google.ca",
"*.google.cl",
"*.google.co.in",
"*.google.co.jp",
"*.google.co.uk",
"*.google.com",
"*.google.com.ar",
"*.google.com.au",
"*.google.com.br",
"*.google.com.co",
"*.google.com.mx",
"*.google.com.tr",
"*.google.com.vn",
"*.google.de",
"*.google.es",
"*.google.fr",
"*.google.hu",
"*.google.it",
"*.google.nl",
"*.google.pl",
"*.google.pt",
"*.googleadapis.com",
"*.googleapis.cn",
"*.googlecommerce.com",
"*.googlevideo.com",
"*.gstatic.cn",
"*.gstatic.com",
"*.gvt1.com",
"*.gvt2.com",
"*.metric.gstatic.com",
"*.urchin.com",
"*.url.google.com",
"*.youtube-nocookie.com",
"*.youtube.com",
"*.youtubeeducation.com",
"*.ytimg.com",
"android.com",
"g.co",
"goo.gl",
"google-analytics.com",
"google.com",
"googlecommerce.com",
"urchin.com",
"youtu.be",
"youtube.com",
"youtubeeducation.com"
],
"parent_spki_subject_fingerprint_sha256": "ec0c72ce7689150e4f62d04f51f0f19713f77cf27ff43cab4035e9e54e846aa9",
"parse_status": "success",
"parsed": {
"extensions": {
"authority_info_access": {
"issuer_urls": [
"http://pki.google.com/GIAG2.crt"
],
"ocsp_urls": [
"http://clients1.google.com/ocsp"
]
},
"authority_key_id": "4add06161bbcf668b576f581b6bb621aba5a812f",
"basic_constraints": {},
"certificate_policies": [
{
"id": "1.2.3.4.5.6.7.8.9"
},
{
"id": "1.2.3.4.5.6.7.8.10"
}
],
"crl_distribution_points": [
"http://pki.google.com/GIAG2.crl"
],
"extended_key_usage": {
"client_auth": true,
"server_auth": true
},
"key_usage": {
"digital_signature": true,
"value": 1
},
"subject_alt_name": {
"dns_names": [
"*.google.com",
"*.android.com",
"*.appengine.google.com",
"*.cloud.google.com",
"*.google-analytics.com",
"*.google.ca",
"*.google.cl",
"*.google.co.in",
"*.google.co.jp",
"*.google.co.uk",
"*.google.com.ar",
"*.google.com.au",
"*.google.com.br",
"*.google.com.co",
"*.google.com.mx",
"*.google.com.tr",
"*.google.com.vn",
"*.google.de",
"*.google.es",
"*.google.fr",
"*.google.hu",
"*.google.it",
"*.google.nl",
"*.google.pl",
"*.google.pt",
"*.googleadapis.com",
"*.googleapis.cn",
"*.googlecommerce.com",
"*.googlevideo.com",
"*.gstatic.cn",
"*.gstatic.com",
"*.gvt1.com",
"*.gvt2.com",
"*.metric.gstatic.com",
"*.urchin.com",
"*.url.google.com",
"*.youtube-nocookie.com",
"*.youtube.com",
"*.youtubeeducation.com",
"*.ytimg.com",
"android.com",
"g.co",
"goo.gl",
"google-analytics.com",
"google.com",
"googlecommerce.com",
"urchin.com",
"youtu.be",
"youtube.com",
"youtubeeducation.com"
]
},
"subject_key_id": "19c6b145efc879529b4a57b15e0d543b011dce35"
},
"issuer": {
"common_name": [
"Google Internet Authority G2"
],
"country": [
"US"
],
"organization": [
"Google Inc"
]
},
"issuer_dn": "C=US, O=Google Inc, CN=Google Internet Authority G2",
"serial_number": "5878999135690490607",
"serial_number_hex": "51966690cda902ef",
"signature": {
"signature_algorithm": {
"name": "SHA256-RSA",
"oid": "1.2.840.113549.1.1.11"
},
"valid": true,
"value": "1e36357c79acc1c99ddec329d06a1695b2e82cc6ee884d6a699e035219fc804df3d090e7e910d88d9f2a3aa300dff16a732c33775bca074b279b6251924f597c160d3b5688b17a525da0818ed16654f7996ab2c81627ad59ee9b4be94b6c2e05873539fdb83b280cbbccf647ba1d44fb2b3beafe0efc9ba2e6258ef809a4cb0bbec54e09dd21236ca10962e6d7b1ae42328bcdc25fa57b650f8aeff1aaef90721098563e8a406567462674b39318f3a6ca54fc651d15ca8eecadff61484a9e3cb078100e6ab96d9d620798752dcf83bdd3b2be69bbdfc22c0e87aff10ce2305d855c6c9a1133e6fc207601f139f0c8fdb3dae5d21371eff9be66de79edcaef6a"
},
"subject": {
"common_name": [
"*.google.com"
],
"country": [
"US"
],
"locality": [
"Mountain View"
],
"organization": [
"Google Inc"
],
"province": [
"California"
]
},
"subject_dn": "C=US, ST=California, L=Mountain View, O=Google Inc, CN=*.google.com",
"subject_key_info": {
"ecdsa": {
"b": "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
"curve": "P-256",
"gx": "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"gy": "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
"length": 256,
"n": "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
"p": "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
"pub": "04f680d0e5c3a1162f2420176176add7ba927c0cecb52453bfa84a16c9fe56219b1ec2b31bcf2ae30d5fb45c475edc79725bf57889a3b2a76ec940d567e66fce77",
"x": "f680d0e5c3a1162f2420176176add7ba927c0cecb52453bfa84a16c9fe56219b",
"y": "1ec2b31bcf2ae30d5fb45c475edc79725bf57889a3b2a76ec940d567e66fce77"
},
"fingerprint_sha256": "3d4a4bd778be7965e90a13ac361e1ed7836d24c15cd5c093f9cc7e7857f53ea0",
"key_algorithm": {
"name": "ECDSA",
"oid": "1.2.840.10045.2.1"
}
},
"validity_period": {
"length_seconds": 7708841,
"not_after": "2015-12-28T00:00:00Z",
"not_before": "2015-09-29T18:39:20Z"
},
"version": 3
},
"spki_subject_fingerprint_sha256": "5eb06b1c29ced84998d3d35a80fa17d3d39e4de96d25539485aecd6360f618dc",
"tbs_fingerprint_sha256": "1661b59eb7d8cda44f800fabc9ef69ba01506309eedf027f2270105afd1663e4",
"tbs_no_ct_fingerprint_sha256": "1661b59eb7d8cda44f800fabc9ef69ba01506309eedf027f2270105afd1663e4",
"validated_at": "2023-09-09T05:55:46Z",
"validation": {
"apple": {
"chains": [
{
"sha256fp": [
"44336eb05c6c783dc177217a9f6fef75f4524e98045b390803ae9de69eb42b08",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"9f630426df1d8abfd80ace98871ba833ab9742cb34838de2b5285ed54c0c7dcc",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"a4124fdaf9cac7baee1cab32e3225d746500c09f3cf3ebb253ef3fbb088afd34",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"c3f697a92a293d86f9a3ee7ccb970e20e0050b8728cc83ed1b996ce9005d4c36",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
}
],
"ever_valid": true,
"had_trusted_path": true,
"parents": [
"44336eb05c6c783dc177217a9f6fef75f4524e98045b390803ae9de69eb42b08",
"9f630426df1d8abfd80ace98871ba833ab9742cb34838de2b5285ed54c0c7dcc",
"a4124fdaf9cac7baee1cab32e3225d746500c09f3cf3ebb253ef3fbb088afd34",
"c3f697a92a293d86f9a3ee7ccb970e20e0050b8728cc83ed1b996ce9005d4c36"
],
"type": "leaf"
},
"chrome": {},
"microsoft": {
"chains": [
{
"sha256fp": [
"44336eb05c6c783dc177217a9f6fef75f4524e98045b390803ae9de69eb42b08",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"9f630426df1d8abfd80ace98871ba833ab9742cb34838de2b5285ed54c0c7dcc",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"a4124fdaf9cac7baee1cab32e3225d746500c09f3cf3ebb253ef3fbb088afd34",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"c3f697a92a293d86f9a3ee7ccb970e20e0050b8728cc83ed1b996ce9005d4c36",
"ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a"
]
},
{
"sha256fp": [
"44336eb05c6c783dc177217a9f6fef75f4524e98045b390803ae9de69eb42b08",
"3c35cc963eb004451323d3275d05b353235053490d9cd83729a2faf5e7ca1cc0",
"08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178"
]
}
],
"ever_valid": true,
"had_trusted_path": true,
"parents": [
"44336eb05c6c783dc177217a9f6fef75f4524e98045b390803ae9de69eb42b08",
"9f630426df1d8abfd80ace98871ba833ab9742cb34838de2b5285ed54c0c7dcc",
"a4124fdaf9cac7baee1cab32e3225d746500c09f3cf3ebb253ef3fbb088afd34",
"c3f697a92a293d86f9a3ee7ccb970e20e0050b8728cc83ed1b996ce9005d4c36"
],
"type": "leaf"
},
"nss": {}
},
"validation_level": "ov",
"zlint": {
"failed_lints": [
"n_subject_common_name_included",
"w_ext_key_usage_not_critical"
],
"notices_present": true,
"timestamp": "2023-09-09T05:55:46Z",
"version": 3,
"warnings_present": true
}
}
}
}
Human Readable Output
Information for certificate
Added At Browser Trust Modified At SHA 256 Validated At 1970-01-01T00:00:00Z nss: Invalid,
microsoft: Valid,
apple: Valid,
chrome: Invalid2024-01-23T12:12:35Z 9d3b51a6b80daf76e074730f19dc01e643ca0c3127d8f48be64cf3302f6622cc 2023-09-09T05:55:46Z
cen-search
Returns previews of hosts matching a specified search query, or a list of certificates that match the given query.
Base Command
cen-search
Input
| Argument Name | Description | Required |
|---|---|---|
| query | Query used to search for hosts with matching attributes. Uses the Censys Search Language. | Required |
| page_size | The maximum number of hits to return in each response (minimum of 0, maximum of 100). Default is 50. (Applies for the host search.) | Optional |
| limit | The number of results to return. Default is 50. | Optional |
| index | The index from which to retrieve data. Possible values are: ipv4, certificates. | Required |
| fields | The fields to return. (Applies for the certificates search). | Optional |
| page | The page to return. (Applies for the certificates search). Default is 1. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.Search.autonomous_system.asn | Number | The autonomous system number (ASN) that the host is in. |
| Censys.Search.autonomous_system.bgp_prefix | String | The autonomous system’s CIDR. |
| Censys.Search.autonomous_system.country_code | String | he autonomous system’s two-letter, ISO 3166-1 alpha-2 country code (e.g., US, CN, GB, RU). |
| Censys.Search.autonomous_system.description | String | A brief description of the autonomous system. |
| Censys.Search.autonomous_system.name | String | The friendly name of the autonomous system. |
| Censys.Search.ip | String | The host’s IP address. |
| Censys.Search.location.continent | String | The continent of the host’s detected location (e.g., North America, Europe, Asia, South America, Africa, Oceania). |
| Censys.Search.location.coordinates | Unknown | The estimated coordinates of the host’s detected location. |
| Censys.Search.location.country | String | The country of the host’s detected location. |
| Censys.Search.location.country_code | String | The two-letter ISO 3166-1 alpha-2 country code of the host’s detected location (e.g., US, CN, GB, RU). |
| Censys.Search.location.registered_country | String | The host’s registered country. |
| Censys.Search.location.registered_country_code | String | The registered country’s two-letter, ISO 3166-1 alpha-2 country code (e.g., US, CN, GB, RU). |
| Censys.Search.location.timezone | String | The IANA time zone database name of the host’s detected location. |
| Censys.Search.services.port | Number | The port the service was reached at. |
| Censys.Search.services.service_name | String | The name of the service on the port. This is typically the L7 protocol (e.g., “HTTP”); however, in the case that a more specific HTTP-based protocol is found (e.g., Kubernetes or Prometheus), the field will show that. This field indicates where protocol-specific data will be located. |
| Censys.Search.services.transport_protocol | String | The transport protocol (known in OSI model as L4) used to contact this service (i.e., UDP or TCP). |
| Censys.Search.parsed.fingerprint_sha256 | String | SHA 256 fingerprint. |
| Censys.Search.parsed.issuer.organization | Unknown | The organization name. |
| Censys.Search.parsed.names | Unknown | Common names for the entity. |
| Censys.Search.parsed.subject_dn | String | Distinguished name of the entity that the certificate belongs to. |
| Censys.Search.parsed.validity.end | Date | Timestamp of when the certificate expires. Time zone is UTC. |
| Censys.Search.parsed.validity.start | Date | Timestamp of when the certificate is first valid. Time zone is UTC. |
| Censys.Search.parsed.issuer_dn | String | Distinguished name of the entity that has signed and issued the certificate. |
Command Example
!cen-search index=certificates query="parsed.issuer.common_name: \"Let's Encrypt\"" limit=1
Context Example
{
"Censys": {
"Search": {
"parsed": {
"fingerprint_sha256": "f3ade17dffcadd9532aeb2514f10d66e22941393725aa65366ac286df9b1234",
"issuer": {
"organization": [
"Let's Encrypt"
]
},
"issuer_dn": "C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3",
"names": [
"*.45g4rg43g4fr3434g.gb.net",
"45g4rg43g4fr3434g.gb.net"
],
"subject_dn": "CN=45g4rg43g4fr3434g.gb.net",
"validity": {
"end": "2021-01-10T14:46:11Z",
"start": "2020-10-12T14:46:11Z"
}
}
}
}
}
Human Readable Output
Search results for query “parsed.issuer.common_name: “Let’s Encrypt””
Issuer Issuer DN Names SHA256 Subject DN Validity organization: Let’s Encrypt C=US, O=Let’s Encrypt, CN=Let’s Encrypt Authority X3 *.45g4rg43g4fr3434g.gb.net,
45g4rg43g4fr3434g.gb.netf3ade17dffcadd9532aeb2514f10d66e22941393725aa65366ac286df9b442ec CN=45g4rg43g4fr3434g.gb.net start: 2020-10-12T14:46:11Z
end: 2021-01-10T14:46:11Z
ip
Runs reputation on IPs.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | IP address or a list of IP addresses to assess reputation. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.IP.services.port | Number | The port number associated with the service running on the IP. |
| Censys.IP.services.transport_protocol | String | The transport protocol used by the service running on the IP. |
| Censys.IP.services.protocol | String | The name of the service running on the IP. |
| Censys.IP.services.cert | String | The SSL/TLS certificate associated with the service running on the IP. |
| Censys.IP.labels | String | Labels associated with the IP address (with premium access only). |
| Censys.IP.dns.reverse_dns.names | String | Reverse DNS names associated with the IP address. |
| Censys.IP.autonomous_system.country_code | String | The country code of the autonomous system associated with the IP address. |
| Censys.IP.autonomous_system.description | String | Description of the autonomous system associated with the IP address. |
| Censys.IP.autonomous_system.name | String | Name of the autonomous system associated with the IP address. |
| Censys.IP.autonomous_system.bgp_prefix | String | BGP prefix of the autonomous system associated with the IP address. |
| Censys.IP.autonomous_system.asn | Number | Autonomous System Number (ASN) of the autonomous system associated with the IP address. |
| Censys.IP.ip | String | The IP address. |
| Censys.IP.location.country | String | Country name of the location associated with the IP address. |
| Censys.IP.location.timezone | String | Time zone of the location associated with the IP address. |
| Censys.IP.location.province | String | Province name of the location associated with the IP address. |
| Censys.IP.location.coordinates.latitude | Number | Latitude coordinate of the location associated with the IP address. |
| Censys.IP.location.coordinates.longitude | Number | Longitude coordinate of the location associated with the IP address. |
| Censys.IP.location.continent | String | Continent name of the location associated with the IP address. |
| Censys.IP.location.postal_code | String | Postal code of the location associated with the IP address. |
| Censys.IP.location.city | String | City name of the location associated with the IP address. |
| Censys.IP.location.country_code | String | Country code of the location associated with the IP address. |
| Censys.IP.service_count | Number | The total number of services running on the IP address. |
| Censys.IP.services.labels.value | String | Labels associated with services running on the IP address. |
| Censys.IP.services.threats.name | String | Threat names associated with services running on the IP address. |
| Censys.IP.services.vulns | String | Vulnerabilities associated with services running on the IP address. |
| Censys.IP.services.scan_time | String | Scan time for services running on the IP address. |
| Censys.IP.dns.names | String | DNS names associated with the IP address. |
| Censys.IP.dns.forward_dns.names | String | Forward DNS names associated with the IP address. |
| Censys.IP.whois.network.name | String | WHOIS network name associated with the IP address. |
| Censys.IP.whois.network.cidrs | String | WHOIS network CIDR blocks associated with the IP address. |
| IP.Address | unknown | The IP address. |
| IP.ASN | unknown | The IP ASN. |
| IP.Geo.Country | unknown | The IP country. |
| IP.Geo.Location | unknown | The IP location. |
| IP.UpdatedDate | unknown | The IP last update. |
| IP.Port | unknown | The IP port. |
| DBotScore.Indicator | unknown | The indicator that was tested. |
| DBotScore.Type | unknown | The indicator type. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Vendor | unknown | The vendor used to calculate the score. |
Command example
!ip ip=8.8.8.8,8.8.4.4
Context Example
{
"services": [
{
"port": 53,
"transport_protocol": "UDP",
"extended_service_name": "DNS",
"service_name": "DNS"
},
{
"certificate": "5a7763efee07b08b18a4af2796bfaac46641a2f15c98e88c3d79fa9a06adfc87",
"extended_service_name": "HTTPS",
"port": 443,
"transport_protocol": "TCP",
"service_name": "HTTP"
},
{
"service_name": "UNKNOWN",
"transport_protocol": "QUIC",
"extended_service_name": "UNKNOWN",
"port": 443
},
{
"transport_protocol": "TCP",
"service_name": "UNKNOWN",
"port": 853,
"certificate": "5a7763efee07b08b18a4af2796bfaac46641a2f15c98e88c3d79fa9a06adfc87",
"extended_service_name": "UNKNOWN"
}
],
"labels": ["database","email","file-sharing","iot","login-page"],
"dns": {
"reverse_dns": {
"names": [
"dns.google"
]
}
},
"autonomous_system": {
"country_code": "US",
"description": "GOOGLE",
"name": "GOOGLE",
"bgp_prefix": "8.8.8.0/24",
"asn": 15169
},
"ip": "8.8.8.8",
"location": {
"country": "United States",
"timezone": "America/Los_Angeles",
"province": "California",
"coordinates": {
"latitude": 37.4056,
"longitude": -122.0775
},
"continent": "North America",
"postal_code": "94043",
"city": "Mountain View",
"country_code": "US"
},
"last_updated_at": "2024-04-07T02:16:23.015Z"
}
Human Readable Output
Censys results for IP: 8.8.8.8
Enriched Host Data
IP Labels Service Count Service Ports Service Protocols Service Transport Protocols Reverse DNS Names Autonomous System Name Autonomous System ASN City Province Postal Code Country Country Code Continent Latitude Longitude 8.8.8.8 database, email, file-sharing, iot, login-page 4 53, 443, 443, 853 DNS, HTTP, UNKNOWN, UNKNOWN UDP, TCP, QUIC, TCP dns.google 15169 Mountain View California 94043 United States US North America 37.4056 -122.0775
cen-host-history-list
Retrieve the event history for a host (IP address).
Base Command
cen-host-history-list
Input
| Argument Name | Description | Required |
|---|---|---|
| host_id | Specify the IP address of a host. | Required |
| start_time | Specify the start time of the host timeline. Supported date formats: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ. For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-10T14:05:44Z. |
Required |
| end_time | Specify the end time of the host timeline. Supported date formats: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ. For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-10T14:05:44Z. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.HostEventHistory.ip | String | The IP address of the host. |
| Censys.HostEventHistory.total_events | Number | The total number of events associated with the host. |
| Censys.HostEventHistory.partial_data | Boolean | Whether the data is partial or not. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.scan_time | Date | The timestamp when the service scan was performed. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.ip | String | The IP address of the scanned service. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.port | Number | The port number of the scanned service. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.protocol | String | The protocol used by the scanned service. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.transport_protocol | String | The transport protocol used during the service scan. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.is_success | Boolean | Whether the service scan was successful or not. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.mysql.error_code | Number | The MySQL error code returned during the scan. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.mysql.error_id | String | The MySQL error identifier returned during the scan. |
| Censys.HostEventHistory.events.resource.service_scanned.scan.mysql.error_message | String | The MySQL error message returned during the scan. |
| Censys.HostEventHistory.events.resource.forward_dns_resolved.name | String | The domain name resolved from the forward DNS lookup. |
| Censys.HostEventHistory.events.resource.forward_dns_resolved.resolve_time | String | The timestamp when the forward DNS resolution occurred. |
| Censys.HostEventHistory.events.resource.jarm_scanned.diff.additionalProp.new | String | The new value in the JARM scan difference. |
| Censys.HostEventHistory.events.resource.jarm_scanned.diff.additionalProp.old | String | The old value in the JARM scan difference. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.cipher_and_version_fingerprint | String | The cipher and version fingerprint from the JARM scan. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.fingerprint | String | The JARM fingerprint of the scanned service. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.hostname | String | The hostname used in the JARM scan. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.ip | String | The IP address scanned by JARM. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.is_success | Boolean | Whether the JARM scan was successful or not. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.port | Number | The port number scanned by JARM. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.scan_time | String | The timestamp when the JARM scan was performed. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.tls_extensions_sha256 | String | The SHA-256 hash of the TLS extensions from the JARM scan. |
| Censys.HostEventHistory.events.resource.jarm_scanned.scan.transport_protocol | String | The transport protocol used during the JARM scan. |
| Censys.HostEventHistory.events.resource.location_updated.location.city | String | The city where the host is located. |
| Censys.HostEventHistory.events.resource.location_updated.location.continent | String | The continent where the host is located. |
| Censys.HostEventHistory.events.resource.location_updated.location.coordinates.latitude | Number | The latitude coordinate of the host location. |
| Censys.HostEventHistory.events.resource.location_updated.location.coordinates.longitude | Number | The longitude coordinate of the host location. |
| Censys.HostEventHistory.events.resource.location_updated.location.country | String | The country where the host is located. |
| Censys.HostEventHistory.events.resource.location_updated.location.country_code | String | The country code where the host is located. |
| Censys.HostEventHistory.events.resource.location_updated.location.postal_code | String | The postal code of the host location. |
| Censys.HostEventHistory.events.resource.location_updated.location.province | String | The province or state where the host is located. |
| Censys.HostEventHistory.events.resource.location_updated.location.registered_country | String | The registered country of the host. |
| Censys.HostEventHistory.events.resource.location_updated.location.registered_country_code | String | The registered country code of the host. |
| Censys.HostEventHistory.events.resource.location_updated.location.timezone | String | The timezone of the host location. |
| Censys.HostEventHistory.events.resource.reverse_dns_resolved.names | String | The domain names resolved from the reverse DNS lookup. |
| Censys.HostEventHistory.events.resource.reverse_dns_resolved.resolve_time | String | The timestamp when the reverse DNS resolution occurred. |
| Censys.HostEventHistory.events.resource.route_updated.diff.additionalProp.new | String | The new value in the route update difference. |
| Censys.HostEventHistory.events.resource.route_updated.diff.additionalProp.old | String | The old value in the route update difference. |
| Censys.HostEventHistory.events.resource.route_updated.route.asn | Number | The Autonomous System Number of the route. |
| Censys.HostEventHistory.events.resource.route_updated.route.bgp_prefix | String | The BGP prefix of the route. |
| Censys.HostEventHistory.events.resource.route_updated.route.country_code | String | The country code associated with the route. |
| Censys.HostEventHistory.events.resource.route_updated.route.description | String | The description of the route. |
| Censys.HostEventHistory.events.resource.route_updated.route.name | String | The name of the route. |
| Censys.HostEventHistory.events.resource.route_updated.route.organization | String | The organization associated with the route. |
| Censys.HostEventHistory.events.resource.whois_updated.diff.additionalProp.new | String | The new value in the WHOIS update difference. |
| Censys.HostEventHistory.events.resource.whois_updated.diff.additionalProp.old | String | The old value in the WHOIS update difference. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.network.allocation_type | String | The allocation type of the network in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.network.cidrs | String | The CIDR blocks of the network in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.network.created | String | The creation timestamp of the network in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.network.handle | String | The handle identifier of the network in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.network.name | String | The name of the network in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.network.updated | String | The last update timestamp of the network in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.abuse_contacts.email | String | The email address of the abuse contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.abuse_contacts.handle | String | The handle identifier of the abuse contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.abuse_contacts.name | String | The name of the abuse contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.address | String | The address of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.admin_contacts.email | String | The email address of the admin contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.admin_contacts.handle | String | The handle identifier of the admin contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.admin_contacts.name | String | The name of the admin contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.city | String | The city of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.country | String | The country of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.handle | String | The handle identifier of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.name | String | The name of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.postal_code | String | The postal code of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.state | String | The state or province of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.street | String | The street address of the organization in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.tech_contacts.email | String | The email address of the technical contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.tech_contacts.handle | String | The handle identifier of the technical contact in WHOIS data. |
| Censys.HostEventHistory.events.resource.whois_updated.whois.organization.tech_contacts.name | String | The name of the technical contact in WHOIS data. |
| Censys.HostEventHistory.extensions | String | The extensions associated with the host event history. |
Command example
!cen-host-history-list host_id=0.0.0.1 start_time="1 week" end_time="1 day"
Context Example
{
"Censys": {
"HostEventHistory": {
"ip": "0.0.0.1",
"total_events": 8,
"partial_data": false,
"events": [
{
"resource": {
"event_time": "2026-03-01T10:00:00.000Z",
"service_scanned": {
"scan": {
"port": 443,
"protocol": "https",
"transport_protocol": "tcp"
}
}
}
},
{
"resource": {
"event_time": "2026-03-01T09:00:00.000Z",
"reverse_dns_resolved": {
"names": [
"example.com",
"www.example.com"
]
}
}
},
{
"resource": {
"event_time": "2026-03-01T08:00:00.000Z",
"endpoint_scanned": {
"scan": {
"port": 8080,
"endpoint_type": "http"
}
}
}
},
{
"resource": {
"event_time": "2026-03-01T07:00:00.000Z",
"forward_dns_resolved": {
"name": "test.example.com"
}
}
},
{
"resource": {
"event_time": "2026-03-01T06:00:00.000Z",
"jarm_scanned": {
"scan": {
"port": 443,
"fingerprint": "0000000000000000000000000000000000000000000000000000000000001"
}
}
}
},
{
"resource": {
"event_time": "2026-03-01T05:00:00.000Z",
"location_updated": {
"location": {
"city": "San Francisco",
"country": "United States"
}
}
}
},
{
"resource": {
"event_time": "2026-03-01T04:00:00.000Z",
"route_updated": {
"route": {
"asn": "15169",
"organization": "Google LLC"
}
}
}
},
{
"resource": {
"event_time": "2026-03-01T03:00:00.000Z",
"whois_updated": {
"whois": {
"organization": {
"name": "Example Organization"
}
}
}
}
}
]
}
}
}
Human Readable Output
Successfully retrieved 8 event(s) for host 0.0.0.1
Host History Events
Event Time Resource Type Resource Details Link to Censys 2026-03-01T10:00:00.000Z service_scanned 443/TCP/https View historical host on Censys platform 2026-03-01T09:00:00.000Z reverse_dns_resolved example.com View historical host on Censys platform 2026-03-01T08:00:00.000Z endpoint_scanned 8080/http View historical host on Censys platform 2026-03-01T07:00:00.000Z forward_dns_resolved test.example.com View historical host on Censys platform 2026-03-01T06:00:00.000Z jarm_scanned 443/0000000000000000000000000000000000000000000000000000000000001 View historical host on Censys platform 2026-03-01T05:00:00.000Z location_updated San Francisco/United States View historical host on Censys platform 2026-03-01T04:00:00.000Z route_updated 15169/Google LLC View historical host on Censys platform 2026-03-01T03:00:00.000Z whois_updated Example Organization View historical host on Censys platform
cen-rescan
Initiate a live rescan for a known host service at a specific IP and port (ip:port) or hostname and port (hostname:port).
Base Command
cen-rescan
Input
| Argument Name | Description | Required |
|---|---|---|
| ioc_type | Specify the type of IOC. Possible values are: Service, Web Property. Default is Service. | Required |
| ioc_value | Specify the value of IOC. | Required |
| port | Specify the port number associated with the IOC. Default is 443. | Required |
| protocol | Specify the service protocol. Note: This argument is required only if the IOC type is Service. |
Optional |
| transport_protocol | Specify the transport protocol. Note: This argument is required only if the IOC type is Service. Possible values are: Unknown, TCP, UDP, ICMP, QUIC. Default is Unknown. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.Rescan.scan_id | String | The unique identifier for the rescan operation. |
| Censys.Rescan.status | String | The status of the rescan (initiated, in_progress, completed, failed). |
| Censys.Rescan.is_completed | Boolean | Whether the rescan has completed. |
| Censys.Rescan.enrichment_data.ip | String | The IP address of the rescanned host. |
| Censys.Rescan.enrichment_data.service_count | Number | The total number of services detected on the host. |
| Censys.Rescan.enrichment_data.labels | String | Labels associated with the host. |
| Censys.Rescan.enrichment_data.location.continent | String | The continent of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.country | String | The name of the country of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.country_code | String | The two-letter ISO 3166-1 alpha-2 country code of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.city | String | The city of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.province | String | The province or state of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.postal_code | String | The postal code of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.timezone | String | The timezone of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.coordinates.latitude | Number | The latitude of the host’s detected location. |
| Censys.Rescan.enrichment_data.location.coordinates.longitude | Number | The longitude of the host’s detected location. |
| Censys.Rescan.enrichment_data.autonomous_system.asn | Number | The autonomous system number (ASN) that the host is in. |
| Censys.Rescan.enrichment_data.autonomous_system.description | String | A brief description of the autonomous system. |
| Censys.Rescan.enrichment_data.autonomous_system.bgp_prefix | String | The autonomous system’s CIDR. |
| Censys.Rescan.enrichment_data.autonomous_system.name | String | The friendly name of the autonomous system. |
| Censys.Rescan.enrichment_data.autonomous_system.country_code | String | The autonomous system’s two-letter, ISO 3166-1 alpha-2 country code. |
| Censys.Rescan.enrichment_data.whois.network.handle | String | The WHOIS network handle identifier. |
| Censys.Rescan.enrichment_data.whois.network.name | String | The WHOIS network name. |
| Censys.Rescan.enrichment_data.whois.network.cidrs | String | The WHOIS network CIDRs. |
| Censys.Rescan.enrichment_data.whois.network.created | Date | The creation date of the WHOIS network record. |
| Censys.Rescan.enrichment_data.whois.network.updated | Date | The last update date of the WHOIS network record. |
| Censys.Rescan.enrichment_data.whois.organization.handle | String | The WHOIS organization handle identifier. |
| Censys.Rescan.enrichment_data.whois.organization.name | String | The WHOIS organization name. |
| Censys.Rescan.enrichment_data.whois.organization.address | String | The WHOIS organization address. |
| Censys.Rescan.enrichment_data.whois.organization.abuse_contacts | String | The WHOIS organization abuse contacts. |
| Censys.Rescan.enrichment_data.whois.organization.admin_contacts | String | The WHOIS organization admin contacts. |
| Censys.Rescan.enrichment_data.services | String | List of services detected on the host. |
| Censys.Rescan.enrichment_data.services.port | Number | The port the service was reached at. |
| Censys.Rescan.enrichment_data.services.protocol | String | The name of the service on the port. |
| Censys.Rescan.enrichment_data.services.transport_protocol | String | The transport protocol used to contact this service. |
| Censys.Rescan.enrichment_data.services.software | String | Software identified on the service. |
| Censys.Rescan.enrichment_data.services.software.source | String | The source of the software identification. |
| Censys.Rescan.enrichment_data.services.software.confidence | Number | The confidence level of the software identification. |
| Censys.Rescan.enrichment_data.services.software.part | String | The part classification of the software in CPE format. |
| Censys.Rescan.enrichment_data.services.software.vendor | String | The vendor of the identified software. |
| Censys.Rescan.enrichment_data.services.software.product | String | The product name of the identified software. |
| Censys.Rescan.enrichment_data.services.labels | String | Labels associated with the service. |
| Censys.Rescan.enrichment_data.services.labels.value | String | The value of the service label. |
| Censys.Rescan.enrichment_data.services.threats | String | Threats detected on the service. |
| Censys.Rescan.enrichment_data.services.vulns | String | Vulnerabilities detected on the service. |
| Censys.Rescan.enrichment_data.services.ip | String | The IP address of the service. |
| Censys.Rescan.enrichment_data.services.scan_time | Date | The time when the service was scanned. |
| Censys.Rescan.enrichment_data.services.banner | String | The banner returned by the service. |
| Censys.Rescan.enrichment_data.services.banner_hash_sha256 | String | The SHA-256 hash of the service banner. |
| Censys.Rescan.enrichment_data.services.banner_hex | String | The hexadecimal representation of the service banner. |
| Censys.Rescan.enrichment_data.dns.reverse_dns.resolve_time | Date | The time when reverse DNS was resolved. |
| Censys.Rescan.enrichment_data.dns.names | String | DNS names associated with the host. |
| Censys.Rescan.enrichment_data.dns.forward_dns.names | String | Forward DNS names for the host. |
| Censys.Rescan.enrichment_data.dns.reverse_dns.names | String | Reverse DNS names for the host. |
| IP.Address | String | The IP address. |
| IP.ASN | String | The autonomous system name for the IP address, for example: “AS8948”. |
| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. |
| IP.Geo.Country | String | The country in which the IP address is located. |
| IP.Geo.Description | String | Additional information about the location. |
| IP.ASOwner | String | The autonomous system owner of the IP. |
| IP.Port | String | Ports that are associated with the IP. |
| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. |
| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. |
| Domain.Name | String | The domain name, for example: “google.com”. |
| Domain.Malicious.Vendor | String | The vendor reporting the domain as malicious. |
| Domain.Malicious.Description | String | A description explaining why the domain was reported as malicious. |
| 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
!cen-rescan ioc_type="Service" ioc_value="0.0.0.1" port="443" protocol="HTTPS" transport_protocol="TCP"
Context Example
{
"Censys": {
"Rescan": {
"ioc_value": "0.0.0.1",
"port": 443,
"status": "completed",
"scan_id": "00000000-0000-0000-0000-000000000001",
"is_completed": true,
"enrichment_data": {
"ip": "0.0.0.1",
"labels": [
{
"source": "censys",
"value": "CLOUD_PROVIDER"
},
{
"source": "censys",
"value": "WEB_SERVER"
}
],
"location": {
"continent": "Asia",
"country": "South Korea",
"country_code": "KR",
"city": "Seoul",
"postal_code": "03141",
"timezone": "Asia/Seoul",
"province": "Seoul",
"coordinates": {
"latitude": 37.566,
"longitude": 126.9784
}
},
"autonomous_system": {
"asn": 12345,
"description": "EXAMPLE-AS-AP Example.Co.LTD",
"bgp_prefix": "0.0.0.1/24",
"name": "EXAMPLE-AS-AP Example.Co.LTD",
"country_code": "KR"
},
"whois": {
"network": {
"handle": "HK-EXAMPLE-20190703",
"name": "EXAMPLE LIMITED",
"cidrs": [
"0.0.0.1/24"
],
"created": "2024-11-26T00:00:00Z",
"updated": "2025-08-18T00:00:00Z"
},
"organization": {
"handle": "ORG-XL117-RIPE",
"name": "EXAMPLE LIMITED",
"address": "RM 29-33,5/F,EXAMPLE COMMERCIAL CENTRE,87-105 EXAMPLE ROAD\\n000000\\nEXAMPLE CITY\\nEXAMPLE COUNTRY",
"abuse_contacts": [
{
"handle": "EXAMPLE-RIPE",
"name": "EXAMPLE-ROLE",
"email": "noc@example.com"
}
],
"admin_contacts": [
{
"handle": "EXAMPLE-RIPE",
"name": "EXAMPLE-ROLE",
"email": "noc@example.com"
}
]
}
},
"services": [
{
"port": 22,
"protocol": "SSH",
"transport_protocol": "tcp",
"software": [
{
"source": "censys",
"confidence": 0.9,
"evidence": [
{
"data_path": "protocol",
"found_value": "SSH",
"literal_match": "SSH"
}
],
"type": [
"REMOTE_ACCESS"
],
"part": "a"
}
],
"labels": [
{
"source": "censys",
"confidence": 0.9,
"evidence": [
{
"data_path": "protocol",
"found_value": "SSH",
"literal_match": "SSH"
}
],
"value": "REMOTE_ACCESS"
}
],
"threats": [
{
"name": "BRUTE_FORCE_ATTACK",
"source": "censys"
}
],
"vulns": [
{
"id": "CVE-2023-12345",
"cvss": 7.5,
"severity": "HIGH"
},
{
"id": "CVE-2023-67890",
"cvss": 5.3,
"severity": "MEDIUM"
}
],
"ip": "0.0.0.1",
"scan_time": "2026-02-02T00:46:23Z",
"banner": "SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3",
"banner_hash_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
"banner_hex": "5353482d322e302d4f70656e5353485f392e3270312044656269616e2d322b64656231327533",
"ja4tscan": {
"scan_time": "2026-02-01T17:09:57Z",
"fingerprint": "65160_2-4-8-1-3_1460_7_1-2-4-8-16"
},
"ssh": {
"endpoint_id": {
"raw": "SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3",
"protocol_version": "2.0",
"software_version": "OpenSSH_9.2p1",
"comment": "Debian-2+deb12u3"
},
"kex_init_message": {
"kex_algorithms": [
"example@openssh.com",
"curve25519-sha256",
"example@openssh.com"
],
"host_key_algorithms": [
"rsa-sha2-512",
"rsa-sha2-256",
"ecdsa-sha2-nistp256",
"ssh-ed25519"
],
"client_to_server_ciphers": [
"example@openssh.com",
"aes128-ctr"
],
"server_to_client_ciphers": [
"example@openssh.com",
"aes128-ctr"
],
"client_to_server_macs": [
"example@openssh.com",
"example@openssh.com"
],
"server_to_client_macs": [
"example@openssh.com",
"example@openssh.com"
],
"client_to_server_compression": [
"none",
"example@openssh.com"
],
"server_to_client_compression": [
"none",
"example@openssh.com"
]
},
"algorithm_selection": {
"kex_algorithm": "example@libssh.org",
"host_key_algorithm": "ecdsa-sha2-nistp256",
"client_to_server_cipher": "example@openssh.com",
"server_to_client_cipher": "example@openssh.com",
"client_to_server_mac": "example@openssh.com",
"server_to_client_mac": "example@openssh.com",
"client_to_server_compression": "none",
"server_to_client_compression": "none"
},
"server_host_key": {
"ecdsa_public_key": {
"b": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"curve": "P256",
"gx": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"gy": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"length": 256,
"n": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"p": "/////wAAAAEAAAAAAAAAAAAAAAD///////////////8=",
"x": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"y": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
}
},
"hassh_fingerprint": "00000000000000000000000000000000"
}
}
],
"service_count": 3,
"dns": {
"names": [
"example.com",
"www.example.com"
],
"forward_dns": {
"names": [
"example.com",
"www.example.com",
"mail.example.com"
]
},
"reverse_dns": {
"names": [
"host.example.com"
],
"resolve_time": "2026-01-30T18:11:14Z"
}
}
}
}
}
}
Human Readable Output
Scan completed successfully for 0.0.0.1:443
Enriched Host Data
IP Labels Service Count Service Ports Service Protocols Service Transport Protocols Service Labels Service Vulns Service Threats Service Scan Times DNS Names Forward DNS Names Reverse DNS Names Network Name CIDRs Autonomous System Name Autonomous System ASN City Province Postal Code Country Country Code Continent Latitude Longitude 0.0.0.1 CLOUD_PROVIDER, WEB_SERVER 3 22 SSH tcp REMOTE_ACCESS CVE-2023-12345, CVE-2023-67890 BRUTE_FORCE_ATTACK 2026-02-02T00:46:23Z example.com, www.example.com example.com, www.example.com, mail.example.com host.example.com EXAMPLE LIMITED 0.0.0.1/24 EXAMPLE-AS-AP Example.Co.LTD 12345 Seoul Seoul 03141 South Korea KR Asia 37.566 126.9784
cen-related-infrastructure-list
Initiate a CensEye (Related Infrastructure) pivot analysis job for a Host, Web Property, or SHA256 Certificate.
Base Command
cen-related-infrastructure-list
Input
| Argument Name | Description | Required |
|---|---|---|
| ioc_type | Specify the type of IOC. Possible values are: Host, Web Property, Certificate. Default is Host. | Required |
| ioc_value | Specify the value of IOC. Note: For Web Property IOC type, include the port in the format hostname:port (e.g., example.com:443). |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Censys.RelatedInfrastructure.job_id | String | The unique identifier for the related infrastructure job. |
| Censys.RelatedInfrastructure.pivot_data.count | Number | The count of related infrastructure entries for this pivot. |
| Censys.RelatedInfrastructure.pivot_data.field_value_pairs.field | String | The field name of the pivot. |
| Censys.RelatedInfrastructure.pivot_data.field_value_pairs.value | String | The value of the pivot field. |
| Censys.RelatedInfrastructure.status | String | The status of the job (initiated, in_progress, completed, failed). |
| Censys.RelatedInfrastructure.is_completed | Boolean | Whether the job has completed. |
| Censys.RelatedInfrastructure.ioc_value | String | The value of the IOC. |
Command example
!cen-related-infrastructure-list ioc_type="Host" ioc_value="0.0.0.1"
Context Example
{
"Censys": {
"RelatedInfrastructure": {
"ioc_value": "0.0.0.1",
"status": "completed",
"job_id": "00000000-0000-0000-0000-000000000001",
"is_completed": true,
"pivot_data": [
{
"count": 5395,
"field_value_pairs": [
{
"field": "host.services.banner_hash_sha256",
"value": "0000000000000000000000000000000000000000000000000000000000000001"
}
]
},
{
"count": 123620,
"field_value_pairs": [
{
"field": "host.services.endpoints.http.headers.key",
"value": "Connection"
},
{
"field": "host.services.endpoints.http.headers.value",
"value": "close"
}
]
},
{
"count": 5395,
"field_value_pairs": [
{
"field": "host.services.endpoints.banner_hash_sha256",
"value": "0000000000000000000000000000000000000000000000000000000000000001"
}
]
},
{
"count": 36216,
"field_value_pairs": [
{
"field": "host.services.endpoints.http.headers.key",
"value": "Content-Type"
},
{
"field": "host.services.endpoints.http.headers.value",
"value": "text/plain"
}
]
}
]
}
}
}
Human Readable Output
Job completed successfully for 0.0.0.1
4 Pivots Data
Key Value Count See results in Censys host.services.banner_hash_sha256 0000000000000000000000000000000000000000000000000000000000000001 5395 View Pivot Information on Censys platform host.services.endpoints.banner_hash_sha256 0000000000000000000000000000000000000000000000000000000000000001 5395 View Pivot Information on Censys platform host.services.endpoints.http.headers.key
host.services.endpoints.http.headers.valueContent-Type
text/plain36216 View Pivot Information on Censys platform host.services.endpoints.http.headers.key
host.services.endpoints.http.headers.valueConnection
close123620 View Pivot Information on Censys platform
Configuration parameters
server_url— Server URL (required)api_token— (required)organization_id— Organization ID (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingspremium_access— Determine IP score by labels (for paid subscribers)malicious_labels— IP Malicious labelssuspicious_labels— IP suspicious labelsmalicious_labels_threshold— Malicious labels thresholdsuspicious_labels_threshold— Suspicious labels thresholdintegration_reliability— Source Reliability
Commands (7)
-
cen-host-history-listRetrieve the event history for a host (IP address).
-
cen-related-infrastructure-listInitiate a CensEye (Related Infrastructure) pivot analysis job for a Host, Web Property, or SHA256 Certificate.
-
cen-rescanInitiate a live rescan for a known host service at a specific IP and port (ip:port) or hostname and port (hostname:port).
-
cen-searchReturn previews of hosts matching a specified search query or a list of certificates that match the given query.
-
cen-viewReturns detailed information for an IP address or SHA256 within the specified index.
-
domainReturn all related IPs as relationships.
-
ipRuns reputation on IPs.
from collections.abc import Callable from typing import Any import demistomock as demisto import urllib3 from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa # Disable insecure warnings urllib3.disable_warnings() # pylint: disable=no-member TOTAL_RETRIES = 4 STATUS_CODE_TO_RETRY = (429, *(status_code for status_code in requests.status_codes._codes if status_code >= 500)) # type: ignore OK_CODES = (200, 201) BACKOFF_FACTOR = 7.5 # Sleep for [0s, 15s, 30s, 60s] between retries. DATE_FORMAT: str = "%Y-%m-%dT%H:%M:%S.000Z" PACK_VERSION = get_pack_version() or "3.1.0" DEMISTO_XSOAR_VERSION = get_demisto_version_as_str().split("-")[0] CONNECTOR_NAME_VERSION = f"CensysXSOAR/{PACK_VERSION} (XSOAR/{DEMISTO_XSOAR_VERSION}; ts={int(time.time())})" ENDPOINTS = { "HOST_EVENT_HISTORY": "v3/global/asset/host/{}/timeline", "INITIATE_RESCAN": "v3/global/scans/rescan", "RESCAN_STATUS": "v3/global/scans/{}", "INITIATE_JOB": "v3/threat-hunting/censeye/jobs", "JOB_STATUS": "v3/threat-hunting/censeye/jobs/{}", "JOB_RESULTS": "v3/threat-hunting/censeye/jobs/{}/results", } ERRORS = { "INVALID_OBJECT": "Failed to parse {} object from response: {}", "REQUIRED_ARGUMENT": "Please provide a valid value for the '{}'. It is required field.", "INVALID_TIME_RANGE": "Invalid time range: '{}' ({}) must be earlier than '{}' ({}).", "INVALID_IP": "Invalid IP address: {}", "INVALID_SELECT": "'{}' is an invalid value for '{}'. Value must be in {}.", "INVALID_PORT": "{} is an invalid value for the port. The port must be between {} to {}.", } HR_SUFFIX = { "HOST_EVENT_HISTORY": "/hosts/{}?at_time={}", "HOST_ALL_EVENTS": "/hosts/{}/events", } OUTPUT_PREFIX = { "HOST_EVENT_HISTORY": "Censys.HostEventHistory", "INITIATE_RESCAN": "Censys.Rescan", "RELATED_INFRASTRUCTURE": "Censys.RelatedInfrastructure", } DEFAULT_PAGE_SIZE = 100 MAX_NUMBER_OF_RECORDS = 1000 MAX_NUMBER_OF_PAGES = 10 CENSYS_API_URL = "https://api.platform.censys.io" CENSYS_PLATFORM_URL = "https://platform.censys.io" DEFAULT_TIMEOUT_THRESHOLD_SECONDS = 240 # 4 minutes in seconds DEFAULT_VALUE_NA = "N/A" INTEGRATION_NAME = "Censys" DEFAULT_POLLING_INTERVAL = 10 # 10 seconds DEFAULT_POLLING_TIMEOUT = 630 # 10 minutes 30 seconds DEFAULT_PORTS = [80, 443] DEFAULT_TRANSPORT_PROTOCOL = "Unknown" MIN_PORT = 1 MAX_PORT = 65535 VALID_IOC_TYPE = {"service": "Service", "web property": "Web Property"} VALID_TRANSPORT_PROTOCOL = {"unknown": "Unknown", "tcp": "TCP", "udp": "UDP", "icmp": "ICMP", "quic": "QUIC"} VALID_RELATED_INFRA_IOC_TYPE = {"host": "Host", "web property": "Web Property", "certificate": "Certificate"} class Client(BaseClient): def __init__(self, base_url: str, api_token: str, org_id: str | None = None, verify: bool = True, proxy: bool = False): """ Initialize the Censys Client. Args: base_url: The base URL for the Censys API api_token: The API token for authentication org_id: Organization ID for multi-org accounts verify: Whether to verify SSL certificates proxy: Whether to use proxy settings """ self.org_id = org_id # Build headers for v3 API headers = {"Authorization": f"Bearer {api_token}", "User-Agent": CONNECTOR_NAME_VERSION} super().__init__(base_url=base_url, headers=headers, verify=verify, proxy=proxy) def http_request( self, method: str, url_suffix: str, params: Union[dict[str, Any], list[tuple[str, Any]]] = None, data: dict[str, Any] = None, json_data: dict[str, Any] = None, response_type: str = "json", **kwargs, ) -> dict[str, Any]: """Makes an HTTP request to the Censys API with automatic retry logic. This method wraps the BaseClient._http_request with Censys-specific configuration including retry logic for transient failures (429, 5xx errors) and automatic response parsing based on the requested response_type. Args: method: The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE'). url_suffix: The URL suffix to be appended to the base URL. Defaults to empty string. params: Query parameters to be appended to the URL. Defaults to None. data: Form data to be sent in the request body. Defaults to None. json_data: JSON data to be sent in the request body. Defaults to None. response_type: The expected response type. Options: 'json', 'content', 'response', 'text'. Defaults to 'json'. **kwargs: Additional keyword arguments passed to _http_request. Returns: Parsed response based on response_type: - 'json': Parsed JSON dict - 'content': Raw bytes content - 'response': Raw Response object - 'text': Response text string Returns None if response parsing fails. Raises: DemistoException: If response parsing fails or if the API returns an error status. Note: Automatically retries up to TOTAL_RETRIES (4) times for rate limit (429) and server errors (5xx) with exponential backoff (BACKOFF_FACTOR=7.5). """ demisto.debug(f"Making API request at {method} {url_suffix} with params: {params} and body: {data or json_data}") # Make the HTTP request using the _http_request method, passing the necessary parameters. res = self._http_request( method=method, url_suffix=url_suffix, data=data, json_data=json_data, params=params, retries=TOTAL_RETRIES, status_list_to_retry=STATUS_CODE_TO_RETRY, ok_codes=OK_CODES, backoff_factor=BACKOFF_FACTOR, resp_type="response", raise_on_status=True, **kwargs, ) try: result = None if response_type == "json": result = res.json() if response_type == "content": result = res.content if response_type == "response": result = res if response_type == "text": result = res.text except ValueError as exception: raise DemistoException(ERRORS["INVALID_OBJECT"].format(response_type, res.text), exception, res) return result # type: ignore def censys_view_request(self, index: str, query: str) -> dict: if index == "ipv4": asset_type = "host" elif index == "webproperty": asset_type = "webproperty" else: asset_type = "certificate" demisto.debug(f"censys_view_request: index={index}, query={query}, asset_type={asset_type}") params = {"organization_id": self.org_id} result = self.http_request("GET", f"/v3/global/asset/{asset_type}/{query}", params=params) return result def censys_search_request( self, query: str, page_size: int | None = None, fields: list | None = None, page_token: str | None = None ) -> dict: """ Execute a single search query request. Args: query: The search query string page_size: Number of results per page fields: List of fields to return page_token: Token for pagination (to get next page) Returns: API response dictionary """ url_suffix = "/v3/global/search/query" data = assign_params(query=query, page_size=page_size, fields=fields, page_token=page_token) demisto.debug(f"censys_search_request: query={query}, page_size={page_size}, page_token={page_token}") params = {"organization_id": self.org_id} return self.http_request("POST", url_suffix, json_data=data, params=params) def censys_host_history_request(self, ip_address: str, start_time: str, end_time: str) -> dict: """Fetch host event history from the Censys API. The Censys API uses reversed time semantics for the timeline endpoint: - API start_time = newer/closer to now (user's end_time) - API end_time = older/further back (user's start_time) This method automatically reverses the provided times when making the API call. Args: ip_address: The IP address of the host to retrieve history for. start_time: Start time from the past (RFC3339 format) - will be reversed to API end_time. end_time: End time near current (RFC3339 format) - will be reversed to API start_time. Returns: Response object from the API containing host event history for the specified time range. """ url_suffix = ENDPOINTS["HOST_EVENT_HISTORY"].format(ip_address) # Reverse the times for API call (API expects reverse chronological order) # User's end_time (recent) -> API start_time (newer) # User's start_time (past) -> API end_time (older) data = assign_params(start_time=end_time, end_time=start_time, organization_id=self.org_id) return self.http_request("GET", url_suffix, params=data) def censys_initiate_rescan_request( self, ioc_type: str, ioc_value: str, port: int | None, protocol: str, transport_protocol: str ) -> dict: """Initiate a rescan for a host service. Args: ioc_type: IOC type (service or web property). ioc_value: IP address of the host. port: Port number. protocol: Service protocol. transport_protocol: Transport protocol (TCP, UDP, etc.). Returns: API response containing scan ID and status """ url_suffix = ENDPOINTS["INITIATE_RESCAN"] if ioc_type.lower() == "service": body = { "target": { "service_id": { "ip": ioc_value, "port": port, "protocol": protocol, "transport_protocol": transport_protocol.lower(), } } } else: body = { "target": { "web_origin": { "hostname": ioc_value, "port": port, } } } params = assign_params(organization_id=self.org_id) return self.http_request("POST", url_suffix, json_data=body, params=params) def censys_rescan_status_request(self, scan_id: str) -> dict: """Get the status of a rescan. Args: scan_id: The tracked scan ID Returns: API response containing scan status """ url_suffix = ENDPOINTS["RESCAN_STATUS"].format(scan_id) params = assign_params(organization_id=self.org_id) demisto.debug(f"censys_rescan_status_request: scan_id={scan_id}") return self.http_request("GET", url_suffix, params=params) def censys_initiate_job_request(self, ioc_type: str, ioc_value: str) -> dict: """Initiate a CensEye related infrastructure job. Args: ioc_type: IOC type (Host, Web Property, or Certificate). ioc_value: The IOC value (IP for Host, hostname:port for Web Property, or certificate SHA-256 for Certificate). Returns: API response containing job ID and status. """ url_suffix = ENDPOINTS["INITIATE_JOB"] ioc_type = ioc_type.replace(" ", "") body = {"target": {f"{ioc_type}_id": ioc_value}} params = assign_params(organization_id=self.org_id) return self.http_request("POST", url_suffix, json_data=body, params=params) def censys_job_status_request(self, job_id: str) -> dict: """Get the status of a CensEye job. Args: job_id: The job ID. Returns: API response containing job status. """ url_suffix = ENDPOINTS["JOB_STATUS"].format(job_id) params = assign_params(organization_id=self.org_id) return self.http_request("GET", url_suffix, params=params) def censys_job_results_request(self, job_id: str) -> dict: """Get the results of a completed CensEye job. Args: job_id: The job ID. Returns: API response containing pivot data results. """ url_suffix = ENDPOINTS["JOB_RESULTS"].format(job_id) params = assign_params(organization_id=self.org_id, page_size=DEFAULT_PAGE_SIZE) return self.http_request("GET", url_suffix, params=params) """ HELPER FUNCTIONS """ def censys_search_with_pagination( client: Client, query: str, page_size: int | None = None, fields: list | None = None, limit: int | None = None ) -> dict: """ Execute a search query with automatic pagination. This function handles pagination automatically by fetching multiple pages until either all results are retrieved or the limit is reached. Args: client: The Censys client instance query: The search query string page_size: Number of results per page (default: 50, max: 100) fields: List of fields to return limit: Maximum total number of results to return across all pages Returns: Dictionary with 'result' containing all hits and metadata: { "result": { "hits": [...], # All collected hits "total_hits": int, # Total available results "next_page_token": str, # Token for next page (if any) "previous_page_token": str, # Token for previous page (if any) "query_duration_millis": int # Query duration } } """ # Determine initial page size if page_size is None: page_size = 100 if limit and limit < page_size: page_size = limit all_hits = [] page_token = None total_fetched = 0 total_hits = None last_result = {} # Pagination loop demisto.debug(f"censys_search_with_pagination: starting pagination for query={query}, limit={limit}") while True: # Make API request for current page response = client.censys_search_request(query, page_size, fields, page_token) result = response.get("result", {}) hits = result.get("hits", []) # Store metadata from first response if total_hits is None: total_hits = result.get("total_hits") # Keep last result for metadata last_result = result # If no hits, break if not hits: break # Add hits to collection all_hits.extend(hits) total_fetched += len(hits) # Check for next page token (it's directly in result, not in links) next_page_token = result.get("next_page_token") # Stop if no more pages or reached limit if not next_page_token or (limit and total_fetched >= limit): break # Update for next iteration page_token = next_page_token # Adjust page_size if approaching limit if limit: remaining = limit - total_fetched if remaining < page_size: page_size = remaining demisto.debug(f"censys_search_with_pagination: finished pagination. total_fetched={total_fetched}, total_hits={total_hits}") # Trim to exact limit if specified if limit and len(all_hits) > limit: all_hits = all_hits[:limit] # Return response in same format as single request return { "result": { "hits": all_hits, "total_hits": total_hits, "next_page_token": last_result.get("next_page_token"), "previous_page_token": last_result.get("previous_page_token"), "query_duration_millis": last_result.get("query_duration_millis"), } } def handle_exceptions(e: Exception, results: list[CommandResults], execution_metrics: ExecutionMetrics, item: str): demisto.debug(f"handle_exceptions: item={item}, error={str(e)}") status_code = 0 message = str(e) if isinstance(e, DemistoException) and e.res is not None: status_code = e.res.status_code message = e.message if status_code == 403 and "quota" in message: # Handle quota exceeded error execution_metrics.quota_error += 1 results.append(CommandResults(readable_output=f"Quota exceeded. Error: {message}")) return True elif status_code == 429: # Handle rate limits error execution_metrics.general_error += 1 results.append(CommandResults(readable_output=f"Too many requests. Error: {message}")) return True elif status_code == 403 and "specific fields" in message: # Handle non-premium access error raise DemistoException( "Your user does not have permission for premium features. " "Please ensure that you deselect the 'Labels premium feature available' option " f"for non-premium access. Error: {message}" ) elif status_code == 401 or status_code == 403: # Handle unauthorized access error raise e else: # Handle general error execution_metrics.general_error += 1 error_msg = f"An error occurred for item: {item}. Error: {message}" results.append(CommandResults(readable_output=error_msg)) return False def get_dbot_score(params: dict, result_labels: list): malicious_labels = set(argToList(params.get("malicious_labels", []))) suspicious_labels = set(argToList(params.get("suspicious_labels", []))) malicious_threshold = arg_to_number(params.get("malicious_labels_threshold")) or 0 suspicious_threshold = arg_to_number(params.get("suspicious_labels_threshold")) or 0 num_malicious = len(malicious_labels.intersection(result_labels)) if num_malicious >= malicious_threshold and num_malicious > 0: matched_labels = sorted(malicious_labels.intersection(result_labels)) description = f"Matched malicious labels: {', '.join(matched_labels)}" return Common.DBotScore.BAD, description num_suspicious = len(suspicious_labels.intersection(result_labels)) if num_suspicious >= suspicious_threshold and num_suspicious > 0: matched_labels = sorted(suspicious_labels.intersection(result_labels)) description = f"Matched suspicious labels: {', '.join(matched_labels)}" return Common.DBotScore.SUSPICIOUS, description return Common.DBotScore.NONE, None def trim_spaces_from_args(args: dict) -> dict: """Trim leading/trailing spaces from argument values. For string values, removes leading and trailing whitespace. Args: args: Dictionary of command arguments to process. Returns: The same dictionary with trimmed values (modifies in-place and returns). Example: >>> trim_spaces_from_args({'key': ' value '}) {'key': 'value'} """ for key, val in args.items(): if isinstance(val, str): args[key] = val.strip() return args def validate_required_argument(value: Any, name: str) -> Any: """ Check if empty string is passed as value for argument and raise appropriate ValueError. Args: value: Value of the argument. name: Name of the argument. Returns: str: Value of the argument. Raises: ValueError: If the value is empty string. """ if not value: raise ValueError(ERRORS["REQUIRED_ARGUMENT"].format(name)) return value def prepare_hr_for_host_history_list_command(events: list[dict], ip_address: str) -> str: """Prepare human-readable markdown output for host history events. Args: events: List of event dictionaries from the Censys API response. ip_address: The IP address of the host (used in summary message and links). Returns: Formatted markdown string with summary heading, event table, and optional note about record caps with link to Censys platform. """ hr_data = [] for event in events: resource = event.get("resource", {}) event_time = resource.get("event_time", DEFAULT_VALUE_NA) resource_type = DEFAULT_VALUE_NA resource_details = DEFAULT_VALUE_NA if "service_scanned" in resource: resource_type = "service_scanned" port = demisto.get(resource, f"{resource_type}.scan.port", DEFAULT_VALUE_NA) protocol = demisto.get(resource, f"{resource_type}.scan.protocol", DEFAULT_VALUE_NA) transport = demisto.get(resource, f"{resource_type}.scan.transport_protocol", DEFAULT_VALUE_NA).upper() resource_details = f"{port}/{transport}/{protocol}" elif "reverse_dns_resolved" in resource: resource_type = "reverse_dns_resolved" names = demisto.get(resource, f"{resource_type}.names", []) resource_details = names[0] if names else DEFAULT_VALUE_NA elif "endpoint_scanned" in resource: resource_type = "endpoint_scanned" port = demisto.get(resource, f"{resource_type}.scan.port", DEFAULT_VALUE_NA) endpoint_type = demisto.get(resource, f"{resource_type}.scan.endpoint_type", DEFAULT_VALUE_NA) resource_details = f"{port}/{endpoint_type}" elif "forward_dns_resolved" in resource: resource_type = "forward_dns_resolved" name = demisto.get(resource, f"{resource_type}.name", DEFAULT_VALUE_NA) resource_details = name elif "jarm_scanned" in resource: resource_type = "jarm_scanned" port = demisto.get(resource, f"{resource_type}.scan.port", DEFAULT_VALUE_NA) fingerprint = demisto.get(resource, f"{resource_type}.scan.fingerprint", DEFAULT_VALUE_NA) resource_details = f"{port}/{fingerprint}" elif "location_updated" in resource: resource_type = "location_updated" city = demisto.get(resource, f"{resource_type}.location.city", DEFAULT_VALUE_NA) country = demisto.get(resource, f"{resource_type}.location.country", DEFAULT_VALUE_NA) resource_details = f"{city}/{country}" elif "route_updated" in resource: resource_type = "route_updated" asn = demisto.get(resource, f"{resource_type}.route.asn", DEFAULT_VALUE_NA) organization = demisto.get(resource, f"{resource_type}.route.organization", DEFAULT_VALUE_NA) resource_details = f"{asn}/{organization}" elif "whois_updated" in resource: resource_type = "whois_updated" org_name = demisto.get(resource, f"{resource_type}.whois.organization.name", DEFAULT_VALUE_NA) resource_details = org_name platform_url = f"{CENSYS_PLATFORM_URL}{HR_SUFFIX['HOST_EVENT_HISTORY'].format(ip_address, event_time)}" hr_data.append( { "Event Time": event_time, "Resource Type": resource_type, "Resource Details": resource_details, "Link to Censys": f"[View historical host on Censys platform]({platform_url})", } ) hr_output = tableToMarkdown( "Host History Events", hr_data, headers=["Event Time", "Resource Type", "Resource Details", "Link to Censys"], removeNull=True, ) return hr_output def validate_port_argument(port: int) -> int: """Validate that the port number is within the valid range. Args: port: Port number to validate Returns: Validated port number Raises: ValueError: If port is not between MIN_PORT and MAX_PORT (1-65535) """ if port < MIN_PORT or port > MAX_PORT: raise ValueError(ERRORS["INVALID_PORT"].format(port, MIN_PORT, MAX_PORT)) return port def validate_rescan_command_args(ioc_type: str, ioc_value: str, port: int | None, protocol: str, transport_protocol: str) -> None: """Validate arguments for the rescan command. Args: ioc_type: IOC type to validate ioc_value: IP address to validate port: Port number to validate protocol: Service protocol to validate transport_protocol: Transport protocol to validate Raises: ValueError: If any argument is invalid """ ioc_type = validate_required_argument(ioc_type, "ioc_type") if ioc_type.lower() not in VALID_IOC_TYPE: raise ValueError(ERRORS["INVALID_SELECT"].format(ioc_type, "ioc_type", ", ".join(VALID_IOC_TYPE.values()))) ioc_value = validate_required_argument(ioc_value, "ioc_value") if ioc_type.lower() == "service": if not is_ip_valid(ioc_value, accept_v6_ips=True): raise ValueError(ERRORS["INVALID_IP"].format(ioc_value)) if not protocol: raise ValueError("Protocol is required when IOC Type is Service.") if transport_protocol.lower() not in VALID_TRANSPORT_PROTOCOL: raise ValueError( ERRORS["INVALID_SELECT"].format( transport_protocol, "transport_protocol", ", ".join(VALID_TRANSPORT_PROTOCOL.values()) ) ) port = validate_required_argument(port, "port") validate_port_argument(port) def validate_related_infra_command_args(ioc_type: str, ioc_value: str) -> None: """Validate arguments for the related infrastructure command. Args: ioc_type: IOC type to validate (Host, Web Property, Certificate) ioc_value: IOC value to validate (for Web Property, should include port as hostname:port) Raises: ValueError: If any argument is invalid """ ioc_type = validate_required_argument(ioc_type, "ioc_type") if ioc_type.lower() not in VALID_RELATED_INFRA_IOC_TYPE: raise ValueError(ERRORS["INVALID_SELECT"].format(ioc_type, "ioc_type", ", ".join(VALID_RELATED_INFRA_IOC_TYPE.values()))) ioc_value = validate_required_argument(ioc_value, "ioc_value") if ioc_type.lower() == "host" and not is_ip_valid(ioc_value, accept_v6_ips=True): raise ValueError(ERRORS["INVALID_IP"].format(ioc_value)) if ioc_type.lower() == "web property": # Validate that ioc_value includes port (format: hostname:port) if ":" not in ioc_value: raise ValueError("For Web Property IOC type, ioc_value must include port in the format hostname:port") parts = ioc_value.rsplit(":", 1) if len(parts) != 2: raise ValueError("For Web Property IOC type, ioc_value must include port in the format hostname:port") port = int(parts[1]) validate_port_argument(port) def prepare_hr_for_ip_resource(resources: list[dict] | dict) -> str: """Prepare human-readable output for IP resource(s). Args: resources: The host resource data from Censys API (single dict or list of dicts) params: Integration parameters Returns: Human-readable output string """ # Handle both single resource and list of resources if isinstance(resources, dict): resources = [resources] hr_data = [] for resource in resources: ioc_value = resource.get("ip") # Location data city = demisto.get(resource, "location.city") province = demisto.get(resource, "location.province") postal = demisto.get(resource, "location.postal_code") country_code = demisto.get(resource, "location.country_code") country = demisto.get(resource, "location.country") continent = demisto.get(resource, "location.continent") lat = demisto.get(resource, "location.coordinates.latitude") lon = demisto.get(resource, "location.coordinates.longitude") asn = demisto.get(resource, "autonomous_system.asn") asn_name = demisto.get(resource, "autonomous_system.name") # Labels and scoring labels_list = [label.get("value") for label in resource.get("labels", []) if label.get("value")] labels_str = ", ".join(labels_list) if labels_list else "" # DNS information dns_names = demisto.get(resource, "dns.names", []) forward_dns_names = demisto.get(resource, "dns.forward_dns.names", []) reverse_dns_names = demisto.get(resource, "dns.reverse_dns.names", []) # WHOIS information whois_network_name = demisto.get(resource, "whois.network.name") whois_cidrs = demisto.get(resource, "whois.network.cidrs", []) # Aggregate service information services = resource.get("services", []) service_ports = [] service_protocols = [] service_transport_protocols = [] all_service_labels = [] all_service_vulns = [] all_service_threats = [] service_scan_times = [] for service in services: if service.get("port"): service_ports.append(str(service.get("port"))) if service.get("protocol"): service_protocols.append(service.get("protocol")) if service.get("transport_protocol"): service_transport_protocols.append(service.get("transport_protocol")) service_labels = [label.get("value") for label in service.get("labels", []) if label.get("value")] all_service_labels.extend(service_labels) threats = [threat.get("name") for threat in service.get("threats", []) if threat.get("name")] all_service_threats.extend(threats) vulns = service.get("vulns", []) vuln_ids = [vuln.get("id") for vuln in vulns if vuln.get("id")] if vuln_ids: all_service_vulns.append(", ".join(vuln_ids)) service_scan_time = service.get("scan_time") if service_scan_time: service_scan_times.append(service_scan_time) # Build comprehensive human-readable content hr_content = { "IP": ioc_value, "Labels": labels_str, "Service Count": resource.get("service_count"), "Service Ports": ", ".join(service_ports), "Service Protocols": ", ".join(service_protocols), "Service Transport Protocols": ", ".join(service_transport_protocols), "Service Labels": ", ".join(all_service_labels), "Service Vulns": ", ".join(all_service_vulns), "Service Threats": ", ".join(all_service_threats), "Service Scan Times": ", ".join(service_scan_times), "DNS Names": ", ".join(dns_names), "Forward DNS Names": ", ".join(forward_dns_names), "Reverse DNS Names": ", ".join(reverse_dns_names), "Network Name": whois_network_name, "CIDRs": ", ".join(whois_cidrs), "Autonomous System Name": asn_name, "Autonomous System ASN": asn, "City": city, "Province": province, "Postal Code": postal, "Country": country, "Country Code": country_code, "Continent": continent, "Latitude": lat, "Longitude": lon, } hr_data.append(hr_content) human_readable = tableToMarkdown("Enriched Host Data", hr_data, removeNull=True, sort_headers=False) return human_readable def prepare_hr_for_web_property_resource(resources: list[dict] | dict) -> str: """Prepare human-readable output for web property resource(s). Args: resources: The web property resource data from Censys API (single dict or list of dicts) Returns: Human-readable output string """ # Handle both single resource and list of resources if isinstance(resources, dict): resources = [resources] hr_data = [] for resource in resources: hostname = resource.get("hostname", "") port = resource.get("port", "") scan_time = resource.get("scan_time", "") # Endpoints information endpoints = resource.get("endpoints", []) endpoint_types = ", ".join([str(ep.get("endpoint_type", "")) for ep in endpoints if ep.get("endpoint_type")]) endpoint_paths = ", ".join([str(ep.get("path", "")) for ep in endpoints if ep.get("path")]) # Labels and scoring labels_list = [label.get("value") for label in resource.get("labels", []) if label.get("value")] labels_str = ", ".join(labels_list) if labels_list else "" # Threats information threats = resource.get("threats", []) threat_names = ", ".join([threat.get("name") for threat in threats if threat.get("name")]) # Vulnerabilities information vulns = resource.get("vulns", []) vulns_names = ", ".join([vuln.get("id") or vuln.get("name") for vuln in vulns if vuln.get("id") or vuln.get("name")]) # Software information software_list = resource.get("software", []) vendors = ", ".join([str(sw.get("vendor", "")) for sw in software_list if sw.get("vendor")]) products = ", ".join([str(sw.get("product", "")) for sw in software_list if sw.get("product")]) versions = ", ".join([str(sw.get("version", "")) for sw in software_list if sw.get("version")]) # Certificate information cert = resource.get("cert", {}) sha256 = cert.get("fingerprint_sha256", "") subject_dn = demisto.get(cert, "parsed.subject_dn", "") issuer_dn = demisto.get(cert, "parsed.issuer_dn", "") common_name = demisto.get(cert, "parsed.subject.common_name", "") not_before = demisto.get(cert, "parsed.validity_period.not_before", "") not_after = demisto.get(cert, "parsed.validity_period.not_after", "") self_signed = demisto.get(cert, "parsed.signature.self_signed", "") # Build comprehensive human-readable content hr_content = { "Hostname": hostname, "Port": port, "Scan Time": scan_time, "Endpoint Types": endpoint_types, "Endpoint Paths": endpoint_paths, "Labels": labels_str, "Threat Names": threat_names, "Vulns Names": vulns_names, "Vendors": vendors, "Products": products, "Versions": versions, "sha256": sha256, "Self Signed": self_signed, "Subject DN": subject_dn, "Issuer DN": issuer_dn, "Common Names": common_name, "Not Before": not_before, "Not After": not_after, } hr_data.append(hr_content) human_readable = tableToMarkdown("Enriched Web Property Data", hr_data, removeNull=True, sort_headers=False) return human_readable def prepare_hr_for_pivot_information(pivot_data: list[dict[str, Any]]) -> str: """Prepare human-readable output for pivot information command.""" hr_data = [] for pivot in pivot_data: count = pivot.get("count", 0) field_value_pairs = pivot.get("field_value_pairs", []) fields = "\n".join(fvp.get("field", "") for fvp in field_value_pairs) values = "\n".join(fvp.get("value", "") for fvp in field_value_pairs) # Check if this is a header field pattern (2 pairs with .key and .value) is_header_pattern = ( len(field_value_pairs) == 2 and field_value_pairs[0].get("field", "").endswith(".key") and field_value_pairs[1].get("field", "").endswith(".value") ) if is_header_pattern: base_field = field_value_pairs[0].get("field", "")[:-4] # Remove ".key" value1 = field_value_pairs[0].get("value", "") value2 = field_value_pairs[1].get("value", "") search_query = f'{base_field}: (key = "{value1}" and value = "{value2}")' else: search_query = " and ".join(f'{fvp.get("field", "")} = "{fvp.get("value", "")}"' for fvp in field_value_pairs) platform_url = f"{CENSYS_PLATFORM_URL}/search?q={urllib.parse.quote_plus(search_query)}" hr_data.append( { "Count": count, "Key": fields, "Value": values, "See results in Censys": f"[View Pivot Information on Censys platform]({platform_url})", } ) # Sort hr_data by count in ascending order (low to high) hr_data.sort(key=lambda x: x["Count"]) hr_output = tableToMarkdown( f"{len(hr_data)} Pivots Data", hr_data, headers=["Key", "Value", "Count", "See results in Censys"], removeNull=True, ) return hr_output """ COMMAND FUNCTIONS """ def test_module(client: Client, params: dict[str, Any]) -> str: # Check if the user has selected malicious or suspicious labels without premium access if not params.get("premium_access") and (params.get("malicious_labels") or params.get("suspicious_labels")): raise DemistoException( "The 'Determine IP score by label' feature only works for Censys paid subscribers (v3 API). " "If you have paid access select the 'Determine IP score by label' option " "to utilize this functionality, or deselect labels" ) fields = ["labels"] if params.get("premium_access") else None try: # Build query for test IP query = 'host.ip="8.8.8.8"' censys_search_with_pagination(client, query, fields=fields, limit=1) return "ok" except DemistoException as e: if e.res is not None: if e.res.status_code == 401: raise DemistoException( "401 Unauthorized: Access credentials are invalid. " "Please verify your 'API Token' in the integration configuration." ) if e.res.status_code == 403: # Handle permission error for non-premium users attempting to access premium features if "specific fields" in e.message: raise DemistoException( "Your user does not have permission for premium features (v3 API). " "Please ensure that you deselect the 'Determine IP score by label' option " "for non-premium access." ) # Handle organization authorization error raise DemistoException( "403 Forbidden: The provided Organization ID is incorrect or the user is not authorized to access it. " "Please verify your 'Organization ID' in the integration configuration." ) # Handle organization ID format error if e.res.status_code == 422: raise DemistoException( "422 Unprocessable Entity: The provided Organization ID is malformed. Please ensure it is a valid UUID." ) raise e def censys_view_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Returns host information for the specified IP address or structured certificate data for the specified SHA-256 """ index = args.get("index", "") query = args.get("query", "") demisto.debug(f"censys_view_command: index={index}, query={query}") res = client.censys_view_request(index, query) resource = demisto.get(res, "result.resource", {}) if index == "ipv4": city = demisto.get(resource, "location.city") province = demisto.get(resource, "location.province") postal = demisto.get(resource, "location.postal_code") country_code = demisto.get(resource, "location.country_code") country = demisto.get(resource, "location.country") description = ", ".join([str(x) for x in [city, province, postal, country_code] if x]) lat = demisto.get(resource, "location.coordinates.latitude") lon = demisto.get(resource, "location.coordinates.longitude") params = demisto.params() labels = list({label.get("value") for label in resource.get("labels", [])}) score, malicious_description = get_dbot_score(params, labels) dbot_score = Common.DBotScore( indicator=query, indicator_type=DBotScoreType.IP, integration_name="Censys", score=score, malicious_description=malicious_description, reliability=params.get("integration_reliability"), ) indicator = Common.IP( ip=query, dbot_score=dbot_score, asn=demisto.get(resource, "autonomous_system.asn"), geo_latitude=str(lat) if lat else None, geo_longitude=str(lon) if lon else None, geo_description=description or None, geo_country=country, as_owner=demisto.get(resource, "autonomous_system.name"), ) hr_content = { "Network": resource.get("autonomous_system", {}).get("name"), "Routing": resource.get("autonomous_system", {}).get("bgp_prefix"), "ASN": resource.get("autonomous_system", {}).get("asn"), "Protocols": ", ".join( [f"{service.get('port')}/{service.get('protocol')}" for service in resource.get("services", [])] ), "Whois Last Updated": demisto.get(resource, "whois.network.updated"), } human_readable = tableToMarkdown(f"Information for IP {query}", hr_content, removeNull=True) return CommandResults( readable_output=human_readable, outputs_prefix="Censys.View", outputs_key_field="ip", outputs=resource, indicator=indicator, raw_response=res, ) else: hr_content = { "Added At": resource.get("added_at"), "Modified At": resource.get("modified_at"), "Browser Trust": [ f"{name}: {'Valid' if val.get('ever_valid') else 'Invalid'}" for name, val in resource.get("validation", {}).items() ], "SHA 256": resource.get("fingerprint_sha256"), "Validated At": resource.get("validated_at"), } human_readable = tableToMarkdown("Information for certificate", hr_content, removeNull=True) return CommandResults( readable_output=human_readable, outputs_prefix="Censys.View", outputs_key_field="fingerprint_sha256", outputs=resource, raw_response=res, ) def censys_search_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Returns previews of hosts matching a specified search query or a list of certificates that match the given query. """ index = args.get("index") query = args.get("query", "") demisto.debug(f"censys_search_command: index={index}, query={query}") page_size: int = arg_to_number(args.get("page_size", 50)) # type: ignore[assignment] limit = arg_to_number(args.get("limit", 50)) hr_contents = [] if index == "ipv4": # Use pagination helper to fetch all results up to limit res = censys_search_with_pagination(client, query, page_size=page_size, limit=limit) hits = res.get("result", {}).get("hits", []) # Extract results results = [] for hit in hits: # Extract resource for human readable output resource = demisto.get(hit, "host_v1.resource", {}) results.append(resource) hr_contents.append( { "IP": resource.get("ip"), "Services": ", ".join( [f"{service.get('port')}/{service.get('protocol')}" for service in resource.get("services", [])] ), "Country code": demisto.get(resource, "location.country_code"), "ASN": demisto.get(resource, "autonomous_system.asn"), "Description": demisto.get(resource, "autonomous_system.description"), "Name": demisto.get(resource, "autonomous_system.name"), } ) human_readable = tableToMarkdown(f'Search results for query "{query}"', hr_contents, removeNull=True) return CommandResults( readable_output=human_readable, outputs_prefix="Censys.Search", outputs_key_field="ip", outputs=results, raw_response=res, ) else: response = search_certs_command(client, args, query, limit, page_size) return response def search_certs_command(client: Client, args: dict[str, Any], query: str, limit: Optional[int], page_size: int | None = None): # Default fields to request (using new API field names with cert prefix) fields = [ "cert.fingerprint_sha256", "cert.parsed.subject_dn", "cert.parsed.issuer_dn", "cert.parsed.issuer.organization", "cert.parsed.validity_period.not_before", "cert.parsed.validity_period.not_after", "cert.names", "cert.parsed.subject.common_name", "cert.parsed.signature.self_signed", "cert.valid_to", "cert.self_signed", ] # Add user-requested fields search_fields = argToList(args.get("fields")) if search_fields: fields.extend(search_fields) # Use pagination helper to fetch all results up to limit res = censys_search_with_pagination(client, query, page_size=page_size, fields=fields, limit=limit) raw_response = res.get("result", {}) hits = raw_response.get("hits", []) if not hits or not isinstance(hits, list): error_msg = f"Unexpected response: 'hits' path not found in response.result. Response: {raw_response}" raise ValueError(error_msg) # Extract results results = [] hr_contents = [] for hit in hits: # Extract the certificate data resource = demisto.get(hit, "certificate_v1.resource", {}) results.append(resource) # Extract data for human readable output parsed = resource.get("parsed", {}) common_names = demisto.get(parsed, "subject.common_name") or [] hr_contents.append( { "Fingerprint sha256": resource.get("fingerprint_sha256"), "Self Signed Signature": demisto.get(parsed, "signature.self_signed"), "Valid To": resource.get("valid_to"), "Self Signed": resource.get("self_signed"), "Subject DN": demisto.get(parsed, "subject_dn"), "Issuer DN": demisto.get(parsed, "issuer_dn"), "Common Names": ", ".join(common_names), "Not Valid Before": demisto.get(parsed, "validity_period.not_before"), "Not Valid After": demisto.get(parsed, "validity_period.not_after"), "Names": resource.get("names"), "Issuer": demisto.get(parsed, "issuer.organization"), } ) human_readable = tableToMarkdown(f'Search results for query "{query}"', hr_contents, removeNull=True, sort_headers=False) return CommandResults( readable_output=human_readable, outputs_prefix="Censys.Search", outputs_key_field="fingerprint_sha256", outputs=results, raw_response=res, ) def ip_command(client: Client, args: dict, params: dict): fields = ( [ "host.labels.value", "host.ip", "host.autonomous_system.asn", "host.autonomous_system.name", "host.autonomous_system.bgp_prefix", "host.autonomous_system.country_code", "host.autonomous_system.description", "host.location.country_code", "host.location.timezone", "host.location.province", "host.location.postal_code", "host.location.coordinates.latitude", "host.location.coordinates.longitude", "host.location.city", "host.location.continent", "host.location.country", "host.services.protocol", "host.services.port", "host.services.transport_protocol", "host.services.extended_service_name", "host.services.cert", "host.whois.network.updated", "host.dns.reverse_dns.names", "host.operating_system.source", "host.operating_system.part", "host.operating_system.version", "host.service_count", "host.services.labels.value", "host.services.threats.name", "host.services.vulns", "host.services.scan_time", "host.dns.names", "host.dns.forward_dns.names", "host.whois.network.name", "host.whois.network.cidrs", ] if params.get("premium_access") else None ) ips: list = argToList(args.get("ip")) demisto.debug(f"ip_command: processing IPs {ips}") results: List[CommandResults] = [] execution_metrics = ExecutionMetrics() try: # Build query for all IPs query = " or ".join([f'host.ip="{ip_addr}"' for ip_addr in ips]) # Send all IPs in a single API call with pagination raw_response = censys_search_with_pagination(client, query, fields=fields) hits = raw_response.get("result", {}).get("hits") if hits is None or not isinstance(hits, list): error_msg = f"Unexpected response: 'hits' path not found in response.result. Response: {raw_response}" raise ValueError(error_msg) # Track which IPs were found found_ips = set() # Process each hit from the response for hit in hits: # Extract resource from host_v1 wrapper resource = demisto.get(hit, "host_v1.resource", {}) ip = resource.get("ip") found_ips.add(ip) labels = list({label.get("value") for label in resource.get("labels", [])}) score, malicious_description = get_dbot_score(params, labels) dbot_score = Common.DBotScore( indicator=ip, indicator_type=DBotScoreType.IP, integration_name="Censys", score=score, malicious_description=malicious_description, reliability=params.get("integration_reliability"), ) content = { "ip": ip, "asn": demisto.get(resource, "autonomous_system.asn"), "updated_date": demisto.get(resource, "whois.network.updated"), "geo_latitude": demisto.get(resource, "location.coordinates.latitude"), "geo_longitude": demisto.get(resource, "location.coordinates.longitude"), "geo_country": demisto.get(resource, "location.country"), "port": ", ".join([str(service.get("port")) for service in resource.get("services", [])]), } indicator = Common.IP(dbot_score=dbot_score, **content) hr_output = f"### Censys results for IP: {ip}\n\n" hr_output += prepare_hr_for_ip_resource(resource) results.append( CommandResults( outputs_prefix="Censys.IP", outputs_key_field="ip", readable_output=hr_output, outputs=resource, raw_response=raw_response, indicator=indicator, ) ) execution_metrics.success += 1 # Report IPs that were not found for ip in ips: if ip not in found_ips: demisto.debug(f"ip_command: IP {ip} not found in search results") results.append(CommandResults(readable_output=f"No results found for IP: {ip}")) except Exception as e: # Handle exceptions for the entire batch handle_exceptions(e, results, execution_metrics, ", ".join(ips)) if execution_metrics.metrics: demisto.debug(f"ip_command: adding execution metrics: {execution_metrics.metrics}") results.append(execution_metrics.metrics) demisto.debug(f"ip_command: returning {len(results)} results. Types: {[type(r) for r in results]}") return results def domain_command(client: Client, args: dict, params: dict): domains: list = argToList(args.get("domain")) ports = argToList(args.get("port", DEFAULT_PORTS)) ports = [validate_port_argument(arg_to_number(port, arg_name="port")) for port in ports if str(port).strip()] # type: ignore ports_str = ", ".join(map(str, ports or DEFAULT_PORTS)) demisto.debug(f"domain_command: processing domains {domains}, ports {ports}") results: List[CommandResults] = [] execution_metrics = ExecutionMetrics() try: # Build query for all domains query = " or ".join( [f'host.dns.names="{dom}" or (web.hostname="{dom}" and web.port: {{{ports_str}}})' for dom in domains] ) # Send all domains in a single API call with pagination raw_response = censys_search_with_pagination(client, query) response = raw_response.get("result", {}) hits = response.get("hits") if hits is None or not isinstance(hits, list): error_msg = f"Unexpected response: 'hits' path not found in response.result. Response: {response}" raise ValueError(error_msg) # Track which domains were found found_domains = set() # Group hits by domain (based on dns.names field or hostname) domain_hits: dict[str, list] = {domain: [] for domain in domains} for hit in hits: # Check if this is a web property hit if "webproperty_v1" in hit: resource = demisto.get(hit, "webproperty_v1.resource", {}) hostname = resource.get("hostname", "") domain_hits.setdefault(hostname, []).append(hit) found_domains.add(hostname) continue resource = demisto.get(hit, "host_v1.resource", {}) dns_names = demisto.get(resource, "dns.names", []) # Match this hit to the requested domain(s) for domain in domains: if domain in dns_names: domain_hits[domain].append(hit) found_domains.add(domain) # Create results for each domain for domain in domains: hits_for_domain = domain_hits.get(domain, []) if not hits_for_domain: # No results for this domain demisto.debug(f"domain_command: domain {domain} not found in search results") results.append(CommandResults(readable_output=f"No results found for domain: {domain}")) continue # Separate host and web property hits host_hits = [hit for hit in hits_for_domain if "host_v1" in hit] web_property_hits = [hit for hit in hits_for_domain if "webproperty_v1" in hit] # Extract resources from host_v1 wrapper host_resources = [] for hit in host_hits: resource = demisto.get(hit, "host_v1.resource", {}) host_resources.append(resource) # Extract resources from webproperty_v1 wrapper web_property_resources = [] for hit in web_property_hits: resource = demisto.get(hit, "webproperty_v1.resource", {}) web_property_resources.append(resource) relationships = [ EntityRelationship( name=EntityRelationship.Relationships.RELATED_TO, entity_a=domain, entity_a_type="Domain", entity_b=demisto.get(hit, "host_v1.resource.ip"), entity_b_type="IP", reverse_name=EntityRelationship.Relationships.RELATED_TO, brand="Censys", ) for hit in host_hits ] # Collect all labels from all host hits for this domain all_labels = [] for res in host_resources: all_labels.extend([label.get("value") for label in res.get("labels", [])]) all_labels = list(set(all_labels)) # Build combined HR output hr_outputs = [] # Add host HR output if there are host hits if not all_labels: host_hr = f"### Censys results for Domain: {domain}" elif len(all_labels) == 1: host_hr = f"### Censys results for Domain: {domain} with label {all_labels[0]}" else: host_hr = f"### Censys results for Domain: {domain} with following labels:\n{', '.join(all_labels)}" hr_outputs.append(host_hr) # Add web property HR output if there are web property hits if web_property_resources: for res in web_property_resources: all_labels.extend([label.get("value") for label in res.get("labels", [])]) all_labels = list(set(all_labels)) hr_output = prepare_hr_for_web_property_resource(web_property_resources) hr_outputs.append(hr_output) combined_hr_output = "\n\n".join(hr_outputs) if hr_outputs else f"No results found for domain: {domain}" score, malicious_description = get_dbot_score(params, all_labels) dbot_score = Common.DBotScore( indicator=domain, indicator_type=DBotScoreType.DOMAIN, integration_name="Censys", score=score, malicious_description=malicious_description, reliability=params.get("integration_reliability"), ) indicator = Common.Domain(domain=domain, dbot_score=dbot_score, relationships=relationships) # Combine all resources for outputs all_resources = host_resources + web_property_resources results.append( CommandResults( outputs_prefix="Censys.Domain", outputs_key_field="Domain", readable_output=combined_hr_output, outputs=all_resources, raw_response=raw_response, indicator=indicator, relationships=relationships, ) ) execution_metrics.success += 1 except Exception as e: # Handle exceptions for the entire batch handle_exceptions(e, results, execution_metrics, ", ".join(domains)) if execution_metrics.metrics: demisto.debug(f"domain_command: adding execution metrics: {execution_metrics.metrics}") results.append(execution_metrics.metrics) demisto.debug(f"domain_command: returning {len(results)} results. Types: {[type(r) for r in results]}") return results def censys_host_history_list_command(client: Client, args: dict) -> CommandResults: """Retrieve the event history for a host (IP address) with automatic pagination. This command fetches historical scan data for an IP address from the Censys API, automatically handling pagination using the scanned_to cursor. It implements robust partial data handling: if an API error occurs mid-pagination after successfully collecting some events, the collected data is returned with a warning instead of failing completely. Pagination limits: - Maximum records: 1000 (MAX_HOST_HISTORY_RECORDS) - Maximum pages: 10 (MAX_NUMBER_OF_PAGES) - Timeout: 4 minutes (240 seconds) Args: client: The Censys client instance for making API requests. args: Command arguments containing: - ip_address (str, required): The IP address to retrieve history for. - start_time (str, required): Start time from the past (e.g., '7 days ago'). - end_time (str, required): End time near current (e.g., 'now'). Returns: CommandResults with host event history data and human-readable table. Raises: ValueError: If required arguments are missing or time range is invalid. DemistoException: If the API call fails before any data is collected. """ ip_address: str = args.get("host_id", "") start_time: str = args.get("start_time", "") end_time: str = args.get("end_time", "") ip_address = validate_required_argument(ip_address, "host_id") start_time = validate_required_argument(start_time, "start_time") end_time = validate_required_argument(end_time, "end_time") if not is_ip_valid(ip_address, accept_v6_ips=True): raise ValueError(ERRORS["INVALID_IP"].format(ip_address)) start_time: str = arg_to_datetime(start_time, arg_name="start_time").strftime(DATE_FORMAT) # type: ignore end_time: str = arg_to_datetime(end_time, arg_name="end_time").strftime(DATE_FORMAT) # type: ignore if start_time >= end_time: raise ValueError(ERRORS["INVALID_TIME_RANGE"].format("start_time", start_time, "end_time", end_time)) all_events: list = [] page_count = 0 is_partial: bool = False # For pagination: current_end_time is the "recent" boundary that shifts with scanned_to. # censys_host_history_request internally reverses start/end for the API. current_end_time = end_time current_time_str = datetime.now(timezone.utc).strftime(DATE_FORMAT) demisto.debug(f"censys_host_history_list: starting pagination for {ip_address}, start_time={start_time}, end_time={end_time}") all_events_platform_url = f"{CENSYS_PLATFORM_URL}{HR_SUFFIX['HOST_ALL_EVENTS'].format(ip_address)}" while len(all_events) < MAX_NUMBER_OF_RECORDS and page_count < MAX_NUMBER_OF_PAGES: page_count += 1 demisto.debug(f"censys_host_history_list: fetching page {page_count} for {ip_address}") # Check if pagination has exceeded the 4-minute timeout threshold if has_passed_time_threshold(current_time_str, DEFAULT_TIMEOUT_THRESHOLD_SECONDS): demisto.debug( f"censys_host_history_list: pagination timeout reached at page {page_count} " f"after collecting {len(all_events)} events. Stopping pagination due to 4-minute time limit." ) partial_data_warning_mes = ( f"Results limited due to command execution time constraint (4 minutes). " f"For complete results, visit: {all_events_platform_url}" ) is_partial = True return_warning(partial_data_warning_mes) break try: response = client.censys_host_history_request(ip_address, start_time, current_end_time) except Exception as e: # Partial data handling: if we already collected some events, return them with a warning if all_events: demisto.debug( f"censys_host_history_list: pagination failed at page {page_count} " f"after collecting {len(all_events)} events. Error: {str(e)}" ) partial_data_warning_mes = ( f"WARNING: Partial data collected ({len(all_events)} event(s)). " f"Pagination stopped at page {page_count} due to error: {str(e)}" ) is_partial = True return_warning(partial_data_warning_mes) break # No data collected yet — propagate the original error raise result = response.get("result", {}) events = result.get("events", []) scanned_to = result.get("scanned_to") if not events: demisto.debug(f"censys_host_history_list: no events on page {page_count}. Pagination complete.") break # Respect the max records cap remaining_capacity = MAX_NUMBER_OF_RECORDS - len(all_events) all_events.extend(events[:remaining_capacity]) demisto.debug( f"censys_host_history_list: page {page_count} returned {len(events)} events. Total collected: {len(all_events)}" ) if len(all_events) >= MAX_NUMBER_OF_RECORDS: demisto.debug(f"censys_host_history_list: reached max {MAX_NUMBER_OF_RECORDS} records.") break if not scanned_to: demisto.debug("censys_host_history_list: no scanned_to cursor. Pagination complete.") break # If the cursor has gone past our time boundary, stop if scanned_to <= start_time: demisto.debug( f"censys_host_history_list: scanned_to ({scanned_to}) <= start_time ({start_time}). Pagination complete." ) break # Advance the pagination cursor current_end_time = scanned_to if not all_events: return CommandResults( readable_output=(f"No historical data found for host {ip_address} within the specified time range."), ) total_events = len(all_events) if is_partial: hr_output = ( f"### Successfully retrieved {total_events} event(s) for host {ip_address} " f"(partial data - {page_count - 1} page(s) fetched).\n" ) else: hr_output = f"### Successfully retrieved {total_events} event(s) for host {ip_address}.\n" if total_events >= MAX_NUMBER_OF_RECORDS: hr_output += ( f"\nThere are more than {MAX_NUMBER_OF_RECORDS} host history records available for this host. " f"The first {MAX_NUMBER_OF_RECORDS} records are displayed. " f"Further exploration should be conducted on the [Censys platform]({all_events_platform_url}).\n" ) hr_output += prepare_hr_for_host_history_list_command(all_events, ip_address) # Context data context_output = { "ip": ip_address, "events": all_events, "total_events": total_events, "partial_data": is_partial, } return CommandResults( readable_output=hr_output, outputs_prefix=OUTPUT_PREFIX["HOST_EVENT_HISTORY"], outputs_key_field="ip", outputs=context_output, raw_response={"result": {"events": all_events, "total_events": total_events, "partial_data": is_partial}}, ) def censys_rescan_command(client: Client, args: dict[str, Any]) -> CommandResults: """Initiate a rescan and automatically retry until completion, then retrieve enrichment data. This command follows XSOAR scheduled command best practices: 1. Initiates a live rescan on a host service 2. Automatically retries every 30 seconds until the rescan is completed 3. If the rescan fails, returns an error message 4. Once completed, retrieves the updated enrichment data Args: client: The Censys client instance args: Command arguments Returns: CommandResults with scan status or list with ScheduledCommand """ ioc_type = args.get("ioc_type", "service").strip() ioc_value = args.get("ioc_value", "").strip() port = arg_to_number(args.get("port", 443)) protocol = args.get("protocol", "").strip() scan_id = args.get("scan_id", "").strip() transport_protocol = args.get("transport_protocol", DEFAULT_TRANSPORT_PROTOCOL).strip() polling = args.get("polling", False) validate_rescan_command_args(ioc_type, ioc_value, port, protocol, transport_protocol) outputs = { "ioc_value": ioc_value, "port": port, "status": "initiated", "scan_id": scan_id, "is_completed": False, } if not polling: response = client.censys_initiate_rescan_request(ioc_type, ioc_value, port, protocol, transport_protocol) result = response.get("result", {}) scan_id = result.get("tracked_scan_id") if not scan_id: outputs.update({"status": "failed", "is_completed": True}) return CommandResults( readable_output="### Scan initiated but no scan ID returned.", outputs_prefix=OUTPUT_PREFIX["INITIATE_RESCAN"], outputs=remove_empty_elements(outputs), raw_response=response, ) outputs["scan_id"] = scan_id return CommandResults( readable_output=f"### Scan initiated successfully for {ioc_value}:{port}.\n#### Scan ID: {scan_id}.", outputs_prefix=OUTPUT_PREFIX["INITIATE_RESCAN"], outputs_key_field="scan_id", outputs=outputs, raw_response=response, ) # Check rescan status status_response = client.censys_rescan_status_request(scan_id) result = status_response.get("result", {}) completed = result.get("completed") if completed is None: outputs.update({"status": "in_progress", "is_completed": False}) return CommandResults( readable_output=f"### Scan is still in progress for {ioc_value}:{port}.\n#### Scan ID: {scan_id}", outputs_prefix=OUTPUT_PREFIX["INITIATE_RESCAN"], outputs_key_field="scan_id", outputs=remove_empty_elements(outputs), raw_response=status_response, ) if not completed: outputs.update({"status": "failed", "is_completed": True}) return CommandResults( readable_output=f"### Scan failed for {ioc_value}:{port}.\n#### Scan ID: {scan_id}", outputs_prefix=OUTPUT_PREFIX["INITIATE_RESCAN"], outputs_key_field="scan_id", outputs=remove_empty_elements(outputs), raw_response=status_response, ) # Determine index based on ioc_type if ioc_type.lower() == "service": index = "ipv4" query = ioc_value else: index = "webproperty" query = f"{ioc_value}:{port}" enrichment_response = client.censys_view_request(index, query) resource = enrichment_response.get("result", {}).get("resource", {}) if ioc_type.lower() == "service": human_readable = prepare_hr_for_ip_resource(resource) else: human_readable = prepare_hr_for_web_property_resource(resource) hr_output = f"### Scan completed successfully for {ioc_value}:{port}.\n" + human_readable outputs.update({"enrichment_data": resource, "status": "completed", "is_completed": True}) return CommandResults( readable_output=hr_output, outputs_prefix=OUTPUT_PREFIX["INITIATE_RESCAN"], outputs_key_field="scan_id", outputs=remove_empty_elements(outputs), raw_response=enrichment_response, ) def censys_related_infrastructure_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """Initiate a CensEye related infrastructure job and poll until completion, then retrieve pivot data. This command follows XSOAR scheduled command best practices: 1. Initiates a CensEye job for the given IOC 2. Automatically retries every 10 seconds until the job is completed 3. If the job fails, returns an error message 4. Once completed, retrieves the pivot data results Args: client: The Censys client instance args: Command arguments Returns: CommandResults with job status or list with ScheduledCommand """ ioc_type = args.get("ioc_type", "Host").strip() ioc_value = args.get("ioc_value", "").strip() job_id = args.get("job_id", "").strip() polling = args.get("polling", False) validate_related_infra_command_args(ioc_type, ioc_value) outputs = { "ioc_value": ioc_value, "status": "initiated", "job_id": job_id, "is_completed": False, } if not polling: response = client.censys_initiate_job_request(ioc_type.lower(), ioc_value) result = response.get("result", {}) job_id = result.get("job_id") if not job_id: outputs.update({"status": "failed", "is_completed": True}) return CommandResults( readable_output="### Job initiated but no job ID returned.", outputs_prefix=OUTPUT_PREFIX["RELATED_INFRASTRUCTURE"], outputs=remove_empty_elements(outputs), raw_response=response, ) outputs["job_id"] = job_id return CommandResults( readable_output=f"### Job initiated successfully for {ioc_value}.\n#### Job ID: {job_id}", outputs_prefix=OUTPUT_PREFIX["RELATED_INFRASTRUCTURE"], outputs_key_field="job_id", outputs=outputs, raw_response=response, ) # Check job status status_response = client.censys_job_status_request(job_id) result = status_response.get("result", {}) state = result.get("state", "") if state == "failed": outputs.update({"status": "failed", "is_completed": True}) return CommandResults( readable_output=f"### Job failed for {ioc_value}.\n#### Job ID: {job_id}", outputs_prefix=OUTPUT_PREFIX["RELATED_INFRASTRUCTURE"], outputs_key_field="job_id", outputs=remove_empty_elements(outputs), raw_response=status_response, ) elif state != "completed": outputs.update({"status": "in_progress", "is_completed": False}) return CommandResults( readable_output=f"### Job is still in progress for {ioc_value}.\n#### Job ID: {job_id}", outputs_prefix=OUTPUT_PREFIX["RELATED_INFRASTRUCTURE"], outputs_key_field="job_id", outputs=remove_empty_elements(outputs), raw_response=status_response, ) # Job completed - fetch results results_response = client.censys_job_results_request(job_id) pivot_data = demisto.get(results_response, "result.results", []) hr_output = f"### Job completed successfully for {ioc_value}.\n\n" if pivot_data: pivot_data_hr = prepare_hr_for_pivot_information(pivot_data) hr_output += pivot_data_hr else: hr_output += "#### No pivot data found." outputs.update({"pivot_data": pivot_data, "status": "completed", "is_completed": True}) return CommandResults( readable_output=hr_output, outputs_prefix=OUTPUT_PREFIX["RELATED_INFRASTRUCTURE"], outputs_key_field="job_id", outputs=remove_empty_elements(outputs), raw_response=results_response, ) def run_polling_command( client: Client, args: dict[str, Any], command_name: str, search_function: Callable ) -> list[CommandResults] | CommandResults: """Generic polling command handler following XSOAR best practices. Args: client: The Censys client instance args: Command arguments command_name: Name of the command for scheduling search_function: Function to execute for status checking Returns: List of CommandResults with ScheduledCommand or single CommandResults """ result = search_function(client, args) outputs = result.outputs or {} is_completed = outputs.get("is_completed") if is_completed: return result if not is_completed: polling_args = {**args, "polling": True} scan_id = outputs.get("scan_id") job_id = outputs.get("job_id") if scan_id: polling_args["scan_id"] = scan_id if job_id: polling_args["job_id"] = job_id scheduled_command = ScheduledCommand( command=command_name, next_run_in_seconds=DEFAULT_POLLING_INTERVAL, args=polling_args, timeout_in_seconds=DEFAULT_POLLING_TIMEOUT, ) command_results = CommandResults(scheduled_command=scheduled_command) return [result, command_results] return result """ MAIN FUNCTION """ def main() -> None: params = demisto.params() api_token = params.get("api_token", {}).get("password") org_id = params.get("organization_id") verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) base_url = params.get("server_url") or "https://api.platform.censys.io" command = demisto.command() demisto.debug(f"Command being called is {command}") commands: dict = { "cen-host-history-list": censys_host_history_list_command, } scheduled_commands: dict = { "cen-rescan": censys_rescan_command, "cen-related-infrastructure-list": censys_related_infrastructure_list_command, } try: args = demisto.args() client = Client(base_url=base_url, api_token=api_token, org_id=org_id, verify=verify_certificate, proxy=proxy) if command == "test-module": return_results(test_module(client, params)) elif command == "cen-view": return_results(censys_view_command(client, args)) elif command == "cen-search": return_results(censys_search_command(client, args)) elif command == "ip": return_results(ip_command(client, args, params)) elif command == "domain": return_results(domain_command(client, args, params)) elif command in commands: # remove nulls from dictionary and trim space from args remove_nulls_from_dictionary(trim_spaces_from_args(args)) result = commands[command](client, args) return_results(result) elif command in scheduled_commands: remove_nulls_from_dictionary(trim_spaces_from_args(args)) return_results( run_polling_command(client=client, args=args, search_function=scheduled_commands[command], command_name=command) ) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()