Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Packs/DomainTools_Iris/.secrets-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,6 @@ [email protected]
217.160.80.126
217.160.82.73
217.160.83.63
217.160.81.67
217.160.81.67
142.250.217.68
142.250.217.78
146 changes: 119 additions & 27 deletions Packs/DomainTools_Iris/Integrations/DomainTools_Iris/DomainTools_Iris.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ def http_request(method: str, params: dict = {}):
response = api.parsed_whois(params.get('domain')).response()
elif method == "parsed-domain-rdap":
response = api.parsed_domain_rdap(query=params.get("domain"))
elif method == "reverse-nameserver":
response = api.reverse_name_server(params.get("nameserver"), limit=params.get("limit")).response()
elif method == "reverse-ip":
response = api.reverse_ip(domain=params.get("domain"), limit=params.get("limit")).response()
elif method == "host-domains":
response = api.host_domains(ip=params.get("ip"), limit=params.get("limit")).response()
else:
response = api.iris_investigate(**params).response()
except Exception as e:
Expand Down Expand Up @@ -483,7 +489,16 @@ def parsed_whois(domain):
return http_request('parsed-whois', {'domain': domain})


def parsed_domain_rdap(domain: str):
def parsed_domain_rdap(domain: str) -> dict[str, Any]:
""" Returns the parsed domain rdap by a given domain.

Args:
domain (str): The domain to lookup.

Returns:
dict: The parsed domain rdap results from DT API.

"""
resp = http_request("parsed-domain-rdap", params={"domain": domain})

return {
Expand All @@ -492,6 +507,18 @@ def parsed_domain_rdap(domain: str):
}


def reverse_nameserver(nameserver: str, limit: int | None = None) -> dict:
return http_request("reverse-nameserver", params={"nameserver": nameserver, "limit": limit})


def reverse_ip(domain: str, limit: int | None = None) -> dict:
return http_request("reverse-ip", params={"domain": domain, "limit": limit})


def host_domains(ip: str, limit: int | None = None) -> dict:
return http_request("host-domains", params={"ip": ip, "limit": limit})


def add_key_to_json(cur, to_add):
if not cur:
return to_add
Expand Down Expand Up @@ -1513,6 +1540,69 @@ def reverse_whois_command():
)


def reverse_nameserver_command():
"""
Returns the reverse lookup on a given nameserver.
"""
nameserver = demisto.args()["nameServer"]
limit = int(demisto.args().get("limit") or 50)

context: dict[str, list[dict]] = {"Domain": []}

results = reverse_nameserver(nameserver=nameserver, limit=limit)
primary_domains = results.get("primary_domains") or []

total_primary_domains = len(primary_domains)

human_readable = f"Found {total_primary_domains} domains. \n"

for domain in primary_domains:
context["Domain"].append({"Name": domain})
human_readable += f"* {domain} \n"

return CommandResults(
readable_output=human_readable,
outputs=context,
raw_response=results,
ignore_auto_extract=True
)


def reverse_ip_command():
"""
Returns the reverse lookup on a given domain or ip.
"""
cmd_args = demisto.args()
ip = cmd_args.get("ip")
domain = cmd_args.get("domain")
limit = int(cmd_args.get("limit") or 50)

context: dict[str, list[dict]] = {"Domain": []}
human_readable = ""

if domain:
results = reverse_ip(domain=domain, limit=limit)
elif ip:
results = host_domains(ip=ip, limit=limit)

addresses: list | dict = results.get("ip_addresses") or []
if not isinstance(addresses, list):
addresses = [addresses]

for address in addresses:
human_readable += f"\nFound {address.get('domain_count', 0)} domains for {address.get('ip_address')}. \n"
for domain in address.get("domain_names") or []:
context["Domain"].append({"Name": domain})
human_readable += f"* {domain} \n"

return CommandResults(
readable_output=human_readable,
outputs=context,
raw_response=results,
ignore_auto_extract=True
)


def parsed_whois_command():
domain = demisto.args()['query']
response = parsed_whois(domain)
Expand Down Expand Up @@ -1565,6 +1655,31 @@ def parsed_whois_command():
)


def parsed_domain_rdap_command():
"""
Returns parsed domain rdap data in a given domain
"""
domain = demisto.args()['domain']
results = parsed_domain_rdap(domain=domain)

_raw_response = results.get("_raw") or {}
flat_response = results.get("flat") or {}

for key, val in flat_response.items():
if "|" in val:
flat_response[key] = ", ".join([v.strip() for v in val.split("|")])

headers = list(flat_response.keys())

human_readable = tableToMarkdown(f'DomainTools parsed domain rdap result for {domain}', flat_response, headers=headers)

return CommandResults(
readable_output=human_readable,
raw_response=_raw_response,
ignore_auto_extract=True
)


def test_module():
"""
Tests the API key for a user.
Expand Down Expand Up @@ -1598,31 +1713,6 @@ def fetch_domains():
)


def parsed_domain_rdap_command():
"""
Returns parsed domain rdap data in a given domain
"""
domain = demisto.args()['domain']
results = parsed_domain_rdap(domain=domain)

_raw_response = results.get("_raw") or {}
flat_response = results.get("flat") or {}

for key, val in flat_response.items():
if "|" in val:
flat_response[key] = ", ".join([v.strip() for v in val.split("|")])

headers = list(flat_response.keys())

human_readable = tableToMarkdown(f'DomainTools parsed domain rdap result for {domain}', flat_response, headers=headers)

return CommandResults(
readable_output=human_readable,
raw_response=_raw_response,
ignore_auto_extract=True
)


def main():
"""
Main Demisto function.
Expand All @@ -1631,6 +1721,7 @@ def main():
"test-module": test_module,
"domain": domain_command,
"domainRdap": parsed_domain_rdap_command,
"domaintools-whois": parsed_whois_command,
"domaintoolsiris-investigate": domain_command,
"domaintoolsiris-analytics": domain_analytics_command,
"domaintoolsiris-threat-profile": threat_profile_command,
Expand All @@ -1639,7 +1730,8 @@ def main():
"domaintools-whois-history": whois_history_command,
"domaintools-hosting-history": hosting_history_command,
"domaintools-reverse-whois": reverse_whois_command,
"domaintools-whois": parsed_whois_command,
"reverseNameServer": reverse_nameserver_command,
"reverseIP": reverse_ip_command
}

try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2440,6 +2440,38 @@ script:
description: Parsed Whois data.
- contextPath: Domain.WhoisRecords
description: Full Whois record.
- name: reverseIP
arguments:
- default: true
name: ip
description: Specify the IP address to query.
- name: domain
description: If a domain name is provided, DomainTools will respond with the list of other domains that share the same IP.
- name: limit
description: Limits the size of the domain list than can appear in a response. The limit is applied per-IP address, not for the entire request.
defaultValue: 50
description: Reverse loopkup of an IP address or a domain.
deprecated: false
execution: false
outputs:
- contextPath: Domain.Name
description: Domain name returned by the query.
- contextPath: Domain.DNS.Address
description: The IP address associated with the returned domains.
- name: reverseNameServer
arguments:
- name: nameServer
required: true
description: Specify the name of the primary or secondary nameserver.
- name: limit
description: Limit the size of the domain list than can appear in a response.
defaultValue: 50
deprecated: false
execution: false
description: Reverse nameserver lookup.
outputs:
- contextPath: Domain.Name
description: Name of the domain returned by the query.
dockerimage: demisto/vendors-sdk:1.0.0.2141458
runonce: false
script: '-'
Expand Down
Loading
Loading