网络安全溯源实战:78.1%网络攻击来自境外,如何精准定位攻击源

0 阅读6分钟

一、数据解读:境外攻击比例已超“警戒线”

2025年5月,工信部下属机构监测发现,由境外IP发起的网络攻击达144.09万次,占网络攻击总量的78.1%,攻击来源覆盖113个国家和地区,其中源自美国的攻击最多,达87.49万次,占境外攻击总数的60.7%。9月的数据显示,境外IP攻击虽回落至61.1%的占比(183.86万次),但整体规模仍在高位震荡,攻击来源扩展至124个国家。

更具代表性的事件是2025年哈尔滨亚冬会。赛事期间,信息系统共遭境外网络攻击270167次,封禁高危恶意IP地址12602个。其中美国攻击次数最高,达170864次,占比63.24%。

这些数据揭示了一个现实:溯源能力不再只是应急响应的“备选”,而是网络安全建设的“必选项”。

二、IP溯源的核心逻辑:从攻击日志到可操作情报

IP溯源的本质,是从攻击链的源头节点入手,将零散的攻击日志转化为可用于决策的威胁情报。技术路径可以归纳为以下步骤:

1. 日志提取:从WAF、防火墙、服务器访问日志中抓取恶意请求的源IP;

2. IP定位:调用IP定位API接口或离线IP库,获取攻击源的地理位置、运营商信息;

3. 风险关联:结合IP的历史行为数据和威胁情报库,评估该IP的风险等级。

4.25-IP定位API接口-内文图1.jpeg

IP溯源三步骤流程图

在实际操作中,一个攻击IP的价值不只在于定位它来自哪个城市,还在于识别它属于哪种网络类型——是住宅宽带,还是数据中心/VPS,抑或是代理/VPN节点。这直接决定了应对策略:住宅IP可能是被劫持的普通用户设备,而VPS上的攻击源则更可能存在持续、有组织的攻击行为。IP定位API接口在这一环节中承担了快速、自动化的地理与网络属性解析任务,是溯源流程的“第一道门”。

以IP数据云提供的定位服务为例,其接口返回字段涵盖国家、城市、运营商、ASN及代理类型,开发者可直接集成至溯源脚本中,实现分钟级的攻击源画像输出。

三、实战案例:一次暴力破解攻击背后的基础设施溯源

2025年,安全团队Huntress在处理一起RDP服务器的暴力破解警报时发现,攻击者成功破解了一个账户凭证,但与典型入侵不同,登录记录来自多个IP地址,这引起了分析师的警觉。团队随即对相关IP进行深入追溯,通过分析TLS证书发现了一个恶意域名specialsseason.com,顺藤摸瓜关联出大量采用“NL-<国家代码>”命名规则的子域名——一个遍布全球多国的初始访问代理基础设施网络逐步浮出水面。这一案例说明:单一IP的背后可能隐藏着庞大的攻击基础设施集群,而这种深度关联分析的起点,恰恰是对IP归属和网络属性的精准定位。在实际溯源工作中,安全团队常借助IP数据云这类专业IP地理位置库,快速区分攻击源是普通住宅带宽还是机房VPS,从而判断攻击行为的组织化程度。

4.25-IP定位API接口-内文图2.jpeg

暴力破解攻击溯源示意图

四、代码实操:从日志到溯源的工具链

以下是一个简化的IP溯源脚本示例。它批量读取攻击日志中的IP地址,调用IP定位API接口获取地理和网络信息,并输出汇总报告:

import requests
import json
from collections import Counter

def query_ip_location(ip, api_key, timeout=(3.05, 10)):
    """
    查询单个IP的地理位置和代理信息
    :param ip: 目标IP地址
    :param api_key: API密钥
    :param timeout: 连接超时(秒)和读取超时(秒)的元组
    :return: 包含定位信息的字典,失败时返回error字段
    """
    api_url = "https://api.ipdatacloud.com/v1/ip-location"
    params = {
        "key": api_key,
        "ip": ip,
        "fields": "country,city,region,isp,asn,proxy_type"
    }
    try:
        response = requests.get(api_url, params=params, timeout=timeout)
        response.raise_for_status()  # 自动处理4xx/5xx状态码
        data = response.json()
        
        # 检查API返回的业务状态码
        if data.get("code") == 200 and "data" in data:
            return data["data"]
        else:
            error_msg = data.get("message", "Unknown API error")
            return {"error": f"API error: {error_msg}"}
    except requests.exceptions.Timeout:
        return {"error": "Request timeout"}
    except requests.exceptions.RequestException as e:
        return {"error": f"Network error: {str(e)}"}
    except (KeyError, ValueError, json.JSONDecodeError) as e:
        return {"error": f"Response parsing error: {str(e)}"}
 
def batch_ip_trace(ip_list, api_key, delay=0.5):
    """
    批量处理IP地址并生成溯源报告
    :param ip_list: IP地址列表
    :param api_key: API密钥
    :param delay: 每次请求之间的延迟(秒),避免触发限流
    :return: 统计报告字典
    """
    import time
    report = {
        "total": len(ip_list),
        "by_country": Counter(),
        "bad_ips": [],
        "details": {}
    }
    # 代理类型黑名单常量
    PROXY_BLACKLIST = {"vpn", "proxy", "tor", "hosting"}
    
    for idx, ip in enumerate(ip_list[:50]):  # 限制批量查询数量
        result = query_ip_location(ip, api_key)
        if "error" not in result:
            country = result.get("country", "Unknown")
            isp = result.get("isp", "Unknown")
            proxy_type = result.get("proxy_type", "").lower()
            report["by_country"][country] += 1
            report["details"][ip] = {
                "country": country,
                "isp": isp,
                "proxy_type": proxy_type if proxy_type else "none"
            }
            if proxy_type in PROXY_BLACKLIST:
                report["bad_ips"].append(ip)
        else:
            report["details"][ip] = {"error": result["error"]}
        
        # 控制请求频率,避免API限流
        if idx < len(ip_list) - 1:
            time.sleep(delay)
    return report
 
# 使用示例(请替换为真实API Key)
API_KEY = "YOUR_API_KEY_HERE"
sample_ips = [
    "45.33.89.124",   # 示例攻击IP
    "185.130.5.225",
    "103.139.44.15"
]

result = batch_ip_trace(sample_ips, API_KEY, delay=0.5)
print(json.dumps(result, indent=2, ensure_ascii=False))

运行上述脚本后,输出示例为:

{
  "total": 3,
  "by_country": {"US": 1, "DE": 1, "Unknown": 1},
  "bad_ips": ["185.130.5.225"],
  "details": {
    "45.33.89.124": {"country": "US", "isp": "Linode", "proxy_type": "hosting"},
    "185.130.5.225": {"country": "DE", "isp": "Hetzner", "proxy_type": "proxy"},
    "103.139.44.15": {"error": "API error: rate limit exceeded"}
  }
}

在生产环境中,可进一步集成威胁情报服务、自动化封禁模块和SIEM/SOAR平台,实现“定位-判定-处置”的全链路闭环。

五、数据来源说明

  •  工信部贵州省通信管理局:《工业互联网网络安全情况通报(2025年第5期)》,发布境外IP攻击占比78.1%、源自美国攻击占比60.7%等核心数据。
  •  国家计算机病毒应急处理中心:《2025年哈尔滨第九届亚冬会赛事信息系统遭境外网络攻击情况报告》,发布27万次攻击总次数、170864次来自美国、封禁12602个恶意IP等数据。

扩展思考:本脚本基于同步请求,适合小批量实时查询。当处理百万级访问日志时,建议改用离线IP库预加载 + 内存二分查找(O(logN)),可将单IP判定延迟降至微秒级。您也可以将代理类型检测集成到WAF或网关中间件,实现实时阻断。