1. scapy的sniff功能
scapy的sniff函数与wireshark、tcpdump工具类似,能够捕获指定接口或类型的报文并进行解析。sniff()函数参数如下,参考help(sniff):
count:捕获的报文数量,如果为0,意味着一直捕获
iface:指定捕获的接口,sniff指捕获该接口的报文
prn:每个包都会运行的处理函数
stroe:存储或者丢弃捕获的报文,设置为0意味着我们只是监视他们
timeout:一个给定的时间后停止捕获,默认未设置。
filter:通过BPF(Berkeley Packet Filter)语法来过滤捕获,bpf语法参考:https://biot.com/capstats/bpf.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | Args: 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: prn = lambda x: x.summary() session: a session = a flow decoder used to handle stream of packets. e.g: IPSession (to defragment on-the-flow) or NetflowSession filter: BPF filter to apply. 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 (or list of PCAP files) to read packets from, instead of sniffing them timeout: stop sniffing after a given time (default: None). L2socket: use the provided L2socket (default: use conf.L2listen). opened_socket: provide an object (or a list of objects) ready to use .recv() on. 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) iface: interface or list of interfaces (default: None for sniffing on all interfaces). monitor: use monitor mode. May not be available on all OS started_callback: called as soon as the sniffer starts sniffing (default: None). The iface, offline and opened_socket parameters can be either an element, a list of elements, or a dict object mapping an element to a label (see examples below). Examples: synchronous >>> sniff(filter="arp") >>> sniff(filter="tcp", ... session=IPSession, # defragment on-the-flow ... prn=lambda x: x.summary()) >>> sniff(lfilter=lambda pkt: ARP in pkt) >>> sniff(iface="eth0", prn=Packet.summary) >>> sniff(iface=["eth0", "mon0"], ... prn=lambda pkt: "%s: %s" % (pkt.sniffed_on, ... pkt.summary())) >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"}, ... prn=lambda pkt: "%s: %s" % (pkt.sniffed_on, ... pkt.summary())) Examples: asynchronous >>> t = AsyncSniffer(iface="enp0s3") >>> t.start() >>> time.sleep(1) >>> print("nice weather today") >>> t.stop() |
最值得关注的是prn参数了。我们可以对每一个包都进行相应的处理,例如prn=lambda x:x.summary(),可以打印每个包的信息等等。例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #import scapy module to python from scapy.all import * # custom custom packet sniffer action method def sniffPackets(packet): if packet.haslayer(IP): pckt_src=packet[IP].src pckt_dst=packet[IP].dst pckt_ttl=packet[IP].ttl print "IP Packet: %s is going to %s and has ttl value %s" (pckt_src,pckt_dst,pckt_ttl) print "custom packet sniffer" #call scapy’s sniff method sniff(filter="ip",iface="wlan0",prn=sniffPackets) ##################ARP######################################## def arpDisplay(pkt): if pkt[ARP].op == 1: #request x= "Request: {} is asking about {} ".format(pkt[ARP].psrc,pkt[ARP].pdst) print x if pkt[ARP].op == 2: #response x = "Response: {} has address {}".format(pkt[ARP].hwsrc,pkt[ARP].psrc) print x sniff(prn=arpDisplay, filter="ARP", store=0, count=10) |
2. scapy端口扫描功能(Port-scanning)
这个功能同nmap一样,能够扫描主机并获取开放或是关闭端口的列表。通过下面的函数来说明这一操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | ####扫描指定IP和指定端口 from scapy.all import sr1, IP, TCP OPEN_PORTS = [] def analyze_port(host, port): """ Function that determines the status of a port: Open / closed :param host: target :param port: port to test :type port: int """ print ("[ii] Scanning port %s" % port) res = sr1(IP(dst=host)/TCP(dport=port), verbose=False, timeout=0.2) if res is not None and TCP in res: if res[TCP].flags == 18: OPEN_PORTS.append(port) print ("Port %s open " % port) def main(): for x in range(0, 80): analyze_port("domain", x) print ("[*] Ports openned:") for x in OPEN_PORTS: print (" - %s/TCP" % x) ############扫描指定IP的部分端口段################################## import logging logging.getLogger("scapy.runtime").setLevel(logging.ERROR) import sys from scapy.all import * if len(sys.argv) !=4: print ("usage: %s target startport endport" % (sys.argv[0])) sys.exit(0) target = str(sys.argv[1]) startport = int(sys.argv[2]) endport = int(sys.argv[3]) print ("Scanning "+target+" for open TCP ports\n") if startport==endport: endport+=1 for x in range(startport,endport): packet = IP(dst=target)/TCP(dport=x,flags="S") response = sr1(packet,timeout=0.5,verbose=0) if response.haslayer(TCP) and response.getlayer(TCP).flags == 0x12: print ("Port "+str(x)+" is open!") sr(IP(dst=target)/TCP(dport=response.sport,flags="R"),timeout=0.5, verbose=0) print ("Scan complete!\n") |
3. scapy的traceroute功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from scapy.all import * hostname = "google.com" for i in range(1, 19): pkt = IP(dst=hostname, ttl=i) / UDP(dport=33434) # Send the packet and get a reply reply = sr1(pkt, verbose=0,timeout=1) if reply is None: # No reply =( break elif reply.type == 3: # We've reached our destination print "Done!", reply.src break else: # We're in the middle somewhere print "%d hops away: " % i , reply.src |
4. scapy读写pcap文件
两个函数接口:
1)rdcap():从pacp文件中读取报文并得到一个报文列表。例:file = rdcap('path_file.pcap')
2) wdcap():写pcap文件。例:packets = sniff(filter='tcp port 21') file=wrpcap('path_file.pcap', packets)
还可以通过sniff接口直接解析pcap文件。例:
pkts = sniff( offline = 'file.pcap')
中文参考链接:https://github.com/Larryxi/Scapy_zh-cn