2017-06-01 118 views
2

我也跟着下面的教程,在Python中实现数据包嗅探器:嗅嗅和发送UDP流量使用Scapy的

http://www.binarytides.com/python-packet-sniffer-code-linux/

在接收到每个UDP数据包,我想送一个已经保存的PCAP文件(测试.pcap)。以下片段显示了我的实现:

# receive a packet 
while True: 
    packet = s.recvfrom(65565) 

    #packet string from tuple 
    packet = packet[0] 

    #parse ethernet header 
    eth_length = 14 

    eth_header = packet[:eth_length] 
    eth = unpack('!6s6sH' , eth_header) 
    eth_protocol = socket.ntohs(eth[2]) 
    print 'Destination MAC : ' + eth_addr(packet[0:6]) + ' Source MAC : ' + 
    eth_addr(packet[6:12]) + ' Protocol : ' + str(eth_protocol) 

    if eth_addr(packet[6:12]) != my_MAC_address: 

     #Parse IP packets, IP Protocol number = 8 
     if eth_protocol == 8 : 
     #Parse IP header 
     #take first 20 characters for the ip header 
     ip_header = packet[eth_length:20+eth_length] 

     #now unpack them :) 
     iph = unpack('!BBHHHBBH4s4s' , ip_header) 

     version_ihl = iph[0] 
     version = version_ihl >> 4 
     ihl = version_ihl & 0xF 

     iph_length = ihl * 4 

     ttl = iph[5] 
     protocol = iph[6] 
     s_addr = socket.inet_ntoa(iph[8]); 
     d_addr = socket.inet_ntoa(iph[9]); 

     print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr) 


     #UDP packets 
     if protocol == 17 : 
     u = iph_length + eth_length 
     udph_length = 8 
     udp_header = packet[u:u+8] 

     #now unpack them :) 
     udph = unpack('!HHHH' , udp_header) 

     source_port = udph[0] 
     dest_port = udph[1] 
     length = udph[2] 
     checksum = udph[3] 

     print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Length : ' + str(length) + ' Checksum : ' + str(checksum) 

     h_size = eth_length + iph_length + udph_length 
     data_size = len(packet) - h_size 

     #get data from the packet 
     data = packet[h_size:] 

     print 'Data : ' + data 
     my_pkt = rdpcap("test.pcap") 
     sendp(my_pkt) 

Test.pcap包含一个UDP数据包,UDP_src = 7777和UDP_dest = 9999。

流量被使用的netcat如下生成:

nc -u -p 7777 ip_dst_addr 9999 

嗅探器可以只接收第一netcat的MSG和响应发送test.pcap。但后来的netcat信息根本没有收到。但是,使用netcat中任何其他UDP端口组合,嗅探器都能正常工作。例如:运行的netcat为:

nc -u -p 8888 ip_dst_addr 9999 

是没有问题的,我能够响应每个UDP包/味精发送test.pcap。

任何帮助将不胜感激!

回答

2

Scapy有几个内置嗅探器,它们非常易于使用。

>>> help(sniff) 
Help on function sniff in module scapy.arch.windows.compatibility: 

sniff(count=0, store=1, offline=None, prn=None, stop_filter=None, lfilter=None, L2socket=None, timeout=None, *arg, **karg) 
    Sniff packets 
    sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets 
    Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names. 
     count: number of packets to capture. 0 means infinity 
     store: whether to store sniffed packets or discard them 
     prn: function to apply to each packet. If something is returned, 
      it is displayed. Ex: 
      ex: prn = lambda x: x.summary() 
    filter: provide a BPF filter 
    lfilter: python function applied to each packet to determine 
      if further action may be done 
      ex: lfilter = lambda x: x.haslayer(Padding) 
    offline: pcap file to read packets from, instead of sniffing them 
    timeout: stop sniffing after a given time (default: None) 
    L2socket: use the provided L2socket 
    stop_filter: python function applied to each packet to determine 
       if we have to stop the capture after this packet 
       ex: stop_filter = lambda x: x.haslayer(TCP) 

这意味着,你可以简单地做:

packets = rdpcap("test.pcap") 
sniff(lfilter=lambda x: x.haslayer(UDP) and x[Ether].src==sending_mac and x[UDP].sport==port, prn=lambda x: send(packets)) 

这都将UDP数据包追加到test.pcap文件

+0

谢谢,您的实现要简单得多。 但问题仍然存在,当我们使用与客户端信息中相同的udp端口发送test.pcap时,嗅探器无法嗅探数据包。 :/ – user112333

+0

你想嗅探你发送的数据包吗?否则,应该工作:/不真的明白你的问题 – Cukic0d

+0

我不想在嗅探器中嗅探传出的pkts。这就是为什么有条件如下: 如果eth_addr(数据包[6:12])!= my_MAC_address 有两种数据包: 1)请求我想嗅探。它可以使用netcat生成。假设UDP_src = 7777和UDP_dst = 9999 2)在我们的例子中是test.pcap。我不想嗅探响应数据包。 test.pcap包含一个UDP数据包UDP_src = 7777和UDP_dst = 9999 在收到第一个请求后,我可以发送test.pcap。但之后无法使用UDP_src = 7777和UDP_dst = 9999来嗅探pkts – user112333