流量特征提取工具NFStream
前言
之前介绍了关于stratum协议挖矿流量的一些内容,今天来介绍一下一款好用的流量特征提取工具 NFStream,它可以很好的帮助我们从更深层次的角度来分析流量特征。
flowcontainer
再介绍NFStream之前,先来介绍一下flowcontainer,它也是基于python开发的一款网络流量基本信息提取库。
flowcontainer默认提取流的:源IP,源端口,目的IP,目的端口,IP包长序列,IP包到达时间序列,流到达时间戳、流结束时间戳、载荷长度序列,载荷到达时间序列。
flowcontainer的安装环境:
python3
numpy>=18.1
系统安装好tshark的最新版本,并将tshark所在的目录添加到系统的环境目录
具体使用文档参考:https://github.com/jmhIcoding/flowcontainer/blob/master/README.md
flowcontainer是一个很好用的库,面对一些流量基本的特征提取是完全够用的,但是想要提取更多维的特征就显得力不从心了,而且不支持深度包检测技术。
下面我就着重介绍一下NFStream这个工具库,NFStream是国外开发的一款基于Python编写的网络流量分析工具,功能更加强大一些。但国内用的人不多,相关文章也很少。
NFStream
NFStream的主要特点:
-
性能:NFStream的运行速度非常快,而且对CPU和内存的需求并不大
-
七层可见度:允许Nfstream执行可靠的加密应用识别与元数据提取
-
灵活性:引入NFPlugin插件概念,便于实现功能扩展
-
机器学习:支持以NFPlugin的形式添加训练模型
安装
pip3 install nfstream # pip3命令安装
git clone https://github.com/aouinizied/nfstream.git #将项目源码克隆至本地
NFStreamer
创建一个NFStreamer:
from nfstream import NFStreamer
my_streamer = NFStreamer(source="facebook.pcap", # or network interface
decode_tunnels=True,
bpf_filter=None,
promiscuous_mode=True,
snapshot_length=1536,
idle_timeout=120,
active_timeout=1800,
accounting_mode=0,
udps=None,
n_dissections=20,
statistical_analysis=False,
splt_analysis=0,
n_meters=0,
max_nflows=0,
performance_report=0,
system_visibility_mode=0,
system_visibility_poll_ms=100)
# 基本的使用方式就是循环遍历NFStreamer(分组)
for flow in my_streamer:
print(flow) # or whatever
NFStreamer的各个属性及含义
属性(默认) | 描述 |
---|---|
source="facebook.pcap" | pcap文件路径或网络接口名称 |
decode_tunnels=True | 开启/关闭GTP/CAPWAP/TZSP隧道解码 |
bpf_filter=None | 指定一个BPF filter过滤器,用于过滤选定的流量 |
promiscuous_mode=True | 启用/禁用混杂捕获模式 |
snapshot_length=1536 | 控制包切片大小(截断),以字节为单位 |
idle_timeout=120 | 空闲流(没有收到数据包)超过该值(秒)即过期 |
active_timeout=1800 | 活动时间超过该值(秒)的流将过期 |
accounting_mode=0 | 指定一个模式报告字节相关特性(0:链路层,1:IP层,2:传输层,3:有效载荷) |
udps=None | 指定用户定义的用于扩展NFStreamer的NFPlugins |
n_dissections=20 | 要为L7可见性特征分析的每个流分组数,当设置为0时,禁用L7可见性特性 |
statistical_analysis=False | 启用/禁用事后流统计分析 |
splt_analysis=0 | 指定第一个分组的长度序列,用于早期的统计分析,当设置为0时,禁用splt_analysis |
n_meters=0 | 指定返回前要捕获的最大流数,当等于0时不设置 |
max_nflows=0 | 指定并行计量过程的数量当,设置为0时,NFStreamer将自动根据运行主机上可用的物理核心对计量进行扩展 |
performance_report=0 | 性能报告间隔时间,单位为秒,当设置为0时禁用,忽略离线捕获 |
system_visibility_mode=0 | 通过探测主机来启用系统进程映射 |
system_visibility_poll_ms=100 | 设置系统进程映射特性的轮询间隔,单位为毫秒(0是最大可达速率) |
NFLow
NFlow是NFStream中的流表示形式。它包含了根据NFStreamer配置计算的所有流特征。
Nflow核心特征包括:
特征 | 数据类型 | 描述 |
---|---|---|
id | int | 流标识符 |
expiration_id | int | 流过期触发器的标识符,0表示idle_timeout,1表示active_timeout,-1表示自定义过期 |
src_ip | str | 源IP地址字符串 |
src_mac | str | 源MAC地址字符串 |
src_oui | str | 源组织唯一标识符字符串 |
src_port | int | 传输层源端口 |
dst_ip | str | 目的IP地址字符串 |
dst_mac | str | 目的MAC地址字符串 |
dst_oui | str | 目标组织唯一标识符字符串 |
dst_port | int | 传输层目的端口 |
protocol | int | 传输层协议 |
ip_version | int | IP版本 |
vlan_id | int | 虚拟局域网标识符 |
bidirectional_first_seen_ms | int | 第一个双向分组的时间戳,单位为毫秒 |
bidirectional_last_seen_ms | int | 最后一个双向分组的时间戳,单位为毫秒 |
bidirectional_duration_ms | int | 双向流持续时间,单位为毫秒 |
bidirectional_packets | int | 流量双向数据包累加器 |
bidirectional_bytes | int | 双向字节累加器(依赖accounting_mode) |
src2dst_first_seen_ms | int | 第一个src2dst分组上的时间戳,单位为毫秒 |
src2dst_last_seen_ms | int | 最后一个src2dst分组上的时间戳,单位为毫秒 |
src2dst_duration_ms | int | src2dst持续时间,单位为毫秒 |
src2dst_packets | int | src2dst数据包累加器 |
src2dst_bytes | int | src2dst字节累加器(取决于accounting_mode) |
dst2src_first_seen_ms | int | 第一个dst2src分组上的时间戳,单位为毫秒 |
dst2src_last_seen_ms | int | 最后一个dst2src分组上的时间戳,单位为毫秒 |
dst2src_duration_ms | int | dst2src持续时间,单位为毫秒 |
dst2src_packets | int | dst2src数据包累加器 |
dst2src_bytes | int | dst2src字节累加器(取决于accounting_mode) |
还有一些其他特征值包括:
-
隧道解码特征(TUNNEL DECODING FEATURES)
-
事后统计流特征 (POST-MORTEM STATISTICAL FEATURES)
-
早期统计特征 (EARLY STATISTICAL FEATURES)
-
系统可见特征 (SYSTEM VISIBILITY FEATURES)
-
流7层可见特征(NFLOW LAYER-7 VISIBILITY FEATURES)
详细参考:https://www.nfstream.org/docs/api
Pandas Dataframe转换
NFStream原生支持Pandas作为导出接口:
my_dataframe = my_streamer.to_pandas(columns_to_anonymize=[])
参数:columns_to_anonymize 要匿名的列名列表 (一般不用)
示例:
from nfstream import NFStreamer
my_dataframe = NFStreamer(source=path_pcap).to_pandas()[["src_ip", # 需要导出的特征列表
"src_port",
"dst_ip",
"dst_port",
"protocol",
"bidirectional_packets",
"bidirectional_bytes",
"application_name"]]
my_dataframe.head(5)
CSV文件转换
NFStream原生支持CSV文件格式作为导出接口:
total_flows_count = my_streamer.to_csv(path=None, columns_to_anonymize=[], flows_per_file=0, rotate_files=0)
参数:
-
path:指定csv结果文件的输出路径
-
flows_per_file:指定每个生成的文件的最大流量
-
columns_to_anonymize:要匿名的列名列表
-
rotate_files:限制磁盘存储使用的rotating文件数量
示例:
默认输出文件,是再原pcap文件名后面加上.csv
, 如a.pacp.csv
NFStream特征提取
NFStream相比于flowcontainer的几大优点:
-
原生支持Pandas导出接口和CSV导出接口。
-
事后统计流特征提取:NFStream进行了48个事后流统计特征提取,包括详细的TCP标志位分析,数据包大小和每个方向的到达间隔时间的最小、均值、最大值和标准差。
-
早期统计流特征提取:NFStream执行早期流(最多255个分组)统计特征提取(也称为SPLT分析)。将这些分组的方向、大小和到达间隔时间归纳为一个序列。
-
应用层可见性特征提取:Nfstream深度数据包检测引擎基于nDPI实现,它允许Nfstream执行可靠的加密应用识别与元数据提取(例如TLS, QUIC, TOR, HTTP, SSH, DNS)
-
系统的可见性:NFStream探测被监控系统的内核,以获取有关开放Internet套接字的信息,并在应用层收集有保证的真实值(进程名、PID等)。
事后统计流特征提取
只需在NFStreamer函数参数设置 statistical_analysis=True
即可开启事后统计流特征提取。
示例:
from nfstream import NFStreamer
my_streamer = NFStreamer(source=pcap,
n_dissections=0, # 第 7 层数据不可见
statistical_analysis=True)
for flow in my_streamer:
print(flow)
NFStream支持48个事后流统计特征提取:
bidirectional_min_ps=84,
bidirectional_mean_ps=92.0,
bidirectional_stddev_ps=11.313708498984761,
bidirectional_max_ps=100,
src2dst_min_ps=84,
src2dst_mean_ps=84.0,
src2dst_stddev_ps=0.0,
src2dst_max_ps=84,
dst2src_min_ps=100,
dst2src_mean_ps=100.0,
dst2src_stddev_ps=0.0,
dst2src_max_ps=100,
bidirectional_min_piat_ms=0,
bidirectional_mean_piat_ms=0.0,
bidirectional_stddev_piat_ms=0.0,
bidirectional_max_piat_ms=0,
src2dst_min_piat_ms=0,
src2dst_mean_piat_ms=0.0,
src2dst_stddev_piat_ms=0.0,
src2dst_max_piat_ms=0,
dst2src_min_piat_ms=0,
dst2src_mean_piat_ms=0.0,
dst2src_stddev_piat_ms=0.0,
dst2src_max_piat_ms=0,
bidirectional_syn_packets=0,
bidirectional_cwr_packets=0,
bidirectional_ece_packets=0,
bidirectional_urg_packets=0,
bidirectional_ack_packets=0,
bidirectional_psh_packets=0,
bidirectional_rst_packets=0,
bidirectional_fin_packets=0,
src2dst_syn_packets=0,
src2dst_cwr_packets=0,
src2dst_ece_packets=0,
src2dst_urg_packets=0,
src2dst_ack_packets=0,
src2dst_psh_packets=0,
src2dst_rst_packets=0,
src2dst_fin_packets=0,
dst2src_syn_packets=0,
dst2src_cwr_packets=0,
dst2src_ece_packets=0,
dst2src_urg_packets=0,
dst2src_ack_packets=0,
dst2src_psh_packets=0,
dst2src_rst_packets=0,
dst2src_fin_packets=0
事后流统计特征主要包括:TCP标志位分析,数据包大小和每个方向的到达间隔时间的最小、均值、最大值和标准差。
字段详细信息参照官方API文档:https://www.nfstream.org/docs/api
早期统计流特征提取
在NFStreamer函数参数设置 splt_analysis=N(N>0)
即可开启早期统计流特征提取。
示例:
from nfstream import NFStreamer
my_streamer = NFStreamer(source=pcap,
n_dissections=0, # 第 7 层数据不可见
splt_analysis=10)
for flow in my_streamer:
print(flow)
这个早期统计流特征提取,和Wireshark的流追踪功能类似,针对同一个TCP会话的数据流方向,数据包大小,到达时间间隔进行了统计。最多统计255个包,当 N>255 时程序报错。
这三个列表的列表长度均为N(splt_analysis=N):
-
splt_direction:分组的方向(0:src2dst, 1:dst2src, -1:no packet)
-
splt_ps:分组的大小(依靠accounting_mode, -1表示没有分组)
-
splt_piat_ms:到达间隔时间(第一个分组总是0,没有分组时总是-1)
应用层可见性特征提取
在NFStreamer函数中设置 n_dissection>0
即可开启7层可见性特征。
示例:
from nfstream import NFStreamer
my_streamer = NFStreamer(source=pcap, n_dissections=20)
for flow in my_streamer:
print(flow)
支持9个7层可见性特征:
application_name=SSH, # 应用程序名称
application_category_name=RemoteAccess, # 应用类别名称
application_is_guessed=1, # 表示检测结果是基于纯解析还是基于猜测启发式
application_confidence=1, # 底层检测方法(O:未知分类,1:仅通过4层端口得到的分类,3:基于部分/不完全DPI信息的分类结果,4:基于部分/不完全DPI信息的LRU缓存的分类结果,5:基于部分LRU缓存的分类结果(即会话之间的相关性),6:深度包检测)
requested_server_name=, # 请求的服务器名称(SSL/TLS、DNS、HTTP)
client_fingerprint=, # 客户端指纹
server_fingerprint=, # 服务器指纹
user_agent=, # 提取的用户代理为HTTP或用户代理标识符为QUIC
content_type= # 提取的HTTP内容类型
深度数据包检测引擎基于nDPI实现,支持这几种应用:TLS, QUIC, TOR, HTTP, SSH, DNS
系统的可见性
在NFStreamer函数参数设置 system_visibility_mode=1
即可开启系统的可见性。
from nfstream import NFStreamer
my_streamer = NFStreamer(source=pcap,
n_dissections=0, # 第 7 层数据不可见
system_visibility_mode=1,
splt_analysis=10)
for flow in my_streamer:
print(flow)
开启以后可以获取关于这个分组的通信进程的信息,包括进程名称(process_name)和进程ID(process_pid)。
我本地运行这个程序运行报错,不过感觉这个用处不大。
还有一个隧道解码特征(TUNNEL DECODING FEATURES),个人感觉几乎用不到。
NFPlugin扩展
NFPlugin不过多介绍了,前面介绍的内容在绝大数情况下都足够使用了。
NFPlugin是扩展NFStream的主要类,可以创建一组新的NFlow特性,可以来满足自定义需求。在使用之前需要导入NFPlugin模块 from nfstream import NFPlugin
关于更多关于NFPlugin更多内容,参照官方文档:https://www.nfstream.org/docs/api
*本文的大部分内容来自官方文档的英文机翻,如有不准确的部分请谅解。
参考文章:
https://pypi.org/project/nfstream/
https://www.nfstream.org/docs/api
https://github.com/jmhIcoding/flowcontainer/blob/master/README.md
若有错误,欢迎指正!o( ̄▽ ̄)ブ