mcpField
P
performing-ip-reputation-analysis-with-shodan

performing-ip-reputation-analysis-with-shodan

github.com/mukul975安全35.2k52 次安装8 周前更新
代码仓库

关于 performing-ip-reputation-analysis-with-shodan

面向安全分析人员的 Shodan IP 声誉分析技能,可丰富告警中的 IP 信息并评估威胁。它结合 Shodan API 与免费 InternetDB API,支持批量查询和基础设施关联。

主要功能

  1. 01查询开放端口、服务与漏洞
  2. 02检查证书、主机名及地理信息
  3. 03按威胁等级评估 IP 声誉
  4. 04批量查询与限速处理
  5. 05关联具有共同属性的主机

适用场景

  1. 01丰富安全告警中的 IP 信息
  2. 02调查可疑 IP 的暴露服务
  3. 03批量筛查 IP 地址
  4. 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 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
scripts/
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 用于高容量查询

参考资料

评论

支持 Markdown