简体   繁体   中英

python-3.4 Scapy sniffing

I have an error when running this script:

from scapy.all import *
sn = sniff(filter="http", count=30)
wireshark(sn)

This is the error:

WARNING: No route found for IPv6 destination :: (no default route?)
WARNING: Please, report issues to https://github.com/phaethon/scapy
Traceback (most recent call last):
File "arp1.py", line 2, in <module>
sn = sniff(filter="http", count=30)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scapy/sendrecv.py", line 566, in sniff
s = L2socket(type=ETH_P_ALL, *arg, **karg)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scapy/arch/pcapdnet.py", line 276, in __init__
self.ins.setfilter(filter)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scapy/arch/pcapdnet.py", line 236, in setfilter
error("Could not compile filter expression %s" % f)
NameError: name 'error' is not defined

When running this script, everything works:

from scapy.all import *
sn = sniff(filter="icmp and host 66.35.250.151", count=4)
wireshark(sn)

Scapy uses the BPF syntax for filtering. This syntax doesn't support specifying "http" as the filter in order to filter HTTP traffic.


However, it is possible to filter all traffic destined to or originating at port 80, which is commonly used for HTTP . The link above proposes the following filter:

To capture all IPv4 HTTP packets to and from port 80, ie print only packets that contain data, not, for example, SYN and FIN packets and ACK -only packets. ( IPv6 is left as an exercise for the reader.)

tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)

This stackoverflow answer supplies a clear explanation of the technical details that stand behind this filter. In a nutshell, it calculates the length in bytes of the application layer payload carried by the packet and verifies that it is not 0 (and thus, positive):

  • IP packet length - IP header length - TCP header length != 0

Since the file /etc/services assigns port number 80 to the service name http it is possible to rewrite the previous filter as follows:

tcp port http and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)

For completeness, it is recommended to filter port 8080 as well ( http-alt in /etc/services ).


Of course, this doesn't guarantee that the filtered traffic is indeed HTTP traffic or that unfiltered traffic doesn't contain HTTP traffic. More sophisticated filters are required for such an endeavour. They would examine the content of the application layer payload in an attempt to deduce the underlying protocol in use.

A simple google search would present several alternative filters for all kinds of purposes, depending on your end-goal. This stackoverflow answer , for example, suggests filters for the basic methods of HTTP : one for the HTTP GET method and another for the HTTP POST method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM