抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

先讨论pcap包的抓取

这里我们可以使用Wireshark+Winpcap组合进行抓取pcap包,但这里要注意的是这个组合不可以抓取回环包,如果要抓回环包可以使用Wireshark+Npcap这个组合。

WinpcapNpcap在网上都是可以找到集成应用的,可以一键配置。

这里我在windows环境下使用python+pypcap+dpkt进行抓取分析。

首先要安装pypcap包,我是用pip install pypcap命令下载失败,[这里是下载pypcap的链接](pypcap · PyPI)

pypcap是一个对libpcapC库进行封装和简化的面向对象的抓包工具库,可以非常方便的用于抓包和过滤,结合dpkt解析库可以完成许多网络数据包的抓取和分析。也就是说pypcap是用c语言写成的。一开始,lipcap API库被设计成使用C和C++语言运行。但随着更多不用高级编程语言的出现,比如Perl、Python、Java、C#和Ruby等,lipcap被允许可以被封装成不同语言的库被调用。Libpcap可以在大部分的Unix操作系统下运行,同时也支持windows系统,也就是winpcap库。

这里我们需要Npcap的支持,先将[Npcap](Npcap: Windows 数据包捕获库和驱动程序 (nmap.org))下载安装,再下载Npcap SDK然后再将下载的pypcap解压到Npcap SDK的目录。并将Npcap SDK的文件名改为wpdpack放在python文件的include文件夹下。然后在文件夹里打开powershell。运行python setup.py install这里遇到了一些问题error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools"。要配置VSC++环境。待配置好之后在powershell窗口python setup.py build & python setup.py install成功即可。

可以先调试下是否安装成功。

1
2
3
4
5
6
7
8
9
import pcap
# list all of the Internet devices
devs = pcap.findalldevs()
print(*devs, sep='\n')
pc = pcap.pcap(devs[3], promisc=True, immediate=True, timeout_ms=50)
# fiter http pcakets
pc.setfilter('tcp port 80')
for ptime, pdata in pc:
print(ptime, pdata)

成功之后就可以使用了。

dpkt的安装pip install dpkt用来解析获取的pcap包。

之后就是使用pypacp抓包了。先了解其中的主要函数。

先是findalldevs,它可以列出当前操作系统的所有网络接口pcap.findalldevs()但是这个方法在windows下并不好操作,这里可以借用wireshark抓包获得接口。

再是pcap.pcap,pc = pcap.pcap(devs[3], promisc=True, immediate=True, timeout_ms=50)以上代码定义了一个pcap对象,首个参数devs[3]对应接口名,promisc为真代表打开混杂模式,immediate代表立即模式,启用将不缓存数据包,timeout_ms代表接收数据包的超时时间

之后是setfilter函数,是用来设置数据包过滤器,比如只想抓http的包,那就通过setfilter(tcp port 80)实现。

再就是最后的抓包

1
2
for ptime,pdata in pc:
print(ptime,pdata)

上边的pcap.pcap对象pc是一个动态数据包,通过循环结构不断输出。

下边是一个简易的抓包工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3
# -*- encoding:utf-8 -*-
import pcap
import dpkt

import getopt
import sys
import datetime
import time
import os
import platform

if 'Windows' in platform.platform():
import winreg as wr


IF_REG = r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}'
def getInterfaceByName(name): //根据接口名称,通过查找注册表信息获取pcap所需的接口设备信息,适用于Windows系统.
'''Get guid of interface from regedit of windows system
Args:
name: interface name
Returns:
An valid guid value or None.
Example:
getInterfaceByName('eth0')
'''
reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
reg_key = wr.OpenKey(reg, IF_REG)
for i in range(wr.QueryInfoKey(reg_key)[0]):
subkey_name = wr.EnumKey(reg_key, i)
try:
reg_subkey = wr.OpenKey(reg_key, subkey_name + r'\Connection')
Name = wr.QueryValueEx(reg_subkey, 'Name')[0]
wr.CloseKey(reg_subkey)
if Name == name:
return r'\Device\NPF_' + subkey_name
except FileNotFoundError as e:
pass

return None

def mac_addr(mac):
return '%02x:%02x:%02x:%02x:%02x:%02x'%tuple(mac)

def ip_addr(ip):
return '%d.%d.%d.%d'%tuple(ip)

def captureData(iface):
pkt = pcap.pcap(iface, promisc=True, immediate=True, timeout_ms=50)
# filter method
filters = {
'DNS': 'udp port 53',
'HTTP': 'tcp port 80'
}
# pkt.setfilter(filters['HTTP'])

pcap_filepath = 'pkts/pkts_{}.pcap'.format(time.strftime("%Y%m%d-%H%M%S",
time.localtime()))
pcap_file = open(pcap_filepath, 'wb') //数据包的存储
writer = dpkt.pcap.Writer(pcap_file)
print('Start capture...')
try:
pkts_count = 0
for ptime, pdata in pkt:
writer.writepkt(pdata, ptime)
# anlysisData(pdata)
printRawPkt(ptime, pdata)
pkts_count += 1
except KeyboardInterrupt as e:
writer.close()
pcap_file.close()
if not pkts_count:
os.remove(pcap_filepath)
print('%d packets received'%(pkts_count))

def printRawPkt(time, data): //打印数据包的基本信息
eth = dpkt.ethernet.Ethernet(data) //数据包的解析
print('Timestamp: ', str(datetime.datetime.utcfromtimestamp(time)))
print('Ethernet Frame: ', mac_addr(eth.src), mac_addr(eth.dst))
if not isinstance(eth.data, dpkt.ip.IP):
print('')
return

ip = eth.data

# get fragments info
do_not_fragment = bool(ip.off & dpkt.ip.IP_DF)
more_fragments = bool(ip.off & dpkt.ip.IP_MF)
fragment_offset = ip.off & dpkt.ip.IP_OFFMASK

print('IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)\n' % (
ip_addr(ip.src), ip_addr(ip.dst), ip.len, ip.ttl,
do_not_fragment, more_fragments, fragment_offset))

def anlysisData(data):
packet = dpkt.ethernet.Ethernet(data)
if isinstance(packet.data, dpkt.ip.IP):
ip = ip_addr(packet.data.dst)
if packet.data.data.dport == 80 or packet.data.data.sport == 80:
try:
print(packet.data.data.data.decode('utf-8', errors='ignore'))
except UnicodeDecodeError as uderr:
print(uderr.__str__())


def main():
if 'Windows' in platform.platform():
iface = getInterfaceByName('Router')
else:
iface = 'enp2s0'
captureData(iface)

if __name__ == "__main__":
main()

再就是简单介绍wireshark

pcap1

数据包的颜色代表了其性质。可以看出它传输过程中不同网络等次的信息,显化TCP三次握手记录。这里区分TCP和UDP,TCP的三次握手四次挥手确保了数据的完整性,不容易丢包,但是相对速度慢。UDP可以说是流式传输,丢包率高速度快,应用于视频电话之类的时间同步较高的传输。

评论