1. 介绍
scapy是一个可用于网络嗅探的非常强大的第三方库。在网络嗅探方面前面的博文介绍过通过Raw Socket进行网络嗅探,但是Raw Socket比较底层,使用起来可能不太容易而且在不同的系统上也有一定的区别。
在网络流量嗅探方面,常用的一些第三方库:
scapy
接下来我详细介绍下scapy的使用,它在这些库中功能最强大使用也最灵活。具有以下几个特点:
交互模式,用作第三方库。可以用来做packet嗅探和伪造packet。 已经在内部实现了大量的网络协议。(DNS,ARP,IP,TCP,UDP等等) 可以用它来编写非常灵活实用的工具。
更详细的信息可参考官方scapy使用说明书。
2. 使用scapy
2.1 scapy安装
既然是第三方库,系统上默认是没有安装的。在Ubuntu下,我们可以直接使用以下命令进行安装:
sudo apt-get install scapy
安装完成以后,只需要在终端下执行sudo scapy就可以进入scapy的命令行模式。
2.2 scapy可用到的协议层次ls() 列出scapy中已实现的网络协议。还有很多下图中没有列举出来,可亲自试验一下便知。
ls(IP) 列出IP协议头部字段格式。
IP().show() 显示包的IP信息。
lsc() 列出scapy中可以使用的命令或函数。
conf scapy配置选项
2.3 scapy嗅探示例
在scapy命令模式下,异常输入以下代码进行试验。
1)、嗅探流量包。
1
2
3
4
5
6
7>>>
>>> pkts = sniff(iface = eth0,count =3 )
>>>
>>> pkts
>>>
sniffer函数进行嗅探流量,iface表示使用的网卡接口,count是嗅探包的个数。结果显示嗅探到了3个TCP包。可以输入pkts[i]查看包的具体内容。
1
2
3
4
5>>> pkts[0]
>>>
>>>
>>>
可以看到以太网帧头各个字段的具体值,还有后面跟的协议类型,这里是IPv4,还有IP个字段的值以及IP上层的TCP协议及其字段值。如果感觉还是不够清晰,可以使用pkts[i].show()更加清楚明了的看到packet中各协议字段的具体值。
2)、将嗅探到的packet内容写到pcap文件中和读取pcap文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16>>>
>>>
>>> wrpcap(demo.pcap,pkts)
>>>
>>>
>>> read_pkts = rdpcap(demo.pcap)
>>>
>>> read_pkts[0]
>>>
>>>
>>> read_pkts[1]
>>
>>>
>>>
3)、为sniffer函数添加过滤条件。
用过wireshark或者tcpdump的coders都知道,网络中的流量是庞大而复杂的,有时候我们需要增加一些特定的条件将我们想要看到的数据筛选出来。比如filter= udp。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24>>>
>>> pkts = sniff(iface = eth0,filter = udp,count =3 )
>>>
>>> pkts[1]
>>>
>>> pkts[2]
>>>
>>>
>>>
3)、动态打印出概要结果。
在scapy命令模式中输入命令pkts = sniff(iface = eth0,filter = icmp,count = 30, prn = lambda x: x.summary()),这里我把嗅探包的数量提高到30,然后过滤ICMP协议类型的包。一边等待显示结果,可以另起一个终端,然后ping一个网址,观察嗅探现实的结果。
4)、帧与字符串的互相转换
vcD4NCjxwcmUgY2xhc3M9"brush:java;"> >>> >>> >>> icmp_str = str(pkts[0]) >>> >>> icmp_str @l?.??'5BYEd?Y@@ò?à¨à¨_eu?£;?` S?ì? +?J?ìz??\$?Yeμa?£7e??@?,??yJ_QaQ???<_qb>>> >>> recombine = Ether(icmp_str) >>> >>> recombine>>> >>>
5)、导入导出base64编码格式的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20>>>
>>>
>>> export_object(str(pkts[0]))
eNoBeQCG/4ACVXJAbI8u1cQIACc1QlkIAEUAAGTD3UAAQAby+MCoAQ7AqAFfABbwdeOjOwSpYApT
gBgTzIQUAAABAQgKDAsrqUrlFMx6GYK9XCTHWRwc8LVhnqMLNwzwy6FAhizYxXlKX1GqUfWY1Txf
cRVCq85FqCadC5VxAS4+6i3U
>>>
>>> newPkt = import_object() #将上一步导出的字符串填入,回车,ctrl_+d结束。
eNoBeQCG/4ACVXJAbI8u1cQIACc1QlkIAEUAAGTD3UAAQAby+MCoAQ7AqAFfABbwdeOjOwSpYApT
gBgTzIQUAAABAQgKDAsrqUrlFMx6GYK9XCTHWRwc8LVhnqMLNwzwy6FAhizYxXlKX1GqUfWY1Txf
cRVCq85FqCadC5VxAS4+6i3U
>>> newPkt
@l.??'5BYEd?Y@@ò?à¨à¨_eu?£;?`
S?ì?
+?J?ìz??\$?Yeμa?£7e??@?,??yJ_QaQ???<_qb>
>>> Ether(newPkt)
>>>
>>>