文章目录
Scapy模块文件
关于Scapy
- Scapy是一个由Python语言编写的强大工具,它是大量程序编写人员最喜爱的一个网络模块。
- 也可以在自己的程序中使用这个模块来实现对网络数据包的发送、监听和解析。
- 这个模块相比起Nmap来说,更为底层。可以更为直观地了解到网络中的各种扫描和攻击行为,例如,要检测某一个端口是否开放,只需提供给Nmap一个端口号,而Nmap就会给出一个开放或者关闭的结果,但是并不知道Nmap是怎么做的。
- 如果想对网络中的各种问题进行深入研究,Scapy无疑是一个更好的选择,可以利用它来产生各种类型的数据包并发送出去,Scapy也只会把收到的数据包展示给你,而并不会试图解释收到的数据包,解释结果可以帮助那些不知道什么是端口扫描的用户,但是弊大于利,因为这对于结果是一种主观的解释。可能的结果就是它们可以自己解释,知识丰富的用户将试图反向还原这个工具的解释以得到引起这个解释的真正原因。不幸的是,在这个过程中有大量的信息丢失。
基本用法
- Scapy提供了和Python一样的交互式命令行。Scapy可以作为Python的一个模块存在,但是Scapy本身就是一个可以运行的工具,它自己具备一个独立的运行环境,因而可以不在Python环境下运行。
- 在Kali Linux 中已经集成了Scapy,既可以在Python环境中使用Scapy,也可以直接使用它。启动一个终端,输入命令“scapy”,就可以启动Scapy环境,如图
- 在Scapy中,每一个协议就是一个类。
- 只需要实例化一个协议类,就可以创建一个该协议的数据包。
- 例如,如果要创建一个IP类型的数据包,就可以使用如下命令
ip = IP()
。
- IP数据包最重要的属性就是源地址和目的地址,这两个属性可以使用src和dst来设置。例如,要构造一个发往“192.168.1.101”的IP数据包,可以使用
ip = IP(dst="192.168.1.101")
语句。
- 这个目标dst的值可以是一个IP地址,也可以是一个IP范围,例如192.168.1.0/24,这时产生的就不是1个数据包,而是256个数据包。
- 如果要查看其中每一个数据包,可以使用
[p for p in ip]
采用分层形式来构造数据包
-
通常最下面的一个协议为Ether,然后是IP,再之后是TCP或者是UDP。
-
IP()函数无法用来构造ARP请求和应答数据包,可以使用Ether(),
-
这个函数可以设置发送方和接收方的MAC地址。产生一个广播数据包,执行命令如下
Ether(dst="ff:ff:ff:ff:ff:ff")
-
Scapy中的分层通过符号“/”实现,一个数据包是由多层协议组合而成,这些协议之间就可以使用“/”分开,按照协议由底而上的顺序从左向右排列
-
例如,可以使用以下命令来完成一个TCP数据包,
Ether()/IP()/TCP()
-
如果构造一个HTTP数据包,可以使用以下方式
IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
-
ls()函数查看一个类所拥有的属性
- 使用
ls(Ether())
来查看Ether类属性
- 使用
ls(IP())
来查看IP类的属性
- 使用
-
可以对这里面的属性进行设置,例如:将ttl的值设置为32,可以使用如下方式
IP(src="192.168.1.1", dst="192.168.1.101", ttl=32)
Scapy模块中的函数
send()和sendp()
send() 工作在第三层,发送IP数据包
sendp() 工作在第二层,发送Ether数据包
例如,构造一个目的地址为"192.168.1.101"的ICMP数据包,并将其发送出去,可以使用语句
send(IP(dst="192.168.1.101")/ICMP())
#注意,如果这个数据包发送成功,下方会有一个“Sent 1 packets.”的显示。
sendp(Ether(dst="ff:ff:ff:ff:ff:ff"))
注:这两个函数的特点是只发不收,只会将数据包发送出去,但是没有能力处理该数据包的回应包!!
fuzz()函数
如果希望发送一个内容是随机填充的数据包,而且又要保证这个数据包的正确性,那么可以是fuzz()函数。
例如,可以使用如下命令来创建一个发往192.168.1.101的TCP数据包。
IP(dst="192.168.1.101")/fuzz(TCP())