流量特征提取工具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 层数据不可见
                         splt_analysis=10)
for flow in my_streamer:
    print(flow)

开启以后可以获取关于这个分组的通信进程的信息,包括进程名称(process_name)和进程ID(process_pid)。

我本地运行程序运行报错。
还有一个隧道解码特征,个人感觉用处也不大。

NFPlugin扩展

NFPlugin不过多介绍了,前面介绍的内容在绝大数情况下都足够使用了。

NFPlugin是扩展NFStream的主要类,可以创建一组新的NFlow特性,可以来满足自定义需求。在使用之前需要导入NFPlugin模块 from nfstream import NFPlugin

关于更多关于NFPlugin更多内容,参照官方文档:https://www.nfstream.org/docs/api

*本文的大部分内容来自官方文档的英文机翻,如有不准确的部分请谅解。

参考文章:
https://pypi.org/project/nfstream/
https://github.com/nfstream/nfstream/blob/master/examples/flow_printer.py
https://github.com/jmhIcoding/flowcontainer/blob/master/README.md


若有错误,欢迎指正!o( ̄▽ ̄)ブ

热门相关:哥哥的情人   Irati   逃离索比堡   利用私贷赚钱的老婆   MZ世代三岛