建立白名单
我们采取两个步骤为每一个用户建立一个白名单。首先,主机在训练期间观察其通讯,建立一组原子并且跟踪其持续性。这个训练的时间长度取决于通讯方式的稳定程度。我们希望训练时间长度由网络运营商确定。我们确定p是持续性的门限值:也就是说,如果一个特定的原子的持续性大于p,那么,这个原子就添加到白名单。在检测阶段,每一个端点主机把自己观察到的原子(全部的原子,而不仅仅是持续性的原子)发送到这个企业的中央IT运营中心或者发送到类似机构的下属机构。在IT运营中心,将计算在这个逻辑和其中的每一个原子的共同性。我们定义共同性c的一个门限值,并且收集共同性超过c的那些原子。这些原子发送到每一个端点主机。端点主机把这些原子添加到这个白名单。因此,每一个主机的白名单都有两个组件:一个单个的组件捕捉对于那个系统来说是独特的行为。另一个通用组件是群体中常见的行为。这个通用组件包含的某些原子可以不是单个主机正常行为的一部分。
检测算法
在一个高级水平上,我们的系统可以对两种类型的事件发出警报。这两类事件是:(1)p-报警,当没有列入主机白名单的一个目标原子变得具有持续性的时候发出的报警;(2)c-报警,当在同一个窗口的大量端点主机中观察到一个目标原子并且识别出这个目标原子是普通的原子时发出的报警。注意,p-报警通常是本地发出的;用户收到报警并且要求告知收到这个报警。相比之下,如果完整的白名单发送给全部用户的话,c-报警可以在中央IT运营中心或者本地发出。需要指出的是,当与一个原子相关的报警变得非常重要时,将出现下面两种情况之中的一种情况:(1)这个原子被分类为良性的(按照用户或者运营商),在这种情况下,它必须添加到适当的白名单中;(2)这个报警指出恶意的行为,要求采取补救措施。我们在这篇文章中不讨论补救措施阶段的事情。我们仅指出一些可能性,如调解通讯流,通过一个设备重新定向通讯流、封锁通讯流等等。
processPacket(pkt, t, wi)
a <-- getDestAtom(pkt)
if a in WHITELIST then
return /* ignore atoms already in the whitelist */
end if
if a is a new connection initiation then
DCT[a][currIdx] = 1 /*update persistence */
sendReport(userID, a, t) /*report sent to central console*/
end if
在这一节的其余部分,我们简单地评估一下处理输出数据包(在表1中综合说明的)所需要的具体行动。当对应于一个原子的输出数据包已经在一个单个主机的白名单中的时候,不需要进一步采取什么行动。如果输出数据包没有对应一个已经存在于主机白名单中的原子,那么,应该采取如下步骤:
•如果这个原子是以前没有见过的,用于跟踪持续性(DCT)的数据结构中应该创建一个新的记录。这是通过一个原子做索引的并且指向一个位图。每一个位图对应一个特定的跟踪窗口。
•跟踪原子(标记为DCT)观察的这个数据结构将为当前的跟踪窗口进行更新。
•这个原子如果是新的,它将被发送到IT运营中心(也许通过一个最低持续性规定过滤之后再发送)。
需要指出的是,我们的系统没有绑定任何独特的通讯功能。为了方便,我们假设每分钟的连接次数是考虑的特点。要发出p报警,我们使用一个滑动窗口在所有的时间量程跟踪持续性。图2描述了这样做的数据结构。要维护一个字典(或者一个hash表),这个字典中有一个原子的索引,这个字典的记录显示与这个原子有关的位图。当在一个跟踪窗口wi看到这个原子的时候,这个ith二进制位设置为1,像图2描绘的那样。随着滑动窗口的移动,在最后一个跟踪窗口中观察到的每一个原子的持续性都要在这最后一个窗口的末端进行计算。为多个时间量程做这个事情似乎是很昂贵的。然而,一个有趣的观察是我们不需要在不同的时间量程复制这个架构。相反,我们需要利用这个时间量程重复的性质(W3 < W4),我们能够使用一个长的位图取消这个架构。这个位图有足够的字节覆盖最长的观察窗口。
图2 用于跟踪原子持续性的数据结构(来源:英特尔公司,2009)
如果在任何时候这个原子的持续值超过门限值p,就会发出这个原子的报警。在这个时候,用户将被要求验证这个原子是否合法,是否应该把这个原子添加到白名单。如果这个值甚至在充分跟踪之后还是不大,这个位图将被删除,这个原子将不再被跟踪(如果它再次出现,将安装一个新的位图)。
要理解这个过程的开销,我们注意到字典的长度不需要太大。如果一个输出数据包已经列入白名单(特别是它的原子在白名单中),那么,就不需要新的字典记录。对于其它东西来说,我们只需要每个原子有一个记录(尽管同一个原子有许多连接或者有许多与它有关的数据包)。拥有实际上要跟踪的原子,有关的计算就是做字典索引和更新位图所需要的时间。然而,我们在通讯流中发现我们跟踪的原子并不是经常出现(最明显的持续性原子已经在白名单中,因此不需要跟踪)。因此,这个位图中的大多数记录是空的。一个简单的优化方法是使用稀疏向量(sparse vectors)替代位图。在我们的分析中,我们发现在所有的用户遇到的最糟糕的情况中,所有的观察窗口Wmax有1435个需要跟踪的原子。平均的情况是有485个需要跟踪的原子。如果考虑到计算能力和与目前移动系统有关的内存,这个情况几乎是可以忽略的。
我们简单地讨论一下“c-报警是如何通过跟踪通用性产生的”来结束这个讨论。这是一种简单的操作。IT运营中心的中央控制台不断地跟踪不同的用户在最大的观察窗口看到的原子。当收到一个主机的报告的时候,相应的原子就会更新。同时,旧的信息将被删除(也就是说比观察窗口看到的还要老的原子将被删除)。当一个原子记录被更新的时候,相关的用户(最新看到过这个原子的用户)数量超过这个门限值c,于是发出c-报警。一台主机向中央控制台发送报告的频繁程度决定能够在多么短的时间里检测到异常情况。立即发送这个报告(在第一次发现这个原子就发出报告)有助于早一些捕捉到异常情况,但是,这要付出通讯成本。批量更新可减少通讯成本,但是,增加了检测的时间。
至此,我们介绍了目前几个有潜力的防御僵尸网络的策略,主要是收集真正的踪迹以检验常态状况。