目录:
一、简介与安装
Scapy的是一个强大的交互式数据包处理程序(使用python编写)。它能够伪造或者解码大量的网络协议数据包,能够发送、捕捉、匹配请求和回复包等等。它可以很容易地处理一些典型操作,比如端口扫描,tracerouting,探测,单元 测试,攻击或网络发现(可替代hping,NMAP,arpspoof,ARP-SK,arping,tcpdump,tethereal,P0F等)。 最重要的他还有很多更优秀的特性——发送无效数据帧、注入修改的802.11数据帧、在WEP上解码加密通道(VOIP)、ARP缓存攻击(VLAN) 等,这也是其他工具无法处理完成的。
安装Scapy:在ubuntu下使用命令sudo apt-get install python-scapy 进行安装,其他环境安装参考scapy使用文档,windows下安装参考:http://www.cnblogs.com/xiaowuyi/p/3329795.html。
二、基本使用命令
Scapy不仅可以进行交互式数据包处理,还可以作为Python的一个模块在Python程序中使用。ps:不管是交互式数据处理,还是在Python代码中使用,都需要root权限运行。
1、执行sudo scapy命令进入交互式数据包处理,在Python代码中使用from scapy.all import *引入scapy。
2、ls()显示scapy支持的所有协议。
截图只截取了一部分,主要的协议有DNS、IP、IPv6、TCP、UDP等。
ps:ls()函数的参数还可以是上面支持的协议中的任意一个,也可以是任何一个具体的数据包。如ls(TCP),ls(newpacket)等。
3、lsc()列出scapy支持的所有的命令。
4、conf:显示所有的配置信息。conf变量保存了scapy的配置信息。
5、help()显示某一命令的使用帮助,如help(sniff)。
6、show()显示指定数据包的详细信息,如newpacket.show()。
7、display()可以简单查看当前数据包的各个参数的取值情况。
8、sprintf()输出某一层某个参数的取值,如果不存在就输出”??”,具体的format格式是:%[[fmt][r],][layer[:nb].]field%,详细的使用参考<Security Power Tools>的146页。
%[[fmt][r],][layer[:nb].]field%
layer:协议层的名字,如Ether、IP、Dot11、TCP等。
filed:需要显示的参数。
nb:当有两个协议层有相同的参数名时,nb用于到达你想要的协议层。
r:是一个标志。当使用r标志时,意味着显示的是参数的原始值。例如,TCP标志中使用人类可阅读的字符串’SA’表示SYN和ACK标志,而其原始值是18.
三、Scapy基本函数使用
1、创建数据包
scapy的数据包创建按照的是TCP/IP协议的四层参考模型:网络接口层、互联网层、传输层、应用层。Scapy为每一层都写了相应的类,创建数据包时我们只要将这些类实例化,然后调用类的方法或改变类的参数值即可。各个层的协议都有各自的创建函数,如IP()、TCP()、UDP()等,不同层之间通过”/”来连接。每个创建函数的参数可以使用ls(函数名)来查看,如ls(TCP)。
数据包中没有设置的部分都使用默认值,如上面数据包的TTL值默认是64。如IP()没有传给它参数,那么数据包的参数是默认的,如果传了参数就会覆盖默认值。用/符号表示两个协议层的组合,如IP()/TCP()、Ether()/IP()/TCP()、IP()/TCP()/”GET / HTTP/1.0\r\n” 即数据部分可以直接使用字符串。
2、发送和接收数据包
构造好数据包就需要进行数据包的发送,并且要根据情况接收数据包的响应。
2.1 简单的发送包,不进行接收
(1)send()在第三层发送数据包,但没有接收响应的功能。如:
send(IP(dst="www.jinglingshu.org",ttl=10)/ICMP())
(2)sendp()在第二层发送数据包,同样没有响应接收功能。如:
sendp(Ether()/IP(dst="www.jinglingshu.org",ttl=10)/ICMP())
2.1 发送数据包,并接收响应
(1)sr() 在第三层发送数据包,并返回响应和未响应的数据包。例如:向www.jinglingshu.org发送ttl分别由5到10的6个ICMP数据包。
result,unanswered=sr(IP(dst="www.jinglingshu.org",ttl=(5,10))/ICMP())
(2)sr1() 在第三层发送数据包,有接收功能,但只接收第一个包。timeout参数表示发送完最后一个数据包后等待超时的时间。 例如:
result=sr1(IP(dst="www.jinglingshu.org",ttl=(30,40))/ICMP())
(3)srloop()工作在第三层,可以设置发包的数量。例如:向www.baidu.com每隔3秒发送ICMP数据包,发送两个。
p=srloop(IP(dst="www.baidu.com",ttl=1)/ICMP(),inter=3,count=2)
(4)srp()、srp1()、srploop()等函数上面sr()、sr1()、srloop()相同,只是工作在第二层。
result,unanswered=srp(Ether()/IP(dst="www.baidu.com")/ICMP())
3、嗅探数据包
scapy除了可以伪造数据包并接收响应结果,还可以用于数据包嗅探。对数据包进行嗅探的函数为sniff(),sniff()的详细使用方法如下:
除了上面介绍的几个参数,sniff()函数还有一个重要的参数是filter,用来表示想要捕获数据包类型的过滤器,如只捕获ICMP数据包,则filter=”ICMP”;只捕获80端口的TCP数据包,则filter=”TCP and (port 80)”。其他几个重要的参数有:count表示需要不活的数据包的个数;prn表示每个数据包处理的函数,可以是lambda表达式,如prn=lambda x:x.summary();timeout表示数据包捕获的超时时间。
四、Scapy使用
1、SYN扫描
SYN扫描:也叫“半开式扫描”(half-open scanning),因为它没有完成一个完整的TCP连接。这种方法向目标端口发送一个SYN分组(packet),如果目标端口返回SYN/ACK,那么可以肯定该端口处于检听状态;否则,返回的是RST/ACK。
从扫描的结果看,80端口返回的flags标识为SA,说明80端口是开放的。可以通过result[TCP].flags来获取响应TCP数据包的TCP的标识位,但是获取的是数字表示,如SA标识的数字是18,S标识是2。
所以使用scapy进行SYN端口扫描的简单代码如下:
#!/usr/bin/env python #coding=utf-8 from scapy.all import * from scapy.error import Scapy_Exception def synscan(domain,port): result=sr1(IP(dst=domain)/TCP(dport=port,flags="S"),timeout=10) if result: print 'got answer' if (result[TCP].flags==18): print 'port open' else: print 'not got answer' synscan('www.jinglingshu.org',80)
2、TCP traceroute 路由跟踪测试
traceroute:用来追踪出发点到目的地所经过的路径,通过Traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路 径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所 走的路由是相同的。
#coding=utf-8 from scapy.all import * ans,unans=sr(IP(dst="www.baidu.com",ttl=(2,25),id=RandShort())/TCP(flags=0x2),timeout=50) for snd,rcv in ans: print snd.ttl,rcv.src,isinstance(rcv.payload,TCP)
五、sniff嗅探HTTP数据包
由于scapy提供的协议层只到TCP层,没有实现HTTP层,因此捕获HTTP数据包有点恼火(因为HTTP数据包可能在多个TCP数据包中,这就涉及到TCP数据包的重组)。
使用scapy捕获HTTP数据包可以使用https://github.com/invernizzi/scapy-http提供的scapy-http模块。配合scapy-http模块进行HTTP数据包的捕获的简陋代码如下(说简陋是因为没有进行TCP数据包重组,内容gzip解压等):
import scapy_http.http as HTTP count=0 from scapy.all import * from scapy.error import Scapy_Exception def pktTCP(pkt): global count count=count+1 print count if HTTP.HTTPRequest or HTTP.HTTPResponse in pkt: src=pkt[IP].src srcport=pkt[IP].sport dst=pkt[IP].dst dstport=pkt[IP].dport test=pkt[TCP].payload if HTTP.HTTPRequest in pkt: #print "HTTP Request:" #print test print "======================================================================" if HTTP.HTTPResponse in pkt: print "HTTP Response:" try: headers,body= str(test).split("\r\n\r\n", 1) print headers except Exception,e: print e print "======================================================================" else: #print pkt[IP].src,pkt[IP].sport,'->',pkt[TCP].flags print 'other' sniff(filter='tcp and port 80',prn=pktTCP)
上面只是捕获了HTTP数据包的部分信息,下面详细讲解一下TCP、HTTP数据包的格式与协议内容,为进行HTTP数据包捕获还原打下基础,并详细介绍使用pcap与dpkt配合进行HTTP数据包捕获与还原、Scapy捕获并还原HTTP数据包的代码。
参考文章:
3、Scapy: All-in-One Networking Tool
5、TCP数据包格式
6、Simple Sniffer HTTP Request and HTTP Response with Python Scapy
9、How to remove trailer of the packet in python using scapy
转载请注明:jinglingshu的博客 » scapy学习笔记