开启数据分析之旅
一次性进群,长期免费索取教程,没有付费教程。
教程列表见微信公众号底部菜单
进微信群回复公众号:微信群;QQ群:460500587
微信公众号:计算机与网络安全
ID:Computer-network
如果您曾经尝试学习一门编程语言,会知道,从“Hello World”示例开始学习是迅速了解这门语言的好办法。当语法被编译器/解释器成功编译,熟悉的内容展现在屏幕上的时候,这一刻的成就感会成为您对这门语言理解上的催化剂,让您欣然学习这门新语言。
本文将采取“Hello World”示例的理念并且将其扩展至安全数据分析所使用的示例,您可以从中学习、执行并且验证自己的分析。将大量使用Python和R语言实例来展现两种语言的相似性、优势,以及在实际数据分析领域中两种语言的差异。
在这里建议使用IPython Notebooks或RStudio作为分析及探索的环境,因为这两种工具提供了宽松的环境,使用它们在shell下可以更灵活地书写、保存以及运行程序。图1和程图2是本文代码的起点。
图1 R代码
图2 Python代码
假设您正在处理安全运营中心(Security Operation Center,SOC)管理者给出的一个问题。SOC的分析师们正被大量琐碎告警所淹没,仅因为安全信息和事件管理系统(SIEM)中增加了一个新的数据集。他们希望您能在不影响可视化效果的前提下帮助减少这些琐碎的告警。
这是一个能够通过数据分析来解决的好问题。我们应该能够在进行探索性的数据分析之后,提出一个可靠的、具有实际意义的问题,并且尽力帮助SOC解决这个问题。
一、获取数据
我们正在进入信息安全的数据时代。当前的挑战不是从哪里获得数据而是如何处理数据,数据集中信息的种类将决定您的研究类型。
对于这个例子,SOC选择整合AlienVault的IP信誉数据库放入SIME。AlienVault自己研发了OSSIM,OSSIM既是一个开源的安全信息管理器,也是一个专有的统一安全管理(USM)产品。OSSIM可以使用各类免费的数据集,其中包含来自互联网的各种类型的“坏数据”。AlienVault提供各种格式的免费数据。在这里,您所使用的是OSSIM格式的数据,在众多数据格式中它能提供最丰富的信息。
AlienVault按小时更新其IP信誉数据集,并且同步产生一个名为“修订版”(revision)的文件,使您能够确定您正在使用的是最新数据集或保存了历史数据集。如果您计划对这个数据集进行长时间的分析(这通常称为纵向研究),一个好的办法是修改一些代码来执行检查,看看是否需要下载一个新的数据集,即使是在进行一些预定的作业时。
在进行探索性分析或者想先看一看数据集的时候,您可以通过浏览器(或者使用wget和curl命令)将它下载下来。AlienVault数据库的大小将近16MB。当您下载了AlienVault IP信誉数据库并且验证了第一部分的数据元素时,您会对这些数据的内容和格式产生一些想法,这些想法会在您阅读和处理数据的过程中派上用场。在后续的代码中,您可以使用一些简单的Linux/UNIX命令进行下载:
对于大多数项目,最好养成直接从您的分析脚本中获取数据源的习惯。如果您仍然喜欢手动下载文件,应该在程序中增加一些注释来记录数据的来源以及当前分析数据的获取时间。这些注释能够帮助您在之后更容易地重复这些分析。一定会比您预期的更频繁地重新阅读您的代码以及重新进行分析。
接下来的示例(图3和图4)展示了如何使用R和Python两种语言来获取这些数据。如果您依照RStudio或者IPython,所有的代码示例都假定位于项目结构的顶层的工作目录。对于大多数情况,代码块是独立的,但每个块都期望在已经运行了RStudio或IPython的会话中执行这部分片段以及后面的片段。
图3 R代码
图4 Python代码
R语言和Python语言的代码看起来非常相似并且遵循相同的基本结构:对URL和文件名尽可能使用变量,在重新下载之前验证这些数据文件是否已经存在。
获得了IP信誉数据,到了读入并使用这些数据的时候了。
二、读入数据
R语言和Python(特别是pandas)在读取和解析数据结构进行处理时能够处理复杂的数据。R的read.table()、read.csv()、read.delim()函数以及pandas的read_csv()函数几乎覆盖了所有的分隔文件读取的需求,并且为各类劣质的输入文件提供了强大的配置选项。
合理的分隔是革命性技术
Base R和Python的pandas能阅读包含分隔符的文件,虽然它们不知道分隔符会在什么时候出现,以及分隔符具体是什么,但是,数据科学社区的共识是分隔符应该是逗号分隔值(CSV)或者制表符(tab)分隔值(TSV),绝大多数样本数据集都可以使用其中一种分隔符。CSV格式的完整定义在RFC 4180中,具有以下高级属性:
每行应只有一个记录。
数据文件可以包含一个可选的标题行。
报头和数据行有用逗号(或制表符)分隔的字段。
每行应该有相同的字段数。
字段中的空格被视为显著标识。
虽然RFC 4180明确规定逗号是一种分隔符,制表符也可以作为分隔符(没有相关的RFC专门说明制表符分隔值)。
安全领域的很多工具都能够导入和导出CSV格式文件。如果打算在类似Hadoop的环境中完成任何工作,您需要熟悉CSV/TSV。
另一种构建格式是JSON(JavaScript Object Notation),该格式广泛应用在服务器和浏览器之间传输数据。JSON格式也是很多NoSQL数据库环境/工具的基础数据格式。JSON格式定义有两个主要结构:
成对的名称/数值集合(一个“字典”)。
一个有顺序的数值列表(一个“数组”)。
相较于CSV和TSV格式,JSON格式保证了更丰富、更复杂的数据表示,而且,JSON正在迅速取代另一种流行的、结构化的数据格式——可扩展标记语言(the Extensible Markup Language,XML)。这是因为JSON更简洁的语法,更易于解析,以及(通常)更强的可读性。虽然XML已经并将继续作为文档表示格式,但您现在应该考虑使用JSON作为您的结构化数据处理格式。
从下载文件的粗略检查中您能看到AlienVault数据有一个相当简单的记录格式,该格式包含使用#作为分隔符的八个字段:
注意,信誉数据文件缺少可选报头,所以上述示例代码手动指定了更有意义的列名称。这是一个可选的步骤,但是它可以在扩展分析时避免混淆,同时,它可以在您添加额外数据集时建立整个数据帧的一致性。
记录格式的一致性使每种语言的数据有相同的消耗。在每种语言/环境中,我们遵循下面的模式:
读取数据。
分配有意义的列名(如果需要的话)。
使用内置函数来获取数据的结构概述。
阅读前几行数据,通常使用head()函数。
后续的代码(图5和图6)是基于前面的代码,不能保证它们在其他地方正常工作。
图5 R代码
图6 Python代码
在Canopy内,IPython有一系列函数将数据输出到一个HTML视图格式(见图7),该格式可以使图6中的head()输出更易阅读(见图8)。
图7 输出到一个HTML视图格式
图8 IPython HTML head()函数输出
三、探索数据
现在是时候把您的安全领域专业知识加进来以探索与发现数据中的奥秘。这将促使您提出和回答好的问题。即便有近26万条记录,也会有很多工具随时告知您数据中有什么内容。
在开始深入探索数据之前,我们总结了一些关于数据的信息:
Reliability、Risk和x是整型。
IP、Type、Country、Locale和Coords是字符串。
IP地址使用点分四组表示法存储,而不是主机名或十进制格式。
每个记录与唯一的IP地址关联,所以共有258626个IP地址(在本次下载中)。
每个IP地址已经通过Coords字段被地理定位为经度和纬度,且记录在同一个字段中并用逗号分隔。如果您希望使用该字段,就必须进一步解析。
当您有描述数量的变量,可以尝试分析变量的基本描述性统计数据。这些统计数据包括:
最小和最大值;求差可以得到范围(范围=最大值–最小值)。
中位数(数据集正中的数值)。
第一和第三个四分位数(是第25和75百分位数,或者你可以认为它是第一个半部分数据的中间值和最后一个半部分数据的中间值)。
均值(所有数据值求和然后除以数据数量)。
您可以认为最大值、最小值、中位数和两个四分位数是一个数据集的五数概括法(由Tukey发明),并且两种语言都有内置函数计算它们,即R中的summary()和Python中的describe(),两种语言同样有函数可以计算均值。请阅读Reliability和Risk(图9和图10)两个主要数据行的概要。
图9 R代码
图10 Python代码
正如这些结果,Reliability列可能存在于[1…10]的范围,而Risk列(AlienVault说其可能的归格范围是[1…10]),实际上只存在于[1…7]范围。您也可以看到,Risk和Reliability都以2为中心。
您现在可以深入一些,共同使用Reliability、Risk、Type和Country这些字段定义数据集的种类。尽管我们认为Reliability和Risk仅是数值,但是它们实际上是序数,这意味着各列中的每个项都可以赋予一个整数,在Reliability和Risk中数值4实际意义不一定指的是数值2的两倍,这意味着当Reliability和Risk的值为4时仅表示相比于它们值为2时程度更高。换言之,这些数据更像是标签而不是仅代表数值大小。分类数据也看做“标称值”(nominal values)、“因子”(factor),或在某些情况下是“定性变量”(qualitative variables)。
“数据”不仅仅是“数据”吗?
您可能已经习惯了从整体的角度处理数据,认为日志文件内容和数据库提取的信息仅仅是数据。如果您习惯了处理电子表格形式的数据(如Microsoft的Excel),您很难改变对它的固有认识。实际上,单个的数据元素可以分为两类:定量(quantitative)数据和定性(qualitative)数据。定量数据元素代表实际数量,而定性数据(或分类数据)元素是对性质的描述。
TCP或UDP的端口号是数字,但是它们不代表数量;当使用数据命名实体时,它们只是分类信息的一部分。接口“22”实际上并不大于或小于接口“7070”。相反,“传输的字节数”或者“染毒主机数”代表了具体数量并且可以对比大小。
分类数据在R中作为factor进行操作被控制,在Python中作为pandas Categorical类。实际上R和Python都有丰富的函数来实现因子的组建、分割、提取和分析。在图5中,在扫描了AlienVault IP信誉数据文件后,R做出了合理的推测,IP、类型、国家和区域在本质上都是分类。国家名称和恶意软件类型简单定义为类型(统计方面的标称数据)。您也会发现R不能正确地识别出Reliability和Risk的定性性质,尽管有意义明确的序列数值,例如风险级别“5”高于“1”,但是序列数值不代表具体数量。(这意味着您不能计算Risk的均值或与其他Risk值做减法。)
在R中,定性和定量变量的差别由summary()函数自动处理(见图11),而且它会显示每个类别的计数。这个工作对定量变量不起作用。当变量中存在太多独立数值时,为了得到计数,可以使用table()函数。在Python中,您可以生成一个简短的函数,利用pandas转换数据帧的列(它只是一个数组),将其转换为一个命名恰当的Categorical对象(见图12),您可以适当调整来得到相似的有用输出。
图11 R代码
图12 Python代码
这些数值表能帮助您了解数据的概况,但是一个数据分布图能提供一个全新的视角,让人们了解到单纯的数字不足以展示数据。我们以一个简单的柱状图给出Country、Risk和Reliability因子快速直观的概述(分别参见图14、16、18)。您将需要单独运行每个R代码来得到每幅图(分别参见图13、15、17)。
图13 R代码
图14 国家(Country)因子柱状图(R)
图15 R代码
图16 风险(Risk)因子柱状图(R)
图17 R代码
图18 可靠性(Reliability)因子柱状图(R)
这些可视化程序的Python版本在图19、图20和图21中。
图19 Python代码
图20 Python代码
图21 Python代码
图24-26所示的国家图说明了确实有一些国家明显存在更多的恶意节点,您可以通过一个时刻的数量来观察列表中前十个国家的数量比例(图22和图23)。
图22 Python代码
图23 Python代码
图24 国家(Country)因子柱状图(Python)
图25 可靠性(Reliability)因子柱状图(Python)
图26 风险(Risk)因子柱状图(Python)
这个快速计算展示了列表中中国和美国共统计出大约46%的恶意节点,而俄罗斯大约有2.4%。在这里,探索的关键点之一是如何比较各种行业报告,因为您期望这些国家中的多个都出现在前十位。然而,一些国家的节点数量显示出数据集可能有一些偏差。您还可以看到,3%的节点不能地理定位(在R程序输出中的[other]分类)。
对于Risk变量,您会发现大多数节点的风险都是微不足道的(非常低以至于可以忽略)。有一些其他元素很有特点,实际上没有端点在1、5、6或7类别中,同时也没有端点存在于剩余的定义范围[8-10]中。这种异常是一种标志,值得深入挖掘,这个异常是数据集内容不均衡的直接证据。
最后,节点的Reliability率也显得有些偏斜(也就是其分布偏向了均值或呈集中趋势)。大部分数值被分类到级别2和级别4中,大于级别4的评级不多。可信度评级完全没有级别3,这个现象应引发一些思考。它也许说明了评级分配的一种系统缺陷,也可能您至少有两个独立的数据集。无论如何,大量数据集中在级别2和级别4而少量集中在级别3这个现象是一个标志,您应进一步探索,因为它有些奇怪并令人惊讶。
您现在有些线索并对数据核心内容的构成有了更清晰的认识。这个初步的分析给您足够的信息来制定研究问题。
四、回到具体问题
考虑AlienVault信誉数据的问题和主要用例:将信誉数据导入SEIM或入侵检测系统/入侵防御系统(Intrusion Detection System/Intrusion Prevention System,IDS/IPS)来警示应急响应小组成员或录入/阻止恶意活动。如何进行设置使信誉数据的总览结果影响SIEM的配置,以确保产生最少数量的“琐碎”的警报?
让我们通过下面的问题将上述问题转化为更实际的问题:“信誉数据库中的哪个节点代表了潜在的真正威胁?”
AlienVault同时包含Risk和Reliability字段是有原因的,您应该能够使用这些属性将节点分为两类:1)您真正关心的节点,2)其他内容。“真正关心”的定义可能有些主观,但是,想依赖258626个节点中的一个来检测到所有的活动并生成警报是不现实的。必须生成优先分流或优先级,该过程最好基于数据的统计分析和证据来生成分流和优先级,而不是仅单独利用专家系统或突发奇想。
您可以通过对比Risk和Reliability因子发现哪些节点需要引起注意。关联表是一种特定变量的多元频率分布的表格视图,可以帮助您完成这项工作。换句话说,关联表可以显示两个变量之间的关系。在建立关联表后,您可以从数据和图形的结果发现AlienVault节点在哪里“聚集”。
图27的R代码的输出结果显示在图28中,该图以分级和尺寸、颜色定量表示的形式展现了关联表的输出。而图29的Python代码用于生成一个标准的热度图(见图30),该热度图只依靠颜色来表示数量。(热度图是一种图形表示,它将包含在矩阵中的各个数值表示为颜色。结合上述两个因子,很明显数据集的值集中在[2,2]附近,这是一种偏差的标志。
图27 R代码
图28 风险(Risk)/可靠性(Reliability)关联表分级图(R)
图29 Python代码
图30 风险(Risk)/可靠性(Reliability)关联表热度图(Python)
有趣的是,您可以确定您所看到的现象是否是偶然,或者发现它们的潜在意义。尽管您需要做一些高级统计或使用Fisher准确度检验,但不要觉得麻烦。如果您假设Risk和Reliability的所有值都是等概率出现会怎么样?分级图是什么样?您应该想到在系统和数据收集过程中存在一些因素,导致一些组合结果出现的概率会比较大。但是它们和当前数据差别有多大呢?
您可以使用sample()函数生成正态分布的随机样本,如[1,7]和[1,10],然后利用这些随机样本构建一个关联表。多次运行将得到不同的随机表。每次运行称为随机过程的实现(realization)。
图31中的R代码生成了图32中的分级图,该图说明了两个内容。第一,您可以用少量的代码制作精美的随机方块。第二,确实存在一些因素使节点趋向于较低的Risk和Reliability类(也就是趋向于0)。这可能是因为数据只具有低风险性和可靠性,或者采样方法或评分系统误导了数据的分布。
图31 R代码
图32 风险(Risk)/可靠性(Reliability)无偏估计图(R)
现在将您的注意力转移到Type变量,看看是否能在Risk和Reliability的评级结果间建立关系。仔细观察Type变量,您会发现一些条目的内容已经超出了“类型”给它们定义的范围,这些内容由分号分隔(如共有215个Scanning Host;Malicious Host值)。因为您想看到这些类型的比较,这些组合类型不应该和其他类型混在一起。因此,不需要解析出多类型的节点,您应该把它们归为一个Multiples类以便表示它们被赋予了多种类型的属性。现在,您可以生成一个三路关联表。在坐标系中加入Type列观察其对结果的影响。
图33中的R代码生成了图34中的三路关联表点阵图,您可以对比在Risk和Reliability分类中Type产生的影响。相应的Python代码在图35中,用柱状图表示了三路关联表(见图36)。
图33 R代码
图34 三路–风险(Risk)/可靠性(Reliability)/类型(type)点阵图(R)
图35 Python代码
图36 三路–风险(Risk)/可靠性(Reliability)/类型(type)柱状图(Python)
相较于文字,图形更有说服力。这个结果包含了Scanning Hosts中的234000个数据点(大约90%的项被分类为“Scanning Hosts”)。这个类别很大,并且它的低风险掩盖了其他类别的风险。将其从Type因子中移除并重新生成图像。这并不是说Scanning Hosts类不重要,而是通过这种方法找出您真正关心的项。您并不关心低风险和可靠评级的节点。所以应该剥离它们然后观察掩盖在Scanning Hosts下的数据关系。我们继续程序图33和图35中的例子,在图37和图39中生成新的结果图,参见图38(R的点阵图)和图40(Python的柱状图)。
图37 R代码
图38 不包括Scanning Hosts的三路点阵图:风险(Risk)/可靠性(Reliability)/类型(type)点阵图(R)
图39 Python代码
图40 不包括Scanning Hosts的三路柱状图:风险(Risk)/可靠性(Reliability)/类型(type)(Python)
现在您就要得到一些结果。在图38中,您会发现Malware domain类的风险评级在2到3之间,可靠性集以2为中心向外蔓延。您也可以观察其他类型的图形结果,包括图40,但是现在您需要重新生成移除了Malware domain后的图形。另外,看起来Malware distribution没有产生任何风险,您可以从剩余的类中过滤掉它(图41和图43中)以观察最终结果图42(R的点阵图)和图44(Python柱状图)。
图41 R代码
图42 三路点阵图:风险(Risk)/可靠性(Reliability)/类型(type),最终结果(R)
图43 Python代码
图44 三路柱状图:风险(Risk)/可靠性(Reliability)/类型(type),最终结果(Python)
通过最后的筛选,您已经将原来的列表减少到不到6%,而且合理地找到了真正关心的节点。如果想一步降低范围,可以过滤掉Reliability与Risk的一些组合。或者,也可从已经被过滤掉的类别中选取一部分重新观察。
这里简单的解析与分割数据并没有展示出哪些变量是最重要的,只是帮您了解这些数据的关系和出现的频率。因为90%的数据是Scanning Hosts,也许您只想筛选出风险不大于2的主机。这个分析只是帮您定位能产生更高警报优先级的节点,您仍然可以将其他类型节点捕捉到低优先级或者信息日志中。
因为AlienVault每小时更新这个列表,您可以在将新的版本导入到安全工具之前创建一个脚本来进行过滤。然后,您可以保持节点过滤的百分比作为潜在调整规则所需的百分比。此外,您应该考虑在半频率(semi-frequent)下实现这种探索分析。这将帮助您确定是否需要重新考虑到底由什么构成特殊节点。
五、结语
本文介绍了Python和R中数据分析的核心架构与概念。并结合了基本统计知识、基础脚本/分析模式、入门可视化等技术帮助您提出和回答一个相关问题。另外,每个例子展示了Python(利用pandas)和R代码的区别以及输出结果。所展示的内容只是这个具体分析存在的一种情况。每种情况其实都不同,这要求您在需要的时候使用不同的工具和方法。
微信公众号:计算机与网络安全
ID:Computer-network
【推荐书籍】