2017-06-01 60 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