Wanted to share this python script that one of my colleagues showed me. You can use it to quickly return useful information about a host including location, DNS, ports and protocols, and software information. If you have access to threat data, you can use the --include_threats tag to highlight that info in the readout as well.
You’ll need to install the Platform SDK and prettytable to get it running.
import argparse
from censys_platform import SDK, RetryConfig
from censys_platform.utils import BackoffStrategy
from prettytable import PrettyTable
# Parse arguments
parser = argparse.ArgumentParser(description="Retrieve data for a given IP address.")
parser.add_argument("--ip", required=False, help="IP address to query")
parser.add_argument("--include_threats", action="store_true", help="Include threats in the output")
args = parser.parse_args()
ip_address = args.ip if args.ip is not None else "34.0.51.123"
include_threats = args.include_threats
# API Key and Org ID for Platform
organization_id = "ORG_ID_HERE_OR_LOAD_FROM_ENV"
platform_api_key = "censys_API_KEY_HERE_OR_LOAD_FROM_ENV"
with SDK(
organization_id=organization_id,
personal_access_token=platform_api_key,
retry_config=RetryConfig("backoff",
BackoffStrategy(100, 10000, 1.5, 30000),
True)
) as sdk:
res = sdk.global_data.get_host(host_id=ip_address)
fwd_dns_records = []
if res.result.result.resource.dns.forward_dns is not None:
for record in res.result.result.resource.dns.forward_dns:
fwd_dns_records.append(record)
rev_dns_records = []
if res.result.result.resource.dns.reverse_dns is not None:
for record in res.result.result.resource.dns.reverse_dns.names:
rev_dns_records.append(record)
if res.result.result.resource.location is not None:
location = res.result.result.resource.location
continent = location.continent
country_code = location.country_code
country = location.country
province = location.province
city = location.city
services = []
for service in res.result.result.resource.services:
new_service = {
"port": service.port,
"protocol": service.protocol,
"software": [],
"threats": [],
}
for software in service.software:
new_software = {}
if software.vendor is not None:
new_software["vendor"] = software.vendor
if software.product is not None:
new_software["software"] = software.product
if software.version is not None:
new_software["version"] = software.version
if software.cpe is not None:
new_software["cpe"] = software.cpe
new_service["software"].append(new_software)
if include_threats:
for threat in service.threats:
new_threat = {}
if threat.name is not None:
new_threat["name"] = threat.name
if threat.type is not None:
new_threat["type"] = threat.type
new_service["threats"].append(new_threat)
services.append(new_service)
# Create a combined visual table for forward and reverse DNS records
dns_table = PrettyTable()
dns_table.field_names = ["Forward DNS", "Reverse DNS"]
# Determine the maximum length between the two lists for iteration
max_len = max(len(fwd_dns_records), len(rev_dns_records))
# Add rows to the table, pairing forward and reverse DNS records
for i in range(max_len):
fwd_record = fwd_dns_records[i] if i < len(fwd_dns_records) else ""
rev_record = rev_dns_records[i] if i < len(rev_dns_records) else ""
dns_table.add_row([fwd_record, rev_record])
# Create a visual table for location information
location_table = PrettyTable()
location_table.field_names = ["Continent", "Country", "Province", "City"]
location_table.add_row([continent, country, province, city])
# Create a visual table for services
services_table = PrettyTable()
if not include_threats:
services_table.field_names = ["Port", "Protocol", "Vendor", "Software", "Version", "CPE"]
else:
services_table.field_names = ["Port", "Protocol", "Vendor", "Software", "Version", "CPE", "Threat Name", "Threat Type"]
# Create a visual table for services
services_table = PrettyTable()
if not include_threats:
services_table.field_names = ["Port", "Protocol", "Vendor", "Software", "Version", "CPE"]
else:
services_table.field_names = ["Port", "Protocol", "Vendor", "Software", "Version", "CPE", "Threat Name",
"Threat Type"]
for service in services:
for software in service["software"]:
# Only add rows with at least one valid piece of software data
if (
software.get("vendor", "N/A") != "N/A"
or software.get("software", "N/A") != "N/A"
or software.get("version", "N/A") != "N/A"
or software.get("cpe", "N/A") != "N/A"
):
if include_threats:
# Check if there are any threats
if service["threats"]:
for threat in service["threats"]:
services_table.add_row([
service["port"],
service["protocol"],
software.get("vendor", "N/A"),
software.get("software", "N/A"),
software.get("version", "N/A"),
software.get("cpe", "N/A"),
threat.get("name", "N/A"),
threat.get("type", "N/A"),
])
else:
# If no threats, add a single row with N/A for threat fields
services_table.add_row([
service["port"],
service["protocol"],
software.get("vendor", "N/A"),
software.get("software", "N/A"),
software.get("version", "N/A"),
software.get("cpe", "N/A"),
"N/A",
"N/A",
])
else:
services_table.add_row([
service["port"],
service["protocol"],
software.get("vendor", "N/A"),
software.get("software", "N/A"),
software.get("version", "N/A"),
software.get("cpe", "N/A"),
])
if 'dns_table' in locals():
print(dns_table)
if 'location_table' in locals():
print(location_table)
if 'services_table' in locals():
print(services_table)After you add your API key and org info, you can run a command like:
python host_context.py --ip=[IP address] --include_threats
To retrieve info about the IP, including threat data. The output will be provided in an easy-to-use table.

