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
Parameter | Required | Type | Description |
---|---|---|---|
query | Yes | string | IP 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
Field | Type | Description |
---|---|---|
other_ips | array | Other IP addresses resolved for the query (IPv6, etc.) |
query | string | Original query (domain or IP) |
resolved_query | string | IP address resolved from domain query |
resolvable | boolean | Whether the query was resolvable |
result | object | Detailed IP information |
Result Object Fieldsβ
Field | Type | Description |
---|---|---|
asn | integer | Autonomous System Number |
cdn_provider | string | CDN provider if applicable |
cdn_region | string | CDN region if applicable |
city_name | string | City name |
cloud_provider | string | Cloud provider (AWS, GCP, Azure, etc.) |
cloud_region | string | Cloud region |
country_code | string | ISO country code |
country_name | string | Country name |
hosts_count | integer | Number of hosts associated with this IP |
ip_address | string | IP address |
ip_decimal | string | IP address in decimal format |
is_cdn | boolean | Whether IP belongs to a CDN |
is_cloud | boolean | Whether IP belongs to a cloud provider |
is_cloudflare | boolean | Whether IP belongs to Cloudflare |
is_ipv4 | boolean | Whether IP is IPv4 |
is_ipv6 | boolean | Whether IP is IPv6 |
is_private | boolean | Whether IP is in private range |
is_public | boolean | Whether IP is public |
isp | string | Internet Service Provider |
location_latitude | float | Geographic latitude |
location_longitude | float | Geographic longitude |
organization | string | Organization name |
postal_code | string | Postal code |
ptr | array | PTR DNS records |
region | string | Geographic 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β
- Batch Processing: Process multiple IPs efficiently
- Caching: Cache results to reduce API calls for repeated lookups
- Rate Limiting: Respect API rate limits for large-scale analysis
- Error Handling: Implement proper error handling and retry logic
Security Analysisβ
- Context Awareness: Consider business context when assessing risk
- Multi-Source Validation: Combine with other intelligence sources
- Regular Updates: Refresh IP intelligence data regularly
Integration Tipsβ
- SIEM Integration: Feed IP intelligence into security monitoring systems
- Automated Enrichment: Automatically enrich security alerts with IP data
- Dashboard Creation: Create dashboards for IP intelligence monitoring
- Alert Correlation: Correlate IP intelligence with other security events