一、Pacp包分析
具体参考博客:pcap文件的python解析实例
1、五元组
在进行Pacp包分析之前,我们需要认真了解五元组这个概念。
网络通信过程中会发送大量的请求,每一个请求都需要通过IP数据包进行交互,但是IP数据包的头部信息过于繁杂,如果通过IP数据包头进行数据包之间的区分就太复杂了,所以就产生了元组。
五元组的构成包括:源IP地址、源端口、目标IP地址、目标端口、4层通信协议。
五元组是元组中的一种,还有四元组、七元组。通过五元组可以表示所在的数据包属于哪一个会话。该特征在数据包查重和流量对比时候使用较多。
2、数据流和数据包之间的关系
具体参考博客:TCP\IP 数据流与数据包
如果针对Pacp文件来说,数据流的概念不同于百度百科的定义。数据流指一次完整的TCP/IP连接,其中包含很多个数据包。
如果在wireshark里面查看pacp包,选中任意一个数据包之后右击-追踪流-TCP流,就能看到该数据包所属的TCP流以及所属TCP流下包含的其他数据包。
二、Pacp包分流
三、Pacp包提取特征元素
问题:提取出pacp文件流的特征,特征不限,每一行代表一个流,不同列代表流的不同特征
1、首先针对给定的pacp包进行提取流操作
利用flowcontainer中的extract对pacp文件进行l流提取(提取TCP流)
# pacp_path为pacp文件的绝对路径,注意路径中的'\'需要变成'\\'
pacp_flow=extract(pacp_path,filter='(tcp)')
extract函数得到的是元组信息实例如下:
2、预热:根据获取到的流提取流中的特征信息
可以根据以上的元组信息反过来查找该元组对应的流信息,即以上图片中的元组得到的是流的索引,实例如下:
for flows in pacp_flow:
value = pacp_flow[flows]
value得到的是(也是flowcontainer默认提取流的特征):源IP,源端口,目的IP,目的端口,IP包长序列,IP包到达时间序列,流到达时间戳、流结束时间戳、载荷长度序列,载荷到达时间序列。
如果想要得到更多的流特征信息,需要在extract
函数中加入extension
,在通过extension_dict=value.extension
获取,此时extension_dict
是一个字典,通过key值就可以获取到指定的特征信息,实例如下:
pacp_flow=extract(pacp_path,filter='(tcp)',extension=['tls.handshake.ciphersuite','tls.handshake.certificate'])
for flows in pacp_flow:
value = pacp_flow[flows]
extension=value.extension
if bool(extension)::
ciphersuite=value.extension['tls.handshake.ciphersuite']
certificate=value.extension['tls.handshake.certificate']
其中certificate
结果示例如下:
可以看到以上是一串数字并没有出现我们熟悉的字母或者文字,可以通过x509相关包进行解析。
ciphersuite
示例如下:
图片中表示该流中第三个数据包出现了ciphersuite以及第五个数据包出现了ciphersuite。
测试中发现并不是每一条流都具备这两项,毕竟不是每条流都是TlS加密流
想获取更多关于extension扩展字段的信息可以参考:flowcontainer: 基于python3的pcap网络流量特征信息提取库
3、提取流中的特征信息
数据流中的特征信息很多,具体可以参考该篇文章:Moore A, Zuev D, Crogan M. Discriminators for use in flow-based classification[R]. 2013
针对TCP流可以通过分割pcap文件中的十六进制数据获取相应信息,可获取的信息如下:
IP头部长度、IP总长度、源地址、目的地址、源端口、目的端口、序列号、ACK、标志位(flags)、TCP头部长度、数据部分
这一步所做的任务就是将wireshark中通过十六进制解析的文字,我们通过python代码将其解析出来,对比如下:
wireshark:
在python代码中我们将做如下解析提取出flags:
flags = data[14 + ip_header_len + 13]
其中data为上述的十六进制数据,即数据帧数据(数据链路层数据)。下面解释为什么是[14 + ip_header_len + 13]
14:
由于以太网首部为14个字节,而data表示数据帧数据,所以所有从data中提取的数据都要以14开始。ip_header_len :
此项flags是在IP数据报的数据部分(也是TCP数据包的头部部分),所以位置就需要加上IP数据报的头部长度13:
此项距离TCP数据包头部第一个字节相差13个字节,所以data[14 + ip_header_len + 13]
表示位于TCP头部的Flags。
如果还是理解不顺畅可以参考:分析Pacp包-TCP/IP四层协议分析
四、Pacp包根据黑名单(.csv)提取出无效流
首先需要构造黑名单(.csv)
1、黑名单构造
(1)提取全部流
首先需要将pacp文件中所想要提取的流提取出来,比如说tls流、http请求流等等(利用extract函数即可),关键代码如下:
pcap_flow = extract(pcap_file_dir + os.sep + fname, filter='(tcp or udp)', extension=['tls.handshake.extensions_server_name',\
'dns.qry.name', 'dns.a', 'http.request.full_uri', 'http2.headers.authority'])
此时提取出来的流包含五种,即extension
中的五种类型流。
得到全部的流以后,利用for循环遍历流并将其分类形成数组,代码如下:
for key in pcap_flow:
value = pcap_flow[key]
if len(value.extension) != 0 and value.extension not in snilist:
filelist.append(key[0])
flowidlist.append(key[2])
protocollist.append(key[1])
siplist.append(value.src)
sportlist.append(value.sport)
diplist.append(value.dst)
dportlist.append(value.dport)
snilist.append(value.extension)
最后将得到的数组输出或者写入文件即可。
(2)根据提取出来的流文件构造黑名单
首先我们需要明确要构造什么样子的黑名单,从而根据黑名单构造什么样的效果。
我们构造的黑名单(csv文件)实际起作用的共有三列(host、sni、http)
,其中sni
即为认定在tls
流下的无效流。
具体编程思路如下:
首先遍历提取出来的流文件(以行为单位),接下来针对csv文件中的每一行进行如下操作:
1、判断是否为dns流,如果是则直接添加host 114.114.114.114列表。否则转2
2、判断是否为http下的ip网址,如果是则提取出IP并附加到http列表中(httplist)
3、获得extension下的值,转化为List并遍历获得sniname
4、如果sniname中是符合指定要求的域名
(1)添加进非重host列表(hostlist),并计算出现次数
(2)判断是http(httplist)还是tls extension(snilist),并添加至相应的非重列表中,并计算出现次数
5、将hostlist、httplist、snilist以及所出现的次数写入csv文件中
此时得到的csv文件即为黑名单。
2、根据黑名单提取出无效流文件
遍历pcap文件目录,针对每一个pacp文件提取指定流(和之前构造黑名单一样,需要在extract()函数的extension中指明提取流的类型)
将黑名单中的每一列数据取出形成列表(hostlist、httplist、snilist),通过对比host以及tls流和http请求流中是否包含此黑名单中的项,从而判断此流是否为无效流。
如果是无效流文件提取出相应信息(例如五元组信息)。
最后遍历所有的pacp文件后将得到的五个数组写入csv文件中。
dataframe = pd.DataFrame(
{'file': filelist, 'protocol': protocollist, 'sip': siplist, 'sport': sportlist, 'dip': diplist,
'dport': dportlist})
dataframe.to_csv(pcap_file_dir + "invalid_flow.csv", index=False, encoding='utf_8_sig')
额外知识点
IPV6的反向解析
IPV6的正向解析包含两种形式,分别为AAAA和A6。反向解析对应也会有两种形式,反向解析的域名系统中包含了ip6.Int和ip6.arpa两个域名,其中ip6.Int和AAAA记录对应,此形式只是简单地扩展了IPV4。ip6.arpa与A6记录对应,标记类型为二进制串的格式,身后为十六进制地址,后缀则是ip6.arpa。
在实际分析pacp包过程中发现了ip6.arpa的例子如下:
1.0.1.2.b.9.7.0.8.2.d.f.d.1.d.0.5.f.7.4.0.9.6.7.9.0.4.0.e.0.4.2.ip6.arpa
python分析pacp包遇到的问题(python运行环境:PyCharm):
1、‘tshark’ 不是内部或外部命令,也不是可运行的程序或批处理文件
因为环境变量里面没有添加tshark所在路径,具体添加方法可以参考:windows10环境变量中添加tshark 最后只需要在path中浏览加入tshark所在路径就好了。
2、tshark添加进去了还是报错怎么办?
可能是因为tshark版本过低,如果需要提取tls的sni,那么tshark的版本需要大于3.0.0!更多tshark版本问题可以查看:flowcontainer: 基于python3的pcap网络流量特征信息提取库
3、UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 1022-1023: unexpected end of data
在代码底部加上:
#!/usr/bin/env python
# coding=utf-8
4、with open(file_dir, “r”, encoding=“utf-8”) as f: FileNotFoundError: [Errno 2] No such file or directory:
将with open()
内的"r"
变为"a+"
尚未解决的问题
1、Python中的extract函数是已经对提取出来的tcp、udp流进行了数据包查重操作吗?
问题原因:因为有可能好几个数据包是属于同一个会话流,即他们的五元组相同。
已经获取的知识:flowcontainer默认滤除重传、乱序数据包、mdns、ssdp、icmp数据包,默认只保留IP数据包。