3. OSPF攻击之伪造LSA:攻击原理、伪造Router-LSA、伪造Network-LSA

好,咱们接着聊OSPF攻击里最“经典”的一招——伪造LSA。

说实话,我在做安全评估的时候,遇到过不少网络工程师觉得OSPF很安全。“不就是个动态路由协议吗?内网跑的,能有啥问题?”嗯,每次听到这种话,我心里都会咯噔一下。你想想看,如果攻击者能伪造一个LSA,让全网的路由器都相信一条不存在的路径,那后果是什么?流量被劫持、数据被窃听、甚至整个网络瘫痪。

今天我就把伪造LSA这件事给你讲透。咱们分三块:攻击原理、伪造Router-LSA、伪造Network-LSA。

3.1 攻击原理:为什么LSA能被伪造?

OSPF的核心是LSA(链路状态通告)。每台路由器都会生成LSA,描述自己直连的链路和邻居。然后通过泛洪,让整个OSPF域内的路由器都收到这些LSA,最终每台路由器都有一张完整的网络拓扑图——LSDB(链路状态数据库)。

问题出在哪?

OSPF本身没有对LSA的发送者做强身份认证。默认情况下,OSPF只靠Router ID来标识一台路由器。而Router ID是什么?就是一个32位的IP地址,明文传输的。攻击者只要知道网络里某台路由器的Router ID,就能伪造一个看起来“合法”的LSA。

核心攻击流程:

  1. 攻击者接入OSPF网络(物理接入或通过被控设备)
  2. 嗅探OSPF Hello报文,获取合法路由器的Router ID
  3. 构造伪造的LSA,包含虚假的链路信息
  4. 将伪造LSA注入网络,触发泛洪
  5. 其他路由器更新LSDB,计算错误的路由表

我遇到过最典型的案例:某公司内网被植入了一台恶意设备,攻击者伪造了一个Router-LSA,声称自己有一条到核心数据库服务器的“最优路径”。结果所有流量都绕道经过这台恶意设备,数据被完整抓包分析了一个月才被发现。

注意:OSPF支持MD5认证,但很多网络在部署时为了省事,直接用了空认证或明文认证。这等于把大门敞开了。我建议,只要条件允许,OSPF一定要启用MD5或HMAC-SHA认证。

3.2 伪造Router-LSA:让全网相信一个假的路由器

Router-LSA是OSPF里最基础的LSA类型(Type 1)。每台路由器都会生成一个Router-LSA,描述自己直连的链路和邻居。伪造Router-LSA,说白了就是让全网相信存在一台“假路由器”,或者让一台真实路由器的链路信息被篡改。

伪造Router-LSA的关键字段:

字段 作用 攻击者篡改方式
Link State ID 等于生成路由器的Router ID 直接伪造一个不存在的Router ID
Advertising Router 通告该LSA的路由器 与Link State ID一致
Link ID 邻居的Router ID或网络号 指向攻击者控制的设备
Link Data 接口IP地址或掩码 伪造虚假的IP
Type 链路类型(1=点对点,2=Transit,3=Stub,4=虚链路) 可随意篡改
Metric 链路开销 设置为极低值,吸引流量

举个例子。假设网络里有一台合法路由器R1(Router ID 1.1.1.1)。攻击者伪造一个Router-LSA,Link State ID设为2.2.2.2(一台不存在的路由器),然后声称2.2.2.2通过一条开销为1的链路连接到核心交换机。其他路由器收到这个LSA后,会认为2.2.2.2是到达核心交换机的最优下一跳。而实际上,2.2.2.2是攻击者控制的设备。

避坑指南:我曾经在应急响应时遇到一个案例,攻击者伪造Router-LSA时,把Metric设成了0。OSPF规定Metric不能为0,但有些老版本的路由器实现不严格,直接接受了。结果全网路由震荡,业务中断了半小时。所以,检查LSA的Metric值是否异常,是发现伪造LSA的一个快速方法。

伪造Router-LSA的代码示例(Python + Scapy):

from scapy.all import *
from scapy.contrib.ospf import *

# 构造一个伪造的OSPF Hello报文,先获取合法Router ID
# 然后构造Router-LSA
fake_router_id = "2.2.2.2"
fake_adv_router = "2.2.2.2"

# 构造链路描述
link = OSPF_Link(
    link_type=2,  # Transit网络
    link_id="192.168.1.1",  # 邻居Router ID
    link_data="192.168.1.2",  # 接口IP
    metric=1
)

# 构造Router-LSA
lsa = OSPF_Router_LSA(
    link_state_id=fake_router_id,
    advertising_router=fake_adv_router,
    options=0x02,
    lsa_age=1,
    ls_type=1,
    link_count=1,
    links=[link]
)

# 封装到OSPF Update报文中
ospf_update = OSPF_Update(
    src="192.168.1.100",  # 攻击者IP
    dst="224.0.0.5",      # 所有OSPF路由器组播地址
    area=0,
    lsalist=[lsa]
)

# 发送
send(ospf_update, iface="eth0")

这段代码只是演示原理。实际攻击中,攻击者还需要处理序列号、校验和等细节,否则会被合法路由器拒绝。但核心思路就是这样——构造一个看起来合法的LSA,然后扔进网络里。

3.3 伪造Network-LSA:让全网相信一个假的网络

Network-LSA(Type 2)是由DR(指定路由器)生成的,描述一个广播网络(比如以太网段)上连接了哪些路由器。伪造Network-LSA,攻击者可以声称某个网段上存在不存在的路由器,或者篡改网段的掩码信息。

伪造Network-LSA的关键字段:

字段 作用 攻击者篡改方式
Link State ID DR的接口IP地址 伪造一个虚假的DR IP
Advertising Router DR的Router ID 与DR的Router ID一致
Network Mask 该网段的子网掩码 篡改为更小的掩码,扩大攻击范围
Attached Router 连接到该网段的路由器列表 添加攻击者控制的设备

伪造Network-LSA的典型场景:攻击者先通过某种方式成为DR(比如修改优先级),然后生成一个伪造的Network-LSA,声称该网段上连接了多台路由器。其他路由器收到后,会认为这个网段是网络的核心枢纽,所有流量都优先经过这里。

实战案例:有一次,某数据中心内部出现异常流量。我排查后发现,攻击者伪造了一个Network-LSA,把/24的网段掩码改成了/16。结果所有路由器都认为这个网段包含了大量IP地址,纷纷把流量发往攻击者控制的DR。这就是典型的“掩码篡改攻击”。

伪造Network-LSA的代码示例:

from scapy.all import *
from scapy.contrib.ospf import *

# 伪造DR的接口IP和Router ID
fake_dr_ip = "10.0.0.1"
fake_dr_router_id = "3.3.3.3"

# 构造Network-LSA
lsa = OSPF_Network_LSA(
    link_state_id=fake_dr_ip,
    advertising_router=fake_dr_router_id,
    network_mask="255.255.0.0",  # 伪造为/16掩码
    attached_routers=[
        "3.3.3.3",  # DR自己
        "4.4.4.4",  # 伪造的邻居
        "5.5.5.5"   # 伪造的邻居
    ]
)

# 封装到OSPF Update
ospf_update = OSPF_Update(
    src="10.0.0.100",
    dst="224.0.0.5",
    area=0,
    lsalist=[lsa]
)

send(ospf_update, iface="eth0")

这里有个细节:伪造Network-LSA时,攻击者必须确保自己确实是该网段的DR,或者至少让其他路由器相信自己是DR。否则,合法的DR会生成一个序列号更高的Network-LSA,把伪造的覆盖掉。

重要提醒:伪造LSA攻击的破坏力取决于攻击者的位置。如果攻击者在骨干区域(Area 0),那影响范围是整个OSPF域。如果攻击者在普通区域,影响范围仅限于该区域。所以,保护好骨干区域的路由器,是OSPF安全的第一道防线。

3.4 如何发现伪造LSA攻击?

说了这么多攻击手法,咱们也得聊聊怎么发现它。我总结了几条实战经验:

  • 检查LSA的序列号:合法路由器的LSA序列号是递增的。如果发现某个LSA的序列号异常大或异常小,很可能是伪造的。
  • 检查LSA的校验和:OSPF LSA有校验和字段。攻击者如果计算错误,校验和会不匹配。但专业的攻击者会正确计算,所以这招只能防“菜鸟”攻击者。
  • 检查Router ID是否重复:OSPF域内不允许出现重复的Router ID。如果发现两个不同的LSA声称来自同一个Router ID,那肯定有一个是伪造的。
  • 检查链路信息是否合理:比如,一个路由器声称自己连接到了一个不存在的网段,或者Metric值异常低。这些都需要人工判断。

我的习惯:在核心路由器上开启OSPF的LSA日志记录。虽然日志量很大,但配合SIEM系统做异常检测,能有效发现伪造LSA攻击。我曾经靠一条“Router ID 2.2.2.2 从未知接口出现”的日志,揪出了一个潜伏在机房的恶意设备。

3.5 防御建议

最后,给几条实在的防御建议:

  1. 启用OSPF认证:这是最有效的防御手段。用MD5或HMAC-SHA,别用明文认证。
  2. 限制OSPF邻居:在接口上配置OSPF邻居的IP白名单,只允许已知设备建立邻居关系。
  3. 使用被动接口:对于不需要建立OSPF邻居的接口,设置为被动接口(passive-interface),不发送Hello报文。
  4. 部署BGP防环机制:虽然OSPF本身有防环机制,但伪造LSA可能绕过。结合BGP的AS_PATH属性,可以增加一层防护。
  5. 定期审计LSDB:show ip ospf database命令查看LSDB,对比基线,发现异常LSA。

好了,关于OSPF伪造LSA攻击,我就讲这么多。记住,OSPF不是天生安全的,它需要你用心去保护。下次咱们聊聊OSPF的其他攻击手法,比如邻居欺骗和路由表污染。


公众号:蓝海资料掘金营,微信deep3321