软件定义网络实验教程
上QQ阅读APP看书,第一时间看更新

任务三 交互式数据包处理工具Scapy使用介绍

任务目的

1. 了解Scapy的背景和基本功能,体会Scapy的优势。

2. 掌握查看Scapy所支持的协议、命令的方法。

3. 掌握自定义数据包,发送、接收数据包的方法。

任务环境

交互式数据包处理工具Scapy使用介绍实验的拓扑如图1-10所示。

0

图1-10 实验拓扑

实验环境镜像配置说明如表1-9所示。

表1-9 实验环境镜像配置说明

0

注:系统默认的账户为root/root@openlab、openlab/user@openlab。

任务内容

1. 学习Scapy的基本功能、特性和安装方法。

2. 学习使用Scapy的基本命令,主要包括ls()、lsc()、help()等。

3. 学习使用Scapy创建数据包,发送、接收数据包。

实验原理

一 概述

Scapy是一个基于Python编写的交互式数据包处理程序,使用Python解释器作为命令面板。可以用来发送、嗅探、解析和伪造网络数据包,常用于网络攻击和测试。Scapy不仅可以实现扫描、路由跟踪、探测、单元测试、攻击和发现网络等传统功能,也可以代替hping、arpspoof、arp-sk、arping、p0f,实现部分Namp、Tcpdump和tshark的功能。它能够伪造或解码大量的网络协议数据包,能够发送、捕捉、匹配请求和回复包等。它还可以发送无效数据帧、注入修改的802.11数据帧、在WEP上解码加密通道(VOIP)、ARP缓存攻击(VLAN)等,这也是其他工具无法处理完成的。Scapy主要负责定义、发送和接收报文。用户利用Scapy定义一系列报文,接着发送这些报文,然后会收到回应,Scapy将收到的回应与请求匹配,匹配结果返回到存放报文对(请求,回应)的列表和没有匹配报文的列表。

Scapy不仅可以进行交互式数据包处理,还可以作为Python模块在Python程序中使用。需要注意的是,无论是交互式数据处理还是在Python代码中使用,都需要基于root权限。

二 安装使用

Scapy是第三方库,系统上默认是没有安装的。在Ubuntu下,可以直接使用命令sudo apt-get install scapy进行安装,安装完成以后,在终端下执行sudo scapy就可以进入Scapy的命令行模式。

Scapy常用功能如下。

1. conf:查看配置信息,如下所示。

 >>> conf 
 ASN1_default_codec = <ASN1Codec BER[1]> 
 AS_resolver = <scapy.as_resolvers.AS_resolver_multi instance at 0x13c1dd0> 
 ( 此处省略 N 行 ) 
 verb       = 2 
 version    = '2.3.2' 
 warning_threshold = 5 
 wepkey     = ''

2. lsc():查看Scapy支持的所有命令,如下所示。

 >>> lsc() 
 arpcachepoison      : Poison target's cache with (your MAC,victim's IP) couple 
 arping              : Send ARP who-has requests to determine which hosts are up 
 bind_layers         : Bind 2 layers on some specific fields' values 
 corrupt_bits        : Flip a given percentage or number of bits from a string 
 ( 此处省略 N 行 ) 
 wireshark           : Run wireshark on a list of packets 
 wrpcap              : Write a list of packets to a pcap file

3. ls():查看实现的网络协议。ls()中携带的参数可以是任何一个具体的包,常用的有ARP、Ether、ICMP、IP、UDP、TCP,也支持SNMP、DHCP、STP等。

缺省参数模式如下。

 >>> ls() 
 AH         : AH 
 ARP        : ARP 
 ASN1_Packet : None 
 ATT_Error_Response : Error Response 
 ATT_Exchange_MTU_Request : Exchange MTU Request 
 ( 此处省略 N 行 ) 
 _IPv6ExtHdr : Abstract IPV6 Option Header 
 _MobilityHeader : Dummy IPv6 Mobility Header

携带参数模式如下。

 >>> ls(UDP) 
 sport        : ShortEnumField           = (53) 
 dport        : ShortEnumField           = (53) 
 len          : ShortField               = (None) 
 chksum       : XShortField              = (None)

4. IP模块的使用。

可以像在Python中一样实例化一个IP对象,如下所示。

 >>> data = IP()   
 >>> data   
 <IP >

也可以传入需要自定义的参数,如下所示。

 >>> data = IP(dst="172.16.2.79")   
 >>> data   
 <IP dst=172.16.2.79 >

查看IP模块对象的所有信息,如下所示。

 >>> data = IP()   
 >>> data.show()   
 ###[ IP ]###  
 version= 4  
 ihl= None  
 tos= 0x0  
 len= None  
 id= 1  
 flags=  
 frag= 0  
 ttl= 64  
 proto= ip  
 chksum= None  
 src= 127.0.0.1  
 dst= 127.0.0.1  
 \options\

5. 创建数据包。

Scapy的数据包创建是按照TCP/IP的参考模型,具体支持网络接入层、网络互联层、传输层、应用层。Scapy为每一层都写了相应的类,创建数据包时只要将这些类实例化,然后调用类的方法或改变类的参数值即可。各个层的协议都有各自的创建函数,如IP()、TCP()、UDP()等,不同层之间通过“/”连接。

6. 发送和接收报文。

可以将上面的IP对象封装成一个数据包发送出去。

send:在第三层即网络层发送数据包,但没有接收功能。

 >>> send(data, iface="eth0")  
 .  
 Sent 1 packets.

sendp:在第二层即数据链路层发送数据包,同样没有接收功能。

sr:在第三层即网络层发送数据包,有接收功能。

sr1:在第三层即网络层发送数据包,有接收功能,但只接收第一个包。

srp:在第二层即数据链路层发送数据包,有接收功能。

srp1:在第二层即数据链路层发送数据包,有接收功能,但只接收第一个包。

实验步骤

一 实验环境检查

步骤1 以root用户登录主机1,执行ifconfig命令查看主机1的IP地址,如下所示。

0

步骤2 以root用户登录主机2,执行ifconfig命令查看主机2的IP地址,如下所示。

0

二 学习Scapy基本命令

步骤1 以root用户登录主机1,执行scapy命令登入Scapy环境进行实验操作,如下所示。

0

说明:如果没有安装所有可选包,会弹出提示消息,不过并不影响发送、接收数据包等基本功能。

步骤2 执行ls()命令,显示Scapy支持的所有协议。

步骤3 执行lsc()命令,显示Scapy支持的所有命令。

步骤4 执行help(send),显示send命令相关的用法,如下所示。

0

说明:按“q”键退出help()命令。

步骤5 执行如下命令,定义一个名为mypacket的IP数据包,并查询该数据包的详细信息,如下所示。

 >>> mypacket = IP()
 >>> mypacket.show()
0

三 创建数据包

步骤1 执行以下命令,创建IP层,将主机2的IP设为目的IP,并查看设置后的结果,如下所示。

 >>> my_ip = IP(dst="10.0.0.2")
 >>> my_ip.dst
0

步骤2 执行以下命令,查看默认的ttl字段,并修改ttl为27,如下所示。

 >>> my_ip.ttl
 >>> my_ip.ttl=27
0

步骤3 执行以下命令,创建TCP层后查看默认的flags字段,然后修改flags为“SA”,并查看修改后的flags字段,如下所示。

 >>> my_tcp=TCP()
 >>> my_tcp.flags
 >>> my_tcp.flags="SA"
0

步骤4 执行以下命令显示整个数据包,不同层之间用“/”连接,如下所示。

 >>> [p for p in my_ip/my_tcp]
0

四 发送接收数据包

步骤1 执行如下命令发送数据包,但并不接收响应。其中,send()在第三层即网络层发送数据包,而sendp()在第二层即数据链路层发送,如下所示。

 >>>send(IP(dst="10.0.0.2",ttl=15)/ICMP())
 >>>sendp(Ether()/IP(dst="10.0.0.2",ttl=15)/ICMP())
0

步骤2 执行以下命令,使用sr()发送数据包,并接收响应,如下所示。

 >>> result,unanswered=sr(IP(dst="10.0.0.2",ttl=(3,10))/ICMP())
 >>> result.show()
 >>> unanswered.show()
0

由上可知,利用sr()在第三层,即网络层发送数据包,向10.0.0.2发送ttl分别为3~10的8个ICMP数据包。其中,有8个获得响应,0个没有响应。

步骤3 执行如下命令,使用sr1()发送数据包,并查看响应数据包,如下所示。

 >>> result=sr1(IP(dst="10.0.0.2",ttl=(22,35))/ICMP())
 >>> result.show()
0

由上可知,虽然sr1()也用于发送数据包并接收响应,但是sr1()只接收第一个数据包。