发送的 Scapy 数据包收不到

Posted

技术标签:

【中文标题】发送的 Scapy 数据包收不到【英文标题】:Scapy packet sent cannot be received 【发布时间】:2013-12-09 15:31:03 【问题描述】:

我正在尝试使用以下命令发送带有 scapy 的 UDP 数据包:

>> send(IP(dst="127.0.0.1",src="111.111.111.111")/UDP(dport=5005)/"Hello")
.
Sent 1 packets.

tcpdump我可以看到:

22:02:58.384730 IP 111.111.111.111.domain > localhost.5005: [|domain]

我正在尝试使用以下代码接收此数据包:

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
    print "received message:", data

但收不到消息。

我测试过网络正常发送udp数据包,代码如下,可以接收到数据包:

import socket
import time

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
num = 0
while True:
  sock.sendto(str(num), (UDP_IP, UDP_PORT))
  print "Message sent: " + str(num)
  num += 1
  time.sleep(1)

任何帮助将不胜感激。

----------------更新-----------

Scapy 发送的无法接收的数据包:

13:22:52.984862 IP (tos 0x0, ttl 64, id 1, offset 0, flags [DF], proto UDP (17), length 33)
    127.0.0.1.5555 > 127.0.0.1.12345: [udp sum ok] UDP, length 5
    0x0000:  4500 0021 0001 4000 4011 3cc9 7f00 0001  E..!..@.@.<.....
    0x0010:  7f00 0001 15b3 3039 000d 9813 4865 6c6c  ......09....Hell
    0x0020:  6f     

                              o

而普通python脚本发送的可以接收的数据包:

13:20:02.374481 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 33)
    127.0.0.1.53143 > 127.0.0.1.12345: [bad udp cksum 0xfe20 -> 0xde2e!] UDP, length 5
    0x0000:  4500 0021 0000 4000 4011 3cca 7f00 0001  E..!..@.@.<.....
    0x0010:  7f00 0001 cf97 3039 000d fe20 4865 6c6c  ......09....Hell
    0x0020:  6f

【问题讨论】:

这些输出是在同一个界面上吗?两个数据包中的源 MAC 地址和目标 MAC 地址不同。在某些情况下,由于错误的目标 MAC 地址,数据包无法到达目标。 【参考方案1】:

看起来您正在使用 Scapy 将 UDP 流量发送到您的本地主机接口。在send() 函数中,指定适当的出接口以将流量发送出去。

例子:

send((IP(dst="127.0.0.1",src="111.111.111.111")/UDP(dport=5005)/"Hello"),iface="lo0")

在我的计算机上,lo0 是我的本地环回接口。要查看或设置 scapy 的默认界面,请查看这篇文章的下半部分:http://thepacketgeek.com/scapy-p-02-installing-python-and-scapy/

【讨论】:

谢谢垫子!我找到了ifconfig 并找到了eth0eth1lo。我尝试了所有方法,但仍然无法正常工作...... 既然你可以用 tcpdump 嗅探 Scapy 数据包,我认为这不是 Scapy 的问题。我发现了一个与此问题类似的线程:***.com/questions/17688061/… 我也有同样的问题。我创建了一个非 scapy 程序并且可以接收数据包。比较在 Wireshark 中工作的数据包和不工作的数据包,唯一的区别是 scapy 数据包使用第 2 层广播地址。如果我在数据包中指定 MAC 地址,scapy 会用广播地址覆盖我指定的 MAC 地址。【参考方案2】:

您可以使用 nfqueue 和 iptables: 你定义一个规则将你的数据包定向到队列,然后用你的脚本拦截它们。

这是一个基本的例子:

import nfqueue, socket
from scapy.all import *
import os

#add iptables rule
os.system('iptables -A OUTPUT -j NFQUEUE --queue-num 0')
#since you are sending packets from your machine you can get them in the OUPUT hook or even in the POSTROUTING hook.

#Set the callback for received packets. The callback should expect the payload:
def cb(payload):
    data = payload.get_data()
    p = IP(data)
    #your manipulation


q = nfqueue.queue()
q.open()
q.unbind(socket.AF_INET)
q.bind(socket.AF_INET)
q.set_callback(cb)
q.create_queue(0) #Same queue number of the rule

try:
    q.try_run()
except KeyboardInterrupt, e:
    os.system('iptables -t -F') #remove iptables rule
    print "interruption"
    q.unbind(socket.AF_INET)
    q.close()

【讨论】:

以上是关于发送的 Scapy 数据包收不到的主要内容,如果未能解决你的问题,请参考以下文章

如何将UDP数据包发送到scapy中的特定UDP dst端口?

python数据包之利器scapy详解!

Python 发包收包利器 - scapy

scapy - 基于python的数据包操作库

Scapy 伪造网络数据包

Python Scapy wrpcap - 如何将数据包附加到 pcap 文件?