Skip to main content

IP Lookup

The IP Lookup API provides comprehensive IP address intelligence and metadata, allowing security professionals to query the FullHunt database for detailed information about any IP address.

IP Address Lookup​

Get comprehensive intelligence and metadata for an IP address.

HTTP Request

GET https://fullhunt.io/api/v1/nexus/ip-lookup

Query Parameters

ParameterRequiredTypeDescription
queryYesstringIP address or domain name to lookup

Example Request

curl "https://fullhunt.io/api/v1/nexus/ip-lookup?query=google.com" \
-H "X-API-KEY: xxxx-xxxx-xxxx-xxxxxx"

Example Response

{
"other_ips": ["2a00:1450:4019:80e::200e"],
"query": "google.com",
"resolved_query": "172.217.19.206",
"resolvable": true,
"result": {
"asn": 15169,
"cdn_provider": "",
"cdn_region": "",
"city_name": "",
"cloud_provider": "GCP",
"cloud_region": "global",
"country_code": "US",
"country_name": "United States",
"error": "",
"hosts_count": 0,
"ip_address": "172.217.19.206",
"ip_decimal": "2899907534",
"is_cdn": false,
"is_cloud": true,
"is_cloudflare": false,
"is_ipv4": true,
"is_ipv6": false,
"is_private": false,
"is_public": true,
"isp": "GOOGLE",
"location_latitude": 37.751,
"location_longitude": -97.822,
"organization": "GOOGLE",
"postal_code": "",
"ptr": ["ams16s31-in-f14.1e100.net.", "fjr04s13-in-f14.1e100.net."],
"region": ""
}
}

Response Fields

FieldTypeDescription
other_ipsarrayOther IP addresses resolved for the query (IPv6, etc.)
querystringOriginal query (domain or IP)
resolved_querystringIP address resolved from domain query
resolvablebooleanWhether the query was resolvable
resultobjectDetailed IP information

Result Object Fields​

FieldTypeDescription
asnintegerAutonomous System Number
cdn_providerstringCDN provider if applicable
cdn_regionstringCDN region if applicable
city_namestringCity name
cloud_providerstringCloud provider (AWS, GCP, Azure, etc.)
cloud_regionstringCloud region
country_codestringISO country code
country_namestringCountry name
hosts_countintegerNumber of hosts associated with this IP
ip_addressstringIP address
ip_decimalstringIP address in decimal format
is_cdnbooleanWhether IP belongs to a CDN
is_cloudbooleanWhether IP belongs to a cloud provider
is_cloudflarebooleanWhether IP belongs to Cloudflare
is_ipv4booleanWhether IP is IPv4
is_ipv6booleanWhether IP is IPv6
is_privatebooleanWhether IP is in private range
is_publicbooleanWhether IP is public
ispstringInternet Service Provider
location_latitudefloatGeographic latitude
location_longitudefloatGeographic longitude
organizationstringOrganization name
postal_codestringPostal code
ptrarrayPTR DNS records
regionstringGeographic region

Integration Example​

import requests
import json
from datetime import datetime
import ipaddress
from collections import defaultdict

class IPIntelligenceAnalyzer:
def __init__(self, api_key):
self.api_key = api_key
self.headers = {"X-API-KEY": api_key}
self.base_url = "https://fullhunt.io/api/v1/nexus/ip-lookup"

def lookup_ip(self, query):
"""Look up IP intelligence for an IP address or domain."""
params = {"query": query}
response = requests.get(self.base_url, headers=self.headers, params=params)

if response.status_code == 200:
return response.json()
else:
print(f"Error looking up {query}: {response.status_code}")
return None

def analyze_ip_profile(self, query):
"""Analyze comprehensive IP profile."""
data = self.lookup_ip(query)

if not data or not data.get('result'):
print(f"No IP data found for: {query}")
return None

result = data['result']

print(f"πŸ” IP Intelligence Analysis for: {query}")
print("=" * 60)

# Basic IP information
resolved_ip = data.get('resolved_query', query)
print(f"Resolved IP: {resolved_ip}")
print(f"Query Type: {'Domain' if data.get('resolvable') else 'IP Address'}")

# Network information
print(f"\n🌐 Network Information:")
print(f" ASN: {result.get('asn', 'N/A')}")
print(f" Organization: {result.get('organization', 'N/A')}")
print(f" ISP: {result.get('isp', 'N/A')}")

# Geographic information
print(f"\nπŸ“ Geographic Location:")
print(f" Country: {result.get('country_name', 'N/A')} ({result.get('country_code', 'N/A')})")
print(f" Region: {result.get('region', 'N/A')}")
print(f" City: {result.get('city_name', 'N/A')}")
print(f" Postal Code: {result.get('postal_code', 'N/A')}")

lat = result.get('location_latitude')
lon = result.get('location_longitude')
if lat and lon:
print(f" Coordinates: {lat}, {lon}")

# Infrastructure classification
print(f"\nπŸ—οΈ Infrastructure Classification:")

infrastructure_flags = [
('Cloud Provider', result.get('is_cloud', False), result.get('cloud_provider', '')),
('CDN', result.get('is_cdn', False), result.get('cdn_provider', '')),
('Cloudflare', result.get('is_cloudflare', False), ''),
('Public IP', result.get('is_public', False), ''),
('Private IP', result.get('is_private', False), ''),
('IPv4', result.get('is_ipv4', False), ''),
('IPv6', result.get('is_ipv6', False), '')
]

for flag_name, flag_value, extra_info in infrastructure_flags:
status = "βœ…" if flag_value else "❌"
extra = f" ({extra_info})" if extra_info else ""
print(f" {status} {flag_name}{extra}")

# DNS information
ptr_records = result.get('ptr', [])
if ptr_records:
print(f"\nπŸ”„ DNS Information:")
print(f" PTR Records: {len(ptr_records)}")
for ptr in ptr_records[:3]: # Show first 3
print(f" β€’ {ptr}")
if len(ptr_records) > 3:
print(f" ... and {len(ptr_records) - 3} more")

# Additional IPs (for domains)
other_ips = data.get('other_ips', [])
if other_ips:
print(f"\nπŸ”— Additional IP Addresses:")
for ip in other_ips[:5]: # Show first 5
print(f" β€’ {ip}")

# Risk assessment
risk_factors = self._assess_ip_risk(result)
if risk_factors:
print(f"\n⚠️ Risk Assessment:")
for risk in risk_factors:
print(f" β€’ {risk}")

return {
'ip_data': data,
'resolved_ip': resolved_ip,
'risk_factors': risk_factors,
'infrastructure_type': self._classify_infrastructure(result)
}

def batch_ip_analysis(self, ip_list):
"""Analyze multiple IP addresses."""
print(f"πŸ“Š Batch IP Analysis - {len(ip_list)} addresses")
print("=" * 60)

results = {}
infrastructure_stats = defaultdict(int)
geographic_stats = defaultdict(int)
organization_stats = defaultdict(int)

for i, ip in enumerate(ip_list, 1):
print(f"\n[{i}/{len(ip_list)}] Analyzing {ip}...")

data = self.lookup_ip(ip)

if data and data.get('result'):
result = data['result']
results[ip] = data

# Collect statistics
if result.get('is_cloud'):
infrastructure_stats['Cloud'] += 1
if result.get('is_cdn'):
infrastructure_stats['CDN'] += 1
if result.get('is_cloudflare'):
infrastructure_stats['Cloudflare'] += 1
if result.get('is_private'):
infrastructure_stats['Private'] += 1
else:
infrastructure_stats['Public'] += 1

# Geographic stats
country = result.get('country_name', 'Unknown')
geographic_stats[country] += 1

# Organization stats
org = result.get('organization', 'Unknown')
organization_stats[org] += 1

print(f" βœ… {result.get('organization', 'Unknown')} - {result.get('country_name', 'Unknown')}")
else:
print(f" ❌ No data found")
results[ip] = None

# Display statistics
print(f"\nπŸ“ˆ Analysis Summary:")
print(f" Total IPs analyzed: {len(ip_list)}")
print(f" Successful lookups: {len([r for r in results.values() if r])}")

print(f"\nπŸ—οΈ Infrastructure Distribution:")
for infra_type, count in sorted(infrastructure_stats.items(), key=lambda x: x[1], reverse=True):
percentage = (count / len(ip_list)) * 100
print(f" {infra_type}: {count} ({percentage:.1f}%)")

print(f"\n🌍 Geographic Distribution:")
for country, count in sorted(geographic_stats.items(), key=lambda x: x[1], reverse=True)[:5]:
percentage = (count / len(ip_list)) * 100
print(f" {country}: {count} ({percentage:.1f}%)")

print(f"\n🏒 Top Organizations:")
for org, count in sorted(organization_stats.items(), key=lambda x: x[1], reverse=True)[:5]:
percentage = (count / len(ip_list)) * 100
print(f" {org}: {count} ({percentage:.1f}%)")

return {
'results': results,
'statistics': {
'infrastructure': dict(infrastructure_stats),
'geographic': dict(geographic_stats),
'organizations': dict(organization_stats)
}
}

def investigate_suspicious_ips(self, ip_list, risk_threshold=2):
"""Investigate IPs for suspicious characteristics."""
print(f"πŸ” Suspicious IP Investigation - {len(ip_list)} addresses")
print("=" * 60)

suspicious_ips = []

for ip in ip_list:
analysis = self.analyze_ip_profile(ip)

if analysis:
risk_count = len(analysis.get('risk_factors', []))

if risk_count >= risk_threshold:
suspicious_ips.append({
'ip': ip,
'risk_count': risk_count,
'risk_factors': analysis['risk_factors'],
'infrastructure_type': analysis['infrastructure_type'],
'full_data': analysis['ip_data']
})

if suspicious_ips:
print(f"\n🚨 Suspicious IPs Found: {len(suspicious_ips)}")

# Sort by risk count
suspicious_ips.sort(key=lambda x: x['risk_count'], reverse=True)

for i, ip_info in enumerate(suspicious_ips, 1):
ip = ip_info['ip']
risk_count = ip_info['risk_count']

print(f"\n{i}. {ip} (Risk Score: {risk_count})")

for risk in ip_info['risk_factors']:
print(f" ⚠️ {risk}")

# Show key details
result = ip_info['full_data']['result']
org = result.get('organization', 'Unknown')
country = result.get('country_name', 'Unknown')
print(f" πŸ“ {org} - {country}")

else:
print(f"\nβœ… No suspicious IPs found (threshold: {risk_threshold} risk factors)")

return suspicious_ips

def _assess_ip_risk(self, result):
"""Assess risk factors for an IP address."""
risk_factors = []

# Check for high-risk characteristics
if result.get('is_private'):
risk_factors.append("Private IP address in public context")

# Check for suspicious organizations
suspicious_orgs = ['tor', 'proxy', 'vpn', 'hosting', 'bulletproof']
org_name = result.get('organization', '').lower()
isp_name = result.get('isp', '').lower()

for suspicious in suspicious_orgs:
if suspicious in org_name or suspicious in isp_name:
risk_factors.append(f"Potentially suspicious organization: {result.get('organization', 'N/A')}")
break

# Check for high-risk countries (example list)
high_risk_countries = ['CN', 'RU', 'KP', 'IR'] # Example - adjust based on your risk model
if result.get('country_code') in high_risk_countries:
risk_factors.append(f"High-risk country: {result.get('country_name', 'N/A')}")

# Check for hosting/cloud without specific provider
if result.get('is_cloud') and not result.get('cloud_provider'):
risk_factors.append("Unidentified cloud provider")

return risk_factors

def _classify_infrastructure(self, result):
"""Classify infrastructure type."""
if result.get('is_cloudflare'):
return 'Cloudflare'
elif result.get('is_cdn'):
return f"CDN ({result.get('cdn_provider', 'Unknown')})"
elif result.get('is_cloud'):
return f"Cloud ({result.get('cloud_provider', 'Unknown')})"
elif result.get('is_private'):
return 'Private Network'
else:
return 'Standard Hosting'

def export_ip_report(self, ip_list, filename=None):
"""Export comprehensive IP analysis report."""
batch_analysis = self.batch_ip_analysis(ip_list)

report = {
'timestamp': datetime.now().isoformat(),
'ip_addresses_analyzed': len(ip_list),
'successful_lookups': len([r for r in batch_analysis['results'].values() if r]),
'statistics': batch_analysis['statistics'],
'detailed_results': batch_analysis['results']
}

if filename is None:
filename = f"ip_intelligence_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"

try:
with open(filename, 'w') as f:
json.dump(report, f, indent=2)

print(f"πŸ“ IP intelligence report exported to: {filename}")
return True

except Exception as e:
print(f"❌ Failed to export report: {e}")
return False

# Usage Examples
api_key = "your-api-key-here"
analyzer = IPIntelligenceAnalyzer(api_key)

# Single IP analysis
ip_analysis = analyzer.analyze_ip_profile("8.8.8.8")

# Domain analysis
domain_analysis = analyzer.analyze_ip_profile("google.com")

# Batch IP analysis
suspicious_ips = ["192.168.1.1", "8.8.8.8", "1.1.1.1"]
batch_results = analyzer.batch_ip_analysis(suspicious_ips)

# Suspicious IP investigation
investigation_results = analyzer.investigate_suspicious_ips(suspicious_ips, risk_threshold=1)

# Export comprehensive report
analyzer.export_ip_report(suspicious_ips)

Advanced Use Cases​

import requests
import json
import geoip2.database
from datetime import datetime, timedelta

def threat_hunting_workflow(api_key, log_file_path):
"""Automated threat hunting workflow using IP intelligence."""
analyzer = IPIntelligenceAnalyzer(api_key)

print("🎯 Threat Hunting Workflow")
print("=" * 50)

# Extract IPs from log file
print("πŸ“„ Extracting IPs from log file...")
unique_ips = extract_ips_from_logs(log_file_path)

print(f"Found {len(unique_ips)} unique IP addresses")

# Analyze all IPs
print("\nπŸ” Analyzing IP intelligence...")
batch_results = analyzer.batch_ip_analysis(list(unique_ips))

# Identify high-risk IPs
print("\n⚠️ Identifying high-risk IPs...")
suspicious_ips = analyzer.investigate_suspicious_ips(list(unique_ips), risk_threshold=1)

# Generate threat report
threat_report = {
'analysis_date': datetime.now().isoformat(),
'log_file': log_file_path,
'total_unique_ips': len(unique_ips),
'suspicious_ips': len(suspicious_ips),
'high_risk_ips': [ip for ip in suspicious_ips if ip['risk_count'] >= 3],
'geographic_distribution': batch_results['statistics']['geographic'],
'infrastructure_distribution': batch_results['statistics']['infrastructure']
}

print(f"\nπŸ“Š Threat Hunting Summary:")
print(f" Total unique IPs: {threat_report['total_unique_ips']}")
print(f" Suspicious IPs: {threat_report['suspicious_ips']}")
print(f" High-risk IPs: {len(threat_report['high_risk_ips'])}")

return threat_report

def extract_ips_from_logs(log_file_path):
"""Extract unique IP addresses from log file."""
import re

ip_pattern = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')
unique_ips = set()

try:
with open(log_file_path, 'r') as file:
for line in file:
ips = ip_pattern.findall(line)
for ip in ips:
# Basic validation
try:
ipaddress.ip_address(ip)
unique_ips.add(ip)
except ValueError:
continue

return unique_ips

except FileNotFoundError:
print(f"Log file not found: {log_file_path}")
return set()

def infrastructure_mapping(api_key, domain_list):
"""Map infrastructure for multiple domains."""
analyzer = IPIntelligenceAnalyzer(api_key)

print("πŸ—ΊοΈ Infrastructure Mapping")
print("=" * 50)

infrastructure_map = {}

for domain in domain_list:
print(f"\nMapping infrastructure for: {domain}")

analysis = analyzer.analyze_ip_profile(domain)

if analysis:
result = analysis['ip_data']['result']

infrastructure_map[domain] = {
'resolved_ip': analysis['resolved_ip'],
'cloud_provider': result.get('cloud_provider', 'None'),
'organization': result.get('organization', 'Unknown'),
'country': result.get('country_name', 'Unknown'),
'is_cloud': result.get('is_cloud', False),
'is_cdn': result.get('is_cdn', False),
'infrastructure_type': analysis['infrastructure_type']
}

print(f" βœ… {infrastructure_map[domain]['infrastructure_type']}")
print(f" Provider: {infrastructure_map[domain]['organization']}")
print(f" Location: {infrastructure_map[domain]['country']}")

# Generate infrastructure summary
print(f"\nπŸ“ˆ Infrastructure Summary:")

cloud_providers = {}
countries = {}

for domain, info in infrastructure_map.items():
provider = info['cloud_provider'] or info['organization']
cloud_providers[provider] = cloud_providers.get(provider, 0) + 1

country = info['country']
countries[country] = countries.get(country, 0) + 1

print(f"\n☁️ Provider Distribution:")
for provider, count in sorted(cloud_providers.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" {provider}: {count} domains")

print(f"\n🌍 Geographic Distribution:")
for country, count in sorted(countries.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" {country}: {count} domains")

return infrastructure_map

# Usage for advanced workflows
api_key = "your-api-key-here"

# Threat hunting workflow
# threat_report = threat_hunting_workflow(api_key, "/var/log/access.log")

# Infrastructure mapping
company_domains = ["example.com", "api.example.com", "www.example.com"]
infra_map = infrastructure_mapping(api_key, company_domains)

Use Cases​

Threat Intelligence​

  • Investigate suspicious IP addresses in security incidents
  • Analyze infrastructure patterns of threat actors
  • Correlate IP addresses with geographic and organizational data

Incident Response​

  • Quickly gather intelligence on IP addresses involved in security incidents
  • Assess risk levels of network connections
  • Validate geographic and organizational claims

Network Security Monitoring​

  • Enrich firewall and IDS logs with IP intelligence
  • Identify high-risk connections and traffic patterns
  • Monitor for connections to suspicious infrastructure

Digital Forensics​

  • Investigate historical IP address usage
  • Correlate IP addresses with business entities
  • Support legal and compliance investigations

Infrastructure Analysis​

  • Map organizational digital infrastructure
  • Analyze cloud and CDN usage patterns
  • Monitor infrastructure changes and migrations

Best Practices​

API Usage​

  1. Batch Processing: Process multiple IPs efficiently
  2. Caching: Cache results to reduce API calls for repeated lookups
  3. Rate Limiting: Respect API rate limits for large-scale analysis
  4. Error Handling: Implement proper error handling and retry logic

Security Analysis​

  1. Context Awareness: Consider business context when assessing risk
  2. Multi-Source Validation: Combine with other intelligence sources
  3. Regular Updates: Refresh IP intelligence data regularly

Integration Tips​

  1. SIEM Integration: Feed IP intelligence into security monitoring systems
  2. Automated Enrichment: Automatically enrich security alerts with IP data
  3. Dashboard Creation: Create dashboards for IP intelligence monitoring
  4. Alert Correlation: Correlate IP intelligence with other security events