- 【参考文献】刘治国,蔡文珠,李运琪,等.基于序列统计的未知无线协议特征提取方法[J].计算机工程,2021,47(11):192-197.DOI:10.19678/j.issn.1000-3428.0059551.
- 【注】本文仅为作者个人学习笔记,如有冒犯,请联系作者删除。
这篇题为《基于序列统计的未知无线协议特征提取方法》的论文,主要研究在未知无线网络环境下,如何从比特流形式的协议数据中提取特征。由于比特流形式的协议数据帧特征不明显,且缺乏先验知识进行分析,特征提取面临较大困难。为了解决这一问题,作者提出了一种基于序列统计的特征提取方法。
在未知无线网络环境下,比特流形式的协议数据帧特征不明显,且缺乏先验知识对其进行分析,造成特征提取困难。提出一种利用序列统计提取未知无线协议特征的方法。统计数据中定长序列出现的频次和位置,根据概率和相似性筛选满足频繁条件的固定序列和交互序列,得到频繁项集,并借鉴关联规则连接频繁项集中的频繁序列,去除冗余的序列信息,得到协议特征集。仿真结果表明,该方法能够有效提高未知无线协议特征提取效果,准确率稳定在90%以上。
关键词:特征提取;序列统计;固定序列;关联规则;比特流
1.引言
由于比特流形式的协议包含的数据特征形式较为单一,因此提取关键的比特流序列作为协议特征是一种有效的方式。通过挖掘特征序列所在帧内位置、特征序列帧内位置关系等辅助信息,并将关键序列、序列位置和序列位置关系作为复合特征,可提高协议识别的准确率。
为提高未知协议特征提取的准确率,本文提出一种基于序列统计的特征提取方法FEMSA。统计定长序列出现的位置和频次,以序列是否固定和交互作为筛选条件来提取频繁项,从而提高频繁项提取的效率。同时通过关联规则连接频繁序列,去除冗余的序列信息来优化频繁项集,最终得到协议特征集合。
2.比特流形式协议
完整的帧格式由帧头、控制段、数据段、验证信息等组成,这些部分又可以分为固定域和变化域。
- 固定域包括固定序列和交互序列。固定序列为在同一位置内只出现一种序列或者固定出现几种序列,若2种序列交替出现,则称为交互序列。
- 变化域可称为数据域,指各种变化的数据序列。
为在后文中方便描述,做以下定义:
- 定义1:Fi为提取出的频繁项,Ci为提取出的协议特征,两者都由三元组[Si,Li,Pi]表示。其中:Si为统计序列;Li为序列Si在帧内出现的位置;Pi为序列Si在位置Li出现频率,频率阈值min_sup可以通过Jaccard系数来获得。
- 定义2:二元组[Lij,Tij]表示某一序列的位置和在当前位置出现的频次。其中:Lij为序列出现的位置;Tij为序列在位置Lij处出现的频次。
- 定义3:二元组[Sij,Pij]表示在帧内某一位置上出现的序列和序列在当前位置出现频率。其中:Sij为在某一位置处出现的序列;Pij为Sij序列在当前位置出现的频率。
3.基于序列统计的特征提取方法
常用的协议特征提取方法是遍历统计,即统计可能出现的比特组合各种状态出现的频次,选取出现频次多的比特组合供后续研究使用。若未知协议特征长度不固定,则需要在扫面数据帧集时逐次增加比特数,由此带来因反复扫描数据帧集而造成分析工作量大的问题。
对此,文献[13]提出了基于特征分析矩阵的协议特征获取方法FAMM。该方法无需反复扫描数据帧集,但是需要创建特征分析矩阵存储每一个备选特征序列的后续一定长度字符串,且备选特征序列长度增加需扫描特征分析矩阵。当源数据量很大时,需要增大空间创建分析矩阵,而当特征长度逐次增加比特时,则需要反复扫描特征分析矩阵。因此,文献[13]方法并未从本质上改变因长度变化导致的多次扫描数据时间消耗的问题。
[13] 张永光,翟绪论. 比特流分析[M]. 北京:电子工业出版社,2018. ZHANG Y G,ZHAI X L. Bit flow analysis [M]. Beijing: Electronic Industry Press,2018.(in Chinese)
本文结合闭包性思想[16]提出一种定长统计序列频繁度的方法,通过遍历一次数据,建立一个序列长度为lbit的特征分析矩阵A,记录统计序列、序列的位置和频次,同时统计频次大于min_sup的序列,得到初始频繁项集。
对频繁序列仅通过出现的频次进行筛选,造成出现错误序列的可能性较大,对此,本文增加筛选条件以降低误识率。如图1所示,由于协议中存在固定和交互序列,因此为提高特征提取准确率和协议识别效率,挖掘更多的协议特征信息,本文根据概率统计和相似性度量思想,在满足频繁条件的序列中提取固定和交互序列,得到频繁项集。由于前序提取结果中存在序列重叠的问题,因此得到的频繁项集中存在大量的冗余信息。此外,真实的协议特征长度是不固定的,采用定长序列统计的方法无法完整表达协议特征。本文引入关联规则的思想连接相关频繁序列,以得到更长的频繁序列,并以更长频繁序列替换原有的频繁序列更新频繁项集,将协议特征集提取分为频繁项集提取和关联规则连接频繁序列两部分。
特征提取过程如图所示。
3.1 频繁项集提取
初始频繁序列提取过程。设初始序列长度l,将2l种lbit组合作为初始序列进行统计。扫描数据,统计所有2l种长度为l的比特组合出现的位置和频次以及存储位置和频次,构成特征分析矩阵A。该矩阵含有2l行,为列可增矩阵,每行元素数量不定,每个元素表示为[Lij,Tij]。特征分析矩阵A存储多种序列出现的位置和频次,矩阵的一行表示同一序列出现的位置和频次,表示如下:
构造特征分析矩阵(Construct the Feature Analysis Matrix,CFAM)算法描述如下:
算法:CFAM算法
输入:n帧比特流形式的数据
输出:特征分析矩阵A
根据概率统计和相似度思想提取固定序列和交互序列对初始频繁项集进行筛选。由于协议固定序列和交互序列出现的情况与位置和包含内容有关,因此根据初始频繁项集构建一个索引为位置Li的查询矩阵B,存储特征序列和频率。查询矩阵B是一个列可增矩阵,由二元组bij组成,存储在不同位置上出现的序列和序列在当前位置上出现的频率,矩阵的一行表示在相同位置上出现的所有序列和序列频率。
通过对大量协议帧集统计得出固定序列和交互序列在协议中存在的规律,通过查询矩阵B对满足规律的固定序列和交互序列提取到频繁项集。固定序列和交互序列提取(FixedandInteractiveSequenceExtraction,FISE)算法描述如下:
算法:FISE 算法
输入:查询矩阵 B
输出:频繁项集 F
在位置Li上的序列出现频率为1,对单协议而言这样的序列一定是此协议的固定序列,在位置Li上出现的序列频率和为1,说明在当前位置反复出现几个序列,这几个序列亦是此协议在当前位置上的固定序列。当similar()值超过repe_rate阈值时,即在Li位置超过repe_rate的数据在Lj位置的集合中也出现了,将位置Li和Lj出现的初始频繁序列作为交互序列提取出来;若在位置Li上,2个初始频繁序列具有repe_rate的相似度,则作为交互序列提取出来。
上述方法能够识别提取固定序列和在2个位置出现或相同位置出现的相似度很高的交互序列。在分析中出现固定序列和交互序列提取冲突时,以交互序列提取为准。但是交互序列的提取存在一定的局限性:提取的数据必须是短时间内有交互的数据,即对于在某些设备只发送信息而不接收信息或在另外的设备只接收信息而不发送信息的环境下抓取的数据帧,用此方法提取交互序列存在一定困难性。
3.2 关联规则连接频繁序列
本文引入关联规则的思想,通过频繁序列连接(FrequentlySequenceConnected,FSC)算法连接频繁项集中的序列得到更长频繁序列,更新频繁项集。此操作能够去除冗余信息,得到更为精简的频繁序列,最终得到协议特征集。
通过 FSC 算法对频繁项集中的频繁序列根据关联的思想进行连接,去除频繁项集中冗余信息,优化频繁项集得到协议特征集。算法描述如下:
FSC 算法
输入: 频繁项集 F输出: 协议特征集 C
4.代码复现
假设数据为这种比特流的数据序列形式:
给出这三个算法的python的实现代码,数据中,每一行为一个协议数据序列。
4.1 CFAM 算法
import numpy as np
def construct_feature_analysis_matrix(data, sequence_length):
num_sequences = 2 ** sequence_length
feature_matrix = [[] for _ in range(num_sequences)]
for i, frame in enumerate(data):
for j in range(len(frame) - sequence_length + 1):
sequence = frame[j:j + sequence_length]
sequence_index = int(sequence, 2)
if not any(pos == j for pos, _ in feature_matrix[sequence_index]):
feature_matrix[sequence_index].append([j, 1])
else:
for pos_freq in feature_matrix[sequence_index]:
if pos_freq[0] == j:
pos_freq[1] += 1
break
return feature_matrix
# Usage
sequence_length = 3 # Example sequence length
data_sequences = data[0].tolist()
feature_matrix = construct_feature_analysis_matrix(data_sequences, sequence_length)
4.2 FISE 算法
def fixed_and_interactive_sequence_extraction(feature_matrix, min_sup, repe_rate):
frequent_items = []
for index, sequences in enumerate(feature_matrix):
total_count = sum(freq for _, freq in sequences)
if total_count / len(data_sequences) >= min_sup:
frequent_items.append([index, sequences])
fixed_sequences = []
interactive_sequences = []
for seq_index, sequences in frequent_items:
if len(sequences) == 1 and sequences[0][1] / len(data_sequences) == 1:
fixed_sequences.append([seq_index, sequences[0][0], 1])
elif len(sequences) == 2:
s1, s2 = sequences
similar = len(set(s1).intersection(s2)) / len(set(s1).union(s2))
if similar >= repe_rate:
interactive_sequences.append([seq_index, sequences])
else:
total_freq = sum(freq for _, freq in sequences)
if total_freq == len(data_sequences):
fixed_sequences.append([seq_index, sequences[0][0], 1])
return fixed_sequences, interactive_sequences
# Usage
min_sup = 0.1 # Example minimum support threshold
repe_rate = 0.8 # Example repeat rate threshold
fixed_sequences, interactive_sequences = fixed_and_interactive_sequence_extraction(feature_matrix, min_sup, repe_rate)
4.3 FSC 算法
def frequently_sequence_connected(fixed_sequences, interactive_sequences, min_conf):
frequent_item_set = fixed_sequences + interactive_sequences
connected_sequences = []
for i in range(len(frequent_item_set)):
for j in range(i + 1, len(frequent_item_set)):
seq1, pos1, _ = frequent_item_set[i]
seq2, pos2, _ = frequent_item_set[j]
if pos1 <= pos2 + len(seq2) or pos2 <= pos1 + len(seq1):
combined_seq = f"{seq1}{seq2}"
combined_freq = sum(1 for seq in data_sequences if combined_seq in seq)
combined_prob = combined_freq / len(data_sequences)
if combined_prob >= min_conf:
connected_sequences.append([combined_seq, pos1, combined_prob])
return connected_sequences
# Usage
min_conf = 0.6 # Example minimum confidence threshold
connected_sequences = frequently_sequence_connected(fixed_sequences, interactive_sequences, min_conf)
对提供的代码进行微调,可实现代码:
# — coding: utf-8 —
import numpy as np
import pandas as pd
# Load the data
file_path = 'xxx.csv'
data = pd.read_csv(file_path, header=None)
# Display the first few rows of the data to understand its structure
print(data.head())
# CFAM Algorithm
def construct_feature_analysis_matrix(data, sequence_length):
num_sequences = 2 ** sequence_length
feature_matrix = [[] for _ in range(num_sequences)]
for i, frame in enumerate(data[0]):
frame = frame.strip() # Remove any surrounding whitespace
for j in range(len(frame) - sequence_length + 1):
sequence = frame[j:j + sequence_length]
if all(c in '01' for c in sequence): # Ensure the sequence is a binary string
sequence_index = int(sequence, 2)
if not any(pos == j for pos, _ in feature_matrix[sequence_index]):
feature_matrix[sequence_index].append([j, 1])
else:
for pos_freq in feature_matrix[sequence_index]:
if pos_freq[0] == j:
pos_freq[1] += 1
break
return feature_matrix
# Usage
sequence_length = 3 # Example sequence length
data_sequences = data[0].tolist()
feature_matrix = construct_feature_analysis_matrix(data_sequences, sequence_length)
# Displaying the feature matrix for the first few sequences
print("Feature Matrix:", feature_matrix[:5])
# FISE Algorithm
def fixed_and_interactive_sequence_extraction(feature_matrix, min_sup, repe_rate):
frequent_items = []
for index, sequences in enumerate(feature_matrix):
total_count = sum(freq for _, freq in sequences)
if total_count / len(data_sequences) >= min_sup:
frequent_items.append([index, sequences])
fixed_sequences = []
interactive_sequences = []
for seq_index, sequences in frequent_items:
if len(sequences) == 1 and sequences[0][1] / len(data_sequences) == 1:
fixed_sequences.append([seq_index, sequences[0][0], 1])
elif len(sequences) == 2:
s1, s2 = sequences
similar = len(set(s1).intersection(s2)) / len(set(s1).union(s2))
if similar >= repe_rate:
interactive_sequences.append([seq_index, sequences])
else:
total_freq = sum(freq for _, freq in sequences)
if total_freq == len(data_sequences):
fixed_sequences.append([seq_index, sequences[0][0], 1])
return fixed_sequences, interactive_sequences
# Usage
min_sup = 0.1 # Example minimum support threshold
repe_rate = 0.8 # Example repeat rate threshold
fixed_sequences, interactive_sequences = fixed_and_interactive_sequence_extraction(feature_matrix, min_sup, repe_rate)
print("Fixed Sequences:", fixed_sequences)
print("Interactive Sequences:", interactive_sequences)
# FSC Algorithm
def frequently_sequence_connected(fixed_sequences, interactive_sequences, min_conf):
frequent_item_set = fixed_sequences + interactive_sequences
connected_sequences = []
for i in range(len(frequent_item_set)):
for j in range(i + 1, len(frequent_item_set)):
seq1, pos1, _ = frequent_item_set[i]
seq2, pos2, _ = frequent_item_set[j]
if pos1 <= pos2 + len(seq2) or pos2 <= pos1 + len(seq1):
combined_seq = f"{seq1}{seq2}"
combined_freq = sum(1 for seq in data_sequences if combined_seq in seq)
combined_prob = combined_freq / len(data_sequences)
if combined_prob >= min_conf:
connected_sequences.append([combined_seq, pos1, combined_prob])
return connected_sequences
# Usage
min_conf = 0.6 # Example minimum confidence threshold
connected_sequences = frequently_sequence_connected(fixed_sequences, interactive_sequences, min_conf)
print("Connected Sequences:", connected_sequences)