如何在Python中发送带有指定十六进制负载的IP数据包?

1 投票
3 回答
14023 浏览
提问于 2025-04-16 07:48

我抓取了一个IGMP数据包,现在我想用Python发送它。有没有办法像这样发送数据包

0x0000   01 00 5E 00 43 67 00 02-B3 C8 7F 44 81 00 00 DE   ..^.Cg..іИD?..Ю
0x0010   08 00 46 00 00 20 00 01-00 00 01 02 36 4C C0 A8   ..F.. ......6LАЁ
0x0020   00 7B EA 00 43 67 94 04-00 00 16 00 BC 97 EA 00   .{к.Cg”.....ј—к.
0x0030   43 67                                             Cg

而不使用像impacket这样的数据包生成器呢?

更新一下,我尝试使用原始套接字,像这样:

dst = '234.0.67.103'

# Open a raw socket.
s = socket.socket(socket.AF_INET, socket.SOCK_RAW,2)

res=''

temp='01 00 5E 00 43 67 00 02 B3 C8 7F 44 81 00 00 DE 08 00 46 00 00 20 00 01 00 00 01 02 36 4C C0 A8 00 7B EA 00 43 67 94 04 00 00 16 00 BC 97 EA 00 43 67'
for i in temp.split(' '):
    res+=chr(int(i, 16))
print res
s.sendto(res, (dst, 0))

一切都很好,除了一个小问题……

如果我抓取那个数据包,它看起来是这样的:

0x0000   01 00 5E 00 43 67 00 02-B3 C8 7F 44 08 00 45 00   ..^.Cg..іИD..E.
0x0010   00 46 07 06 00 00 01 02-C4 25 C0 A8 00 7B EA 00   .F......Д%АЁ.{к.
0x0020   43 67 01 00 5E 00 43 67-00 02 B3 C8 7F 44 81 00   Cg..^.Cg..іИDЃ.
0x0030   00 DE 08 00 46 00 00 20-00 01 00 00 01 02 36 4C   .Ю..F.. ......6L
0x0040   C0 A8 00 7B EA 00 43 67-94 04 00 00 16 00 BC 97   АЁ.{к.Cg”.....ј—
0x0050   EA 00 43 67                                       к.Cg

如你所见,出于某种原因,Python忽略了我的头部信息,自己生成了新的。那我该怎么解决这个问题呢?

3 个回答

1

下面是对你代码的修改,这段代码可以发送原始数据包:

import socket

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, 0x8100)
s.bind(('eth0', 0x8100))

res=''
temp='01 00 5E 00 43 67 00 02 B3 C8 7F 44 81 00 00 DE 08 00 46 00 00 20 00 01 00 00 01 02 36 4C C0 A8 00 7B EA 00 43 67 94 04 00 00 16 00 BC 97 EA 00 43 67'
for i in temp.split(' '):
    res+=chr(int(i, 16))
s.send(res)
6

根据《Unix网络编程》第三版的内容:

sockfd = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
# inform os about that program are compose ip header
sockfd.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, True)
2

好的,按照我的理解,做到这一点的唯一方法是以这样的方式使用scapy:

from scapy.all import *
a=Ether(import_hexcap())
<some dumped hex>
sendp(a)

撰写回答