Python: 从pcap文件中提取每个TCP session的payload
如今,网络在我们生活中起到不可或缺的作用,同时也催生出很多与网络相关的问题。比如恶意软件检测、流量识别等。机器学习和深度学习的相关算法已经被广泛应用于这些问题上面了。
本人在进行Botnet detection学习的时候,遇到第一个问题就是TCP数据的获取。但是一般我们通过抓包工具获得的就是一些pcap文件。从这些文件中我们利用如dpkt和scapy等库,很容易可以获得文件中的数据。但是如果想把从pcap文件中获得更好的特征,我们一般需要把流量数据按照一定单位分隔开来。
代码借鉴:https://github.com/hmishra2250/Botnet-Detection-using-Machine-Learning/tree/master/Custom%20Flow%20Generator
1.数据分割的单位
这里仅讨论TCP数据的分割。一般来说分割的单位有:TCP flow 和 TCP session。
TCP flow: (源地址、源端口、目的地址、目的端口、传输层协议) 相同的流数据就是一个flow。
TCP session: 包含两个方向的TCP flow
从理解上来说,TCP session就是一次TCP connection中,服务器和客户端相互之间传送的所有packet。而TCP flow指得是一次TCP连接中,客户端->服务器的所有packet,或者是服务器->客户端的所有packet。
2.利用wireshark导出csv文件
获得pcap文件后,可以通过dpkt和scapy等库直接读入数据。但是我觉得如果能够直接操作.csv文件会更方便。
wireshark是著名的网络工具,当我们获得一个pcap文件的之后,我们可以增加或者删除我们想要的columns。
比如我们想要添加Sequence number为特征columns,我们找到相关信息点击右键,再选择用用为列即可。把所有需要的特征都选上之后,点击左上角"文件",选择“导出分组解析结果”,在选择.CSV文件即可。
这样就拥有了一个包含raw data的.csv文件数据集。
3.实现TCP session分割
这里利用Python实现将raw data分割成一个一个的TCP session。在分辨前后两行数据是否属于同一个TCP session时一般有如下标准:
1. 前后两行数据的(源地址、源端口、目的地址、目的端口、传输层协议) 是否相同。(这里说的是主机号pair相同即可,即认为服务器->客户端跟客户端->服务器是相同的)
2.前后两行数据的时间差是否大于某个阈值。
3.标志位。
我们知道每次TCP连接由三次握手开始,四次握手结束。因此在数据分割时,看到许多人会在检测到packet的FIN标志位为1时,就认为这是TCP connection结束。但是这其中隐含着一些问题。
首先我们抓包经常会抓到一些深色的带有Bad TCP标志的包,这些包是因为没收到确认重发,或者是顺序混乱等问题导致的。因此有可能会在一次Session中遇到多于两个带有FIN的包。另外四次挥手过程中,一共会有两个packet带有FIN标志位。所以以FIN为标准判断Session结束是不合理的。
于是本人使用的方法是:通过SYN标志为判断Session开始和结束。首先我们把数据按照(源地址、源端口、目的地址、目的端口、传输层协议)划分为不同的组,然后按照时间排序。接着一次遍历数据。如果当前数据的主机对与上一条数据的主机对不相同,代表Session结束,下一个Session开始。而如果遇到SYN标志位,也表示这是另一个Session的开始,上一个Session结束。(这里SYN判断主要是为了分辨相同主机对之间的多次TCP session)
所以具体程序如下,该程序没有考虑重传等问题,即获得的包有可能是重复的。因此想要修正的朋友,可以在读入时把所有Bad TCP的packet删除,或者通过Sequence number和ACK number排除重传的包:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import keras.Sequential'''
Dataset 包括的特征:
'No.', 'Time', 'Source Port', 'Answer RRs', 'Source', 'Destination','Destination Port', 'Length', 'Protocol', 'TCP Segment Len','Protocols in frame', 'IP_Flags', 'Next sequence number','Sequence number', 'tcp_Flags', 'udp_Length', 'TCP payload','Coloring Rule Name'
'''def flow_id(x):if pd.isnull(x['udp_Length']):protocal = 'TCP'else:protocal = 'UDP'if x['Source']>x['Destination']:return x['Source']+'-'+x['Destination']+'-'+str(x['Source Port'])+'-'+str(x['Destination Port'])+'-'+protocalelse:return x['Destination']+'-'+x['Source']+'-'+str(x['Destination Port'])+'-'+str(x['Source Port'])+'-'+protocalraw = pd.read_csv('wal') #只保留TCP数据
raw = raw[(raw['Source Port'].notnull()) & (raw['Destination Port'].notnull()) & (raw['Coloring Rule Name']!='Bad TCP')]
#raw = raw[(raw['Source Port'].notnull()) & (raw['Destination Port'].notnull())]
raw['tcp_Flags'] = raw['tcp_Flags'].apply(lambda x:int(x,16) if x!='' else 0)#定义数据流动方向和主机对+协议
raw['Forward'] = raw.apply(lambda x: 1 if x['Source'] > x['Destination'] else 0,axis=1)
raw['UFid'] = raw.apply(lambda x:flow_id(x),axis=1)#按照主机对和时间排序
raw = raw.sort_values(['UFid','Time'],ascending=True)
raw.reset_index(drop=True,inplace=True)#分离数据
raw_dict = raw.to_dict() #将dataset转换为字典,提高迭代速度prev = None
Flow = []
FlowNo = 0
count = 0for row in raw_dict['Source']:if prev == None: #new flow Flow.append(FlowNo)count = 1prev = raw_dict['UFid'][row]elif raw_dict['UFid'][row] == prev:#flow is already existingif raw_dict['tcp_Flags'][row] & 0x02: #SYNif raw_dict['tcp_Flags'][row] & 0x10: #SYN + ACKFlow.append(FlowNo)count+=1else:if count == 1: #当连续遇到多个SYNpacket时候,直接略过Flow.append(FlowNo)else:FlowNo = FlowNo + 1Flow.append(FlowNo)count = 1else:#New packet in a pre-existing flowFlow.append(FlowNo)count += 1else:#Previous Flow tuple didn't receive any more packets, start a new flowFlowNo = FlowNo + 1Flow.append(FlowNo)count = 1prev = raw_dict['UFid'][row]raw['FlowNo'] = Flow #获得每一个packet所属的Session的编号raw = raw[raw['TCP payload'].notnull()] #仅保留有payload的数据
Python: 从pcap文件中提取每个TCP session的payload相关推荐
- gnuradio上怎么使用python文件_使用Python从PDF文件中提取数据
前言 数据是数据科学中任何分析的关键,大多数分析中最常用的数据集类型是存储在逗号分隔值(csv)表中的干净数据.然而,由于可移植文档格式(pdf)文件是最常用的文件格式之一,因此每个数据科学家都应该了 ...
- 使用Python从PDF文件中提取数据
前言 数据是数据科学中任何分析的关键,大多数分析中最常用的数据集类型是存储在逗号分隔值(csv)表中的干净数据.然而,由于可移植文档格式(pdf)文件是最常用的文件格式之一,因此每个数据科学家都应该了 ...
- python在txt文件中提取段落_如何使用python从.txt文件中提取段落?
我需要从一个.txt文件中提取段落,其中每个段落都以字母摘要开头,如下所示.在 文摘:大规模多输入多输出天线系统.毫米波通信和超密集网络被广泛认为是 促进5G开发和部署的三大关键因素 系统.我们提出了 ...
- Python从视频文件中提取音频
利用python库moviepy或者ffmpeg处理 # 这是一个示例 Python 脚本. from moviepy.editor import * import tkinter as tk fro ...
- python调用simulink_使用Python从dbc文件中提取simulink建模数据定义
使用dbc文件建模完成CAN通讯是一种比较高效的开发模式,不过在建模的过程中dbc文件中描述的数据需要自己去定义.使用文本编辑工具打开dbc文件可以看到,实际上dbc文件是一个可以进行语义解析的文本. ...
- Python从txt文件中提取特定数据
本段代码用于,想要从一段txt文件中只提取目标数据的情况. 代码: def get_data(txt_path: str = '', epoch: int = 100, target: str = ' ...
- python从html拿到数据,python - 使用BeautifulSoup和Python从HTML文件中提取数据 - 堆栈内存溢出...
我需要提取的数据可以在不同的标题下找到. 这是我到目前为止: from BeautifulSoup import BeautifulSoup ecj_data = open("data\ec ...
- python从视频中提取音频信号_通过python从音频文件中提取音频
我认为你的问题有三个不同的部分: >如何将音频文件加载到python中? >如何计算python中的频谱? >如何处理频谱? 1.如何在python中加载音频文件? 使用scipy可 ...
- python从pdf文件中提取文本,并自动翻译
针对Python 3.5.2 测试 首先安装两个包: $ pip install googletrans $ pip install pdfminer3k googletrans会提供一个命令tran ...
最新文章
- JS 缓存 设置临时缓存和长期缓存 sessionStorage localStorage
- MySQL导入.sql文件及常用命令
- 《Hadoop基础教程》之初识Hadoop
- python官网下载步骤图解-下载及安装Python详细步骤
- IK分词源代码分析学习——与solr4.0接口
- 在Access和 SQL Server中通配符的应用方法
- JZOJ 3852. 【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- docker(4):docker的安装(centos7)和加速
- es6 属性及常用新属性汇总
- NModBus的使用
- 光伏发电极其并网控制matlab/simulink仿真文件,最大功率点跟踪采用扰动观察法
- java订餐管理系统代码,基于JAVA的订餐管理系统
- 就工业企业智慧能源能效管理系统建设问题探讨!
- Android 微信聊天页面
- 华美天气(数据来源:和风天气 API)
- HashMap 容量为2次幂的原因
- 初学安装oracle11g遇到的问题,以及解决方案
- 考考你的基础知识:C++ 文件操作ofstream、ifstream使用
- NYU计算机系,NYU的Computer Science and Engineering「纽约大学计算机科学与工程系」
- 来自国外高级Java架构师的采访总结