Scapy - 发送 IPv6 路由器广告失败,生命周期 > 0
Scapy - sending IPv6 Router Advertisement failing with lifetime > 0
我正在尝试使用 Scapy 创建一个工具,通过向 FF02::1 多播地址发送伪造的路由器通告来发现 link- 本地 IPv6 主机。
*SNIP*
router_advertisement = scapy.IPv6(src=ra_src_addr, dst='FF02::1')/scapy.ICMPv6ND_RA(routerlifetime=0, reachabletime=0)/scapy.ICMPv6NDOptSrcLLAddr(lladdr=hw_addr)/scapy.ICMPv6NDOptPrefixInfo(prefixlen=64, validlifetime=0x6, preferredlifetime=0x6, prefix='dead::')
answer, unanswer = scapy.sr(router_advertisement, timeout=10, multi=True)
for reply in answer:
print(reply[1][scapy.Ether].src + ' : ' + reply[1]scapy.IPv6].src)
剪辑上方的所有内容主要是设置路由器广告的参数(ra_prefix、hw_addr 等)。我已将完整脚本放在 pastebin 上以避免混淆问题:http://pastebin.com/4Q3JheXh
上面的问题是,当 Scapy 成功发送路由器广告数据包时,我看到了邻居请求响应,但在我可以使用 sr() 查看答案之前,Scapy 正在错误退出。
完整输出:
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
Finished to send 1 packets.
...Traceback (most recent call last):
File "find_ipv6_local.py", line 40, in <module>
answer, unanswer = scapy.sr(router_advertisement, timeout=10, multi=True)
File "/usr/lib/python2.7/site-packages/scapy/sendrecv.py", line 317, in sr
a,b=sndrcv(s,x,*args,**kargs)
File "/usr/lib/python2.7/site-packages/scapy/sendrecv.py", line 141, in sndrcv
h = r.hashret()
File "/usr/lib/python2.7/site-packages/scapy/layers/inet6.py", line 423, in hashret
return struct.pack("B", nh)+self.payload.hashret()
File "/usr/lib/python2.7/site-packages/scapy/packet.py", line 711, in hashret
return self.payload.hashret()
File "/usr/lib/python2.7/site-packages/scapy/layers/inet6.py", line 1317, in hashret
return struct.pack("HH",self.mladdr)+self.payload.hashret()
struct.error: pack expected 2 items for packing (got 1)
有趣的是,当我将 validlifetime 和 preferredlifetime 设置为 0 时,Scapy 不会崩溃和燃烧。然而,这并没有多大用处,因为 0 的生命周期不会给我任何响应。
我是不是在脚本的某个地方搞砸了,或者 Scapy 在 IPv6 方面有点 off?
我认为 scapy
在这方面有点狡猾。您的通告在这里:
return struct.pack("HH",self.mladdr)+self.payload.hashret()
应包含以下内容:
return struct.pack("HH", 0, 0)+""
那struct.pack
是没机会的,至少应该是:
return struct.pack("HH", *self.mladdr)+self.payload.hashnet()
所以struct.pack
没有机会接收到"HH"需要的两个参数。 是一个错误。
由于您不关心负载,您可以将 ICMPv6MLQuery
的 scapy 代码更改为:
class ICMPv6MLQuery(_ICMPv6ML): # RFC 2710
name = "MLD - Multicast Listener Query"
type = 130
mrd = 10000
mladdr = "::" # 10s for mrd
overload_fields = {IPv6: { "dst": "ff02::1", "hlim": 1, "nh": 58 }}
def hashret(self):
if self.mladdr != "::":
return struct.pack("HH",self.mladdr)+self.payload.hashret()
else:
return self.payload.hashret()
至
class ICMPv6MLQuery(_ICMPv6ML): # RFC 2710
name = "MLD - Multicast Listener Query"
type = 130
mrd = 10000
mladdr = "::" # 10s for mrd
overload_fields = {IPv6: { "dst": "ff02::1", "hlim": 1, "nh": 58 }}
def hashret(self):
return self.payload.hashret()
即干掉 struct.pack
。
另外注意:这个:
WARNING: No route found for IPv6 destination :: (no default route?)
可能会阻止您收到答复(NIC 可能会认为什么都没有到达并忽略它)。至少配置一些简单的路由是明智的,例如
$ route -6
Kernel IPv6 routing table
Destination Next Hop Flag Met Ref Use If
::/0 [::] U 256 0 0 eth0
您可能想尝试 Scapy pull request #335 中提出的修复方法。
编辑:修复已经合并,所以如果你有同样的问题,你现在要做的就是升级 Scapy!
我正在尝试使用 Scapy 创建一个工具,通过向 FF02::1 多播地址发送伪造的路由器通告来发现 link- 本地 IPv6 主机。
*SNIP*
router_advertisement = scapy.IPv6(src=ra_src_addr, dst='FF02::1')/scapy.ICMPv6ND_RA(routerlifetime=0, reachabletime=0)/scapy.ICMPv6NDOptSrcLLAddr(lladdr=hw_addr)/scapy.ICMPv6NDOptPrefixInfo(prefixlen=64, validlifetime=0x6, preferredlifetime=0x6, prefix='dead::')
answer, unanswer = scapy.sr(router_advertisement, timeout=10, multi=True)
for reply in answer:
print(reply[1][scapy.Ether].src + ' : ' + reply[1]scapy.IPv6].src)
剪辑上方的所有内容主要是设置路由器广告的参数(ra_prefix、hw_addr 等)。我已将完整脚本放在 pastebin 上以避免混淆问题:http://pastebin.com/4Q3JheXh
上面的问题是,当 Scapy 成功发送路由器广告数据包时,我看到了邻居请求响应,但在我可以使用 sr() 查看答案之前,Scapy 正在错误退出。
完整输出:
WARNING: No route found for IPv6 destination :: (no default route?)
Begin emission:
Finished to send 1 packets.
...Traceback (most recent call last):
File "find_ipv6_local.py", line 40, in <module>
answer, unanswer = scapy.sr(router_advertisement, timeout=10, multi=True)
File "/usr/lib/python2.7/site-packages/scapy/sendrecv.py", line 317, in sr
a,b=sndrcv(s,x,*args,**kargs)
File "/usr/lib/python2.7/site-packages/scapy/sendrecv.py", line 141, in sndrcv
h = r.hashret()
File "/usr/lib/python2.7/site-packages/scapy/layers/inet6.py", line 423, in hashret
return struct.pack("B", nh)+self.payload.hashret()
File "/usr/lib/python2.7/site-packages/scapy/packet.py", line 711, in hashret
return self.payload.hashret()
File "/usr/lib/python2.7/site-packages/scapy/layers/inet6.py", line 1317, in hashret
return struct.pack("HH",self.mladdr)+self.payload.hashret()
struct.error: pack expected 2 items for packing (got 1)
有趣的是,当我将 validlifetime 和 preferredlifetime 设置为 0 时,Scapy 不会崩溃和燃烧。然而,这并没有多大用处,因为 0 的生命周期不会给我任何响应。
我是不是在脚本的某个地方搞砸了,或者 Scapy 在 IPv6 方面有点 off?
我认为 scapy
在这方面有点狡猾。您的通告在这里:
return struct.pack("HH",self.mladdr)+self.payload.hashret()
应包含以下内容:
return struct.pack("HH", 0, 0)+""
那struct.pack
是没机会的,至少应该是:
return struct.pack("HH", *self.mladdr)+self.payload.hashnet()
所以struct.pack
没有机会接收到"HH"需要的两个参数。 是一个错误。
由于您不关心负载,您可以将 ICMPv6MLQuery
的 scapy 代码更改为:
class ICMPv6MLQuery(_ICMPv6ML): # RFC 2710
name = "MLD - Multicast Listener Query"
type = 130
mrd = 10000
mladdr = "::" # 10s for mrd
overload_fields = {IPv6: { "dst": "ff02::1", "hlim": 1, "nh": 58 }}
def hashret(self):
if self.mladdr != "::":
return struct.pack("HH",self.mladdr)+self.payload.hashret()
else:
return self.payload.hashret()
至
class ICMPv6MLQuery(_ICMPv6ML): # RFC 2710
name = "MLD - Multicast Listener Query"
type = 130
mrd = 10000
mladdr = "::" # 10s for mrd
overload_fields = {IPv6: { "dst": "ff02::1", "hlim": 1, "nh": 58 }}
def hashret(self):
return self.payload.hashret()
即干掉 struct.pack
。
另外注意:这个:
WARNING: No route found for IPv6 destination :: (no default route?)
可能会阻止您收到答复(NIC 可能会认为什么都没有到达并忽略它)。至少配置一些简单的路由是明智的,例如
$ route -6
Kernel IPv6 routing table
Destination Next Hop Flag Met Ref Use If
::/0 [::] U 256 0 0 eth0
您可能想尝试 Scapy pull request #335 中提出的修复方法。
编辑:修复已经合并,所以如果你有同样的问题,你现在要做的就是升级 Scapy!