关于 performing-ip-reputation-analysis-with-shodan
面向安全分析人员的 Shodan IP 声誉分析技能,可丰富告警中的 IP 信息并评估威胁。它结合 Shodan API 与免费 InternetDB API,支持批量查询和基础设施关联。
主要功能
- 01查询开放端口、服务与漏洞
- 02检查证书、主机名及地理信息
- 03按威胁等级评估 IP 声誉
- 04批量查询与限速处理
- 05关联具有共同属性的主机
适用场景
- 01丰富安全告警中的 IP 信息
- 02调查可疑 IP 的暴露服务
- 03批量筛查 IP 地址
- 04关联攻击基础设施
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill performing-ip-reputation-analysis-with-shodan安装后在 Claude Code 中输入/performing-ip-reputation-analysis-with-shodan确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
使用 Shodan 执行 IP 信誉分析
概述
Shodan 是全球首个针对互联网连接设备的搜索引擎,持续扫描 IPv4 和 IPv6 地址空间,编目开放端口、运行中的服务、SSL 证书以及已知漏洞。本技能涵盖使用 Shodan API 和 InternetDB 免费 API 来丰富安全告警中的 IP 地址、基于暴露的服务和漏洞评估威胁等级、识别托管基础设施模式,以及将 IP 信誉数据集成到 SOC 分诊和威胁情报工作流中。
何时使用
- 在开展涉及使用 Shodan 执行 IP 信誉分析的安全评估时
- 在遵循相关安全事件的事件响应流程时
- 在执行计划的安全测试或审计活动时
- 在通过动手测试验证安全控制时
前提条件
- Python 3.9+ 及
shodan库(pip install shodan) - Shodan API 密钥(免费套餐:查询次数有限;付费计划可提高限额并支持流式数据)
- 了解 TCP/UDP 端口、常见服务和 CVE 标识符
- 熟悉 ASN、CIDR 表示法和 IP 地理位置概念
- 具备解读扫描结果的网络安全知识
关键概念
Shodan 数据模型
Shodan 中的每条 IP 记录包含:开放端口和协议、banner 数据(服务响应)、SSL/TLS 证书详情、已知 CVE 漏洞、主机名和反向 DNS、ASN 和 ISP 信息、地理位置、操作系统指纹,以及显示随时间变化的历史扫描数据。
InternetDB API
Shodan 的免费 InternetDB API(internetdb.shodan.io)无需身份验证即可提供快速 IP 查询,返回开放端口、主机名、标签、CPE 和已知漏洞。这对于完整 Shodan API 会触及速率限制的高容量数据丰富场景非常有用。
信誉评分
IP 信誉通过组合以下因素进行评估:开放端口的数量和类型(异常端口表明已遭入侵)、存在漏洞的服务(存在已知 CVE 的未修补软件)、托管类型(住宅、云、VPN/代理、防弹托管)、历史活动(过去与恶意软件、扫描、垃圾邮件的关联),以及地理背景(以特定威胁活动著称的国家)。
工作流
步骤 1:使用 Shodan API 进行基础 IP 丰富
import shodan
import json
from datetime import datetime
class ShodanEnricher:
def __init__(self, api_key):
self.api = shodan.Shodan(api_key)
self.info = self.api.info()
print(f"[+] Shodan API initialized. Credits: {self.info.get('scan_credits', 0)}")
def enrich_ip(self, ip_address):
"""Full enrichment of an IP address via Shodan."""
try:
host = self.api.host(ip_address)
enrichment = {
"ip": ip_address,
"organization": host.get("org", ""),
"asn": host.get("asn", ""),
"isp": host.get("isp", ""),
"country": host.get("country_name", ""),
"country_code": host.get("country_code", ""),
"city": host.get("city", ""),
"latitude": host.get("latitude"),
"longitude": host.get("longitude"),
"os": host.get("os", ""),
"ports": host.get("ports", []),
"hostnames": host.get("hostnames", []),
"domains": host.get("domains", []),
"vulns": host.get("vulns", []),
"tags": host.get("tags", []),
"last_update": host.get("last_update", ""),
"services": [],
}
for service in host.get("data", []):
svc = {
"port": service.get("port", 0),
"transport": service.get("transport", "tcp"),
"product": service.get("product", ""),
"version": service.get("version", ""),
"module": service.get("_shodan", {}).get("module", ""),
"banner": service.get("data", "")[:200],
}
if "ssl" in service:
svc["ssl_subject"] = service["ssl"].get("cert", {}).get("subject", {})
svc["ssl_issuer"] = service["ssl"].get("cert", {}).get("issuer", {})
svc["ssl_expires"] = service["ssl"].get("cert", {}).get("expires", "")
enrichment["services"].append(svc)
# Calculate reputation score
enrichment["reputation"] = self._calculate_reputation(enrichment)
print(f"[+] {ip_address}: {len(enrichment['ports'])} ports, "
f"{len(enrichment['vulns'])} vulns, "
f"reputation: {enrichment['reputation']['level']}")
return enrichment
except shodan.APIError as e:
print(f"[-] Shodan error for {ip_address}: {e}")
return None
def _calculate_reputation(self, data):
"""Calculate IP reputation score based on Shodan data."""
score = 0
factors = []
# Vulnerability assessment
vuln_count = len(data.get("vulns", []))
if vuln_count > 10:
score += 40
factors.append(f"{vuln_count} known vulnerabilities")
elif vuln_count > 5:
score += 25
factors.append(f"{vuln_count} known vulnerabilities")
elif vuln_count > 0:
score += 10
factors.append(f"{vuln_count} known vulnerabilities")
# Suspicious port analysis
suspicious_ports = {4444, 5555, 6666, 8888, 9090, 1234, 31337,
6667, 6697, 8080, 8443, 3128, 1080}
open_ports = set(data.get("ports", []))
sus_found = open_ports.intersection(suspicious_ports)
if sus_found:
score += 15
factors.append(f"suspicious ports: {sus_found}")
# Tag-based assessment
malicious_tags = {"self-signed", "cloud", "vpn", "proxy", "tor"}
tags = set(data.get("tags", []))
mal_tags = tags.intersection(malicious_tags)
if mal_tags:
score += 10
factors.append(f"tags: {mal_tags}")
# Too many open ports
port_count = len(data.get("ports", []))
if port_count > 20:
score += 15
factors.append(f"excessive open ports ({port_count})")
level = (
"critical" if score >= 50
else "high" if score >= 35
else "medium" if score >= 15
else "low"
)
return {"score": score, "level": level, "factors": factors}
def enrich_ip_free(self, ip_address):
"""Quick IP enrichment using free InternetDB API."""
import requests
resp = requests.get(f"https://internetdb.shodan.io/{ip_address}", timeout=10)
if resp.status_code == 200:
data = resp.json()
print(f"[+] InternetDB: {ip_address} -> "
f"{len(data.get('ports', []))} ports, "
f"{len(data.get('vulns', []))} vulns")
return data
return None
enricher = ShodanEnricher("YOUR_SHODAN_API_KEY")
result = enricher.enrich_ip("8.8.8.8")
print(json.dumps(result, indent=2, default=str))
步骤 2:批量 IP 信誉检查
import time
def batch_ip_reputation(enricher, ip_list, output_file="ip_reputation.json"):
"""Check reputation for a list of IP addresses."""
results = []
for i, ip in enumerate(ip_list):
result = enricher.enrich_ip(ip)
if result:
results.append(result)
if (i + 1) % 10 == 0:
print(f" [{i+1}/{len(ip_list)}] Processed")
time.sleep(1) # Rate limiting
# Sort by reputation score (highest risk first)
results.sort(key=lambda x: x.get("reputation", {}).get("score", 0), reverse=True)
with open(output_file, "w") as f:
json.dump(results, f, indent=2, default=str)
# Summary
levels = {"critical": 0, "high": 0, "medium": 0, "low": 0}
for r in results:
level = r.get("reputation", {}).get("level", "low")
levels[level] += 1
print(f"\n=== Batch Reputation Summary ===")
print(f"Total IPs: {len(results)}")
for level, count in levels.items():
print(f" {level.upper()}: {count}")
return results
suspicious_ips = ["203.0.113.1", "198.51.100.5", "192.0.2.100"]
results = batch_ip_reputation(enricher, suspicious_ips)
步骤 3:基础设施关联
def correlate_infrastructure(enricher, ip_address):
"""Find related infrastructure based on shared attributes."""
host_data = enricher.enrich_ip(ip_address)
if not host_data:
return {}
correlations = {
"same_org": [],
"same_asn": [],
"shared_ssl": [],
}
# Search for same organization
org = host_data.get("organization", "")
if org:
try:
results = enricher.api.search(f'org:"{org}"', limit=20)
for match in results.get("matches", []):
correlations["same_org"].append({
"ip": match.get("ip_str", ""),
"port": match.get("port", 0),
"product": match.get("product", ""),
})
except shodan.APIError:
pass
# Search for same SSL certificate
for service in host_data.get("services", []):
ssl_subject = service.get("ssl_subject", {})
if ssl_subject:
cn = ssl_subject.get("CN", "")
if cn:
try:
results = enricher.api.search(f'ssl.cert.subject.CN:"{cn}"', limit=20)
for match in results.get("matches", []):
correlations["shared_ssl"].append({
"ip": match.get("ip_str", ""),
"cn": cn,
})
except shodan.APIError:
pass
print(f"[+] Infrastructure correlations for {ip_address}:")
print(f" Same org: {len(correlations['same_org'])} hosts")
print(f" Shared SSL: {len(correlations['shared_ssl'])} hosts")
return correlations
验证标准
- Shodan API 已使用正确的身份验证成功查询
- IP 丰富返回端口、服务、漏洞和地理位置
- 信誉评分按威胁等级对 IP 进行分类
- 批量丰富正确处理速率限制
- 基础设施关联识别出相关主机
- InternetDB 免费 API 用于高容量查询