Scapy packet sent cannot be received

2020-07-10 11:58发布

问题:

I'm trying to send UDP Packets with scapy with the following command:

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

And from tcpdump I can see:

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

I'm trying to receive this packet with the following code:

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

But cannot receive the message.

I have tested the network by sending udp packets normally with the following code and the packet can be received:

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)

Any help will be greatly appreciated.

----------------Updates-----------------------

A packet sent by Scapy that can not be received:

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

While a packet sent by normal python script that can be received:

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

回答1:

Looks like you are using Scapy to send the UDP traffic to your localhost interface. In the send() function, specify the appropriate outbound interface to send the traffic out.

Example:

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

On my computer, the lo0 is my local loopback interface. To see or set the default interface for scapy, check out the bottom half of this post: http://thepacketgeek.com/scapy-p-02-installing-python-and-scapy/



回答2:

You can use nfqueue and iptables: you define a rule to direct your packets to the queue and then intercept them with your script.

Here is a basic example:

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()