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
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(),可以打印每个包的信息等等。例子如下:
#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一样,能够扫描主机并获取开放或是关闭端口的列表。通过下面的函数来说明这一操作。
####扫描指定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功能
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')