第二届阿里云安全算法挑战赛经验分享

第二届阿里云安全算法挑战赛经验分享

一、简介

我在2017年8月参加了这个比赛,比赛分两道子赛题,我和队友分别负责其中一道,我负责的是《扫描爆破拦截》,单题排名5/959,两题综合12/959。原本应该在比赛完就写博客记录的,但事情太多以至于拖延到了现在,找实习的时候翻回从前比赛时期零碎的笔记,才想起来自己原来做过这么些事情,经历过这样的一些思考,还发现了一些纰漏和可以改进的地方。现在重写一份经验分享,旨在记录过去,督促自己寻求创新。


二、赛题

2.1 赛题简介

详细的赛题可以看这里。显然,《扫描爆破拦截》的背景是用户通过不同的端口向阿里云主机发送连接请求,请求之中存在着部分恶意用户,他们的目的不是简单地连接主机,而是要通过端口进行扫描,利用密码本暴力爆破登录主机。赛题提供了一段时间内(一个月)的连接记录恶意用户名单,要求我们预测接下来一段时间(一周)的恶意用户。

2.2 赛题数据

2.2.1 提供特征

样本量估计在2000w左右(线上赛没有留下记录,大致记得是这样的数量级)。

用户连接记录
序号特征名含义
1client_ip云主机IP,AB段已hash,CD段保留
2client_port云主机端口
3source_ip访客IP,AB段已hash,CD段保留
4hashuserid云主机拥有者ID,已hash
5hh连接请求的发起时间:小时
6mi连接请求的发起连接时间:分钟
7ss连接请求的发起连接时间:秒,精确到10秒
8counts10秒内连接次数
9ds日期
用户登录记录
序号特征名含义
1client_ip云主机IP,AB段已hash,CD段保留
2client_port云主机端口
3source_ip成功登录者IP,AB段已hash,CD段保留
4hh登录时间:小时
5ds登录日期
攻击者名单
序号特征名含义
1client_port恶意访问云主机端口
2source_ip恶意访问者IP,AB段已hash,CD段保留
3ds恶意访问日期
2.2.2 评估方式

比赛以F值的形式评估,针对日期 i i 端口 j,设置F值

Sij=4PRP+3R×100% S i j = 4 P R P + 3 R × 100 %

最后以整体平均的方式作为综合评分 Score=avg(Sij) S c o r e = a v g ( S i j )

2.2.3 关于赛题数据的思考
  1. 非实时系统
    标签 Label 的格式是 source_ip : client_port : ds (下称 id ),因此在实际应用中,需要在这一天结束时统计完整的连接记录才能进行判断,不具有实时性,这一点与基于数据包解析的恶意攻击检测有本质的区别。
  2. 攻击者判定
    标签 Label 的格式决定,只要 source_ipds 这一天的任意时刻对 client_port 进行过一次攻击行为,他在当天对该端口的所有访问行为都会被判定为恶意攻击。因此,可以预计有部分 id, 即使在某一天的大部分连接行为都与正常访问者无异,只需一次爆破行为,即足以判定为攻击者,可以根据这一点挖掘潜在攻击者。
  3. 样本采样的灵活性
    虽然恶意攻击的判定单位为“天”,但 instance 是精确到10秒的,因此参与训练的 instance 不一定以“天”为单位,若以“小时”或“十秒”为单位进行采样,则可扩展样本数量。
  4. 测试集Label的复数性
    每一个 id 都应有多个 Label 相同的样本,而模型对测试集的预测却不一定,可以预计大多会出现同一个 id 下的 Label 各异的情况,届时可制定规则来判定该 idLabel,比如voting或者规则等。
  5. 业务理解的重要性
    最后,这道题的关键在于理解业务。多问自己一些问题,代入攻击者的角色,如果自己是黑客,怎样攻击能够达到目的,从而能够发现不同于正常访问的访问行为,提取相应的特征。

三、特征工程

在提供的三周的连接记录中,我线下选择用前两周训练,最后一周线下验证,线上则用全集三周进行训练。概括地来说,我提取的特征包括以 dshh 两种不同粒度的基本特征和组合特征,以及一项构造的特征。

然后,仔细回想了一下,我这种特征提取方式,提取的总是“当天”的统计信息,而没有像以往的比赛一样,将之前的某段时间作为特征提取区间,这有可能是一个缺漏,也可能是一个trick。说是缺漏的原因在于,我没有用到完整的历史特征,这其中可能包含了对决策有利的信息。说是trick的原因在于,题目Label的特性反映出它更关心当天内(不同时段)用户的行为。不论如何,这个想法已经无法验证了,非常可惜。

基本构成

以特定 id (例如sip:port:ds:hh)关于不同时间粒度的针对连接的统计特征。

  • 记录总数
  • 连接总次数
  • 最大连接次数、平均连接密度(除以记录数、除以hh或mi个数)
  • 主机网段种类(IP取AB段)
  • 最大、平均网段个数(除以记录数、除以hh或mi)
  • 云主机拥有者个数
  • 最大、平均云主机拥有者个数(除以记录数、除以hh或mi种数)

这里解释一下,在平均值的计算中,有“除以hh个数”这一项,这是由于用户并不是在每个小时都有记录,应该在有记录的时间内取平均,例如当天只有12、13、14时内有记录,则应该除以3。

特定 Id 构成

根据 id 的物理意义,实际上可进一步细分为用户特征、端口特征、用户端口特征、网段特征、用户网段特征等。这里为了方便描述,分为“直接”与“cip_ab相关”,后者并不是直接统计的,经过了一次预处理。

直接

  • sip : port : ds : hh
  • sip : port : ds
  • sip : ds : hh
  • port : ds : hh
  • port : ds

cip_ab 相关

  • sip : port : ds : hh : cip_ab sip : port : ds : hh
  • sip : port : ds : cip_ab sip : port : ds
  • port : ds : hh : cip_ab port : ds : hh
  • port : ds : cip_ab port : ds

这么看可能不容易看懂。

以“直接”中 sip : port : ds : hh 为例,具体做法是将训练集以 sip : port : ds : hh 进行 groupby,然后提取基本构成中的各项指标,旨在提取具有类似于“用户在ds通过port尝试访问的云主机个数”这等层次意义的特征。

以“cip_ab 相关”中第一项为例,先将训练集按 sip : port : ds : hh : cip_ab 进行 groupby,然后提取基本构成中的各项指标,旨在提取具有类似于“sip在ds-hh通过port访问特定网段cip_ab的最大记录数”这样的特征。然后,按 sip : port : ds : hh 进行groupby,对不同网段的统计量进行聚合,再次使统计量的关注点回归到sip : port : ds : hh上来。这样的特征描述了类似“sip在ds-hh通过port平均访问多少个网段”的特征。

构造特征

经过观察,发现我提取的特征里,攻击者的某些特征取值明显比普通用户高得多,为了扩大这个效果,构造了一个特征mul。这个特征最终使得线上成绩从0.73飙升到0.77,排名上升到排行榜第5。

mul=×××IP m u l = 连 接 总 次 数 记 录 数 × 云 主 机 种 数 × 主 机 拥 有 者 个 数 × 云 主 机 I P 网 段 个 数

关于聚合时间粒度

解释一下为什么增加了 hh h h 粒度效果会变好。下表为按时间聚合的 sip : port : ds : hh 连接量,其中A只有3个小时有记录,而B有20个小时有记录。

source_ipportdshhcounts_hh
A22201707011040
A222017070111900
A22201707011260
B2220170701050
B22201707011950

下表为按天聚合的 sip : port : ds 连接量

source_ipportdscounts_ds
A22201707011000
B22201707011000

可见按照 ds d s 粒度进行groupby时,A和B的统计量是一样的,是否就应该将他们视作同一label呢?答案是否定的,看按照 hh h h 粒度进行groupby时,A在11时明显在突发地大量发送连接请求,很有可能就是在扫描爆破。按照 ds d s 粒度分辨不出来的用户行为,按照 hh h h 粒度就能分辨出来。


四、模型与规则

最佳提交结果 = 双粒度特征 + 构造强特征 + 模型融合 + 前科者规则

4.1 模型选择

由于本次比赛完全是平台赛,因此只能使用PAI平台提供的工具。我选择了gbdt、rf和PS-SMART,它们都支持二分类任务。根据比赛中的测试,三个模型对于相同的特征,效果是差不多的。

4.2 模型融合

比赛中我尝试了两种模型融合。

  1. 两个gbdt,一个采用day粒度特征,另一个采用hour粒度特征,预测结果(概率)简单平均。效果在0.77的基础上有略微提升。

  2. 两个PS-SMART+一个RF,为PS-SMART、gbdt和RF各自训练三个模型,分别基于三个不同的特征子集:全特征、ds粒度特征和hh粒度特征,总共9个模型,分别进行模型调参,根据线下准确率,选出分数最高的三个模型:RF_day, PSSMART_all, PSSMART_day,然后将它们融合,融合权值是通过人肉网格搜索决定的。

这里写图片描述

4.3 前科者规则

对于测试集中的 sip-port ,若在训练集中曾经被标记为攻击者,无论模型对测试样本的预测结果如何,都将被标记是攻击者。事实上这个规则也可以转化为特征:之前被标记为攻击者的次数。


五、最重要的点

总结一下为什么能获得这么高的名次。

  1. 特征工程方面
    第一,将特征扩充为以小时为单位。原因在于赛题对攻击者的标记是以天为单位的,也就是说也许访问者当天只在某一短时间进行了扫描。若以小时为单位,模型就能学习去判断访问者在当天的哪些时段进行了攻击,最后利用voting综合决策,从而提升准确率。第二,是构造的强特征,赛题提供的信息我并未完全利用, 我当时并没有用到赛题提供的访问者登录成功的信息,我私底下问过一个F1值跟我差不多的队伍,他们表示单模型下提取了登录特征也顶多跟我差不多,可见这个强特征有多重要。

  2. 赛题的理解和对数据的观察方面
    出于对赛题的理解我改变了时间聚合粒度,并提出了规则,由于观察过数据,我构造出了强特征。更多地去观察数据,即使不能从中发现新的特征,也能增进对整个赛题的理解。

  3. 思路方面
    本次比赛中,我的时常将自己往攻击者靠拢,尝试从他们的角度分析,如果我是攻击者我会怎么做?怎样才能尽可能破解到更多的主机?我会对哪些主机更感兴趣?拥有者多的还是属于特定网段的?此外,我感觉我在比赛中的思路特别清晰,这部分特征提取的意义何在,特征要怎么拼接起来,要怎么给模型训练,模型要怎么融合起来,这些思路在观察数据的时候基本就有成型了。

  4. 代码方面
    写SQL的时候一定要给出明白的注释,有时候超长一段只是为了提取零星的几个特征而已,不加注释的话以后就不知道自己写了什么了。另外,对于SQL不能写循环的特性,可以利用Python进行文本替换生成代码。


六、不足之处

这次比赛我参加得不算早,好像是在中途参加的。在这之前我甚至还不会写SQL,基本上是边学边做。比赛的那段时间刚好被老板要求写论文,因此用来作比赛的时间不多。虽然队伍有两个人(简直不敢相信),分别负责一道题,虽然有所交流,但能获取的只有idea,实现基本还是自己完成的。我认为我的不足之处在于:

  1. 完全没有用到用户登录流水信息。不是我故意不用,是我一开始没想到要怎么利用,到最后直接给忘了。但是,我光使用连接信息就达到了接近顶尖的水平,如果用上login应该能更上一层。

  2. 没有做数据采样,实际上数据存在样本标签不均衡的问题。具体地,应该对负样本按照时间采样,例如将每小时分成四份,则可以做到25%的采样,进一步划分奇偶小时,可做到12.5%采样。

  3. 没有考虑到不同端口的恶意样本比例不同对模型带来的影响,对于恶意用户比例高的端口,其阈值应该调高以减少误判。

  4. 没有尝试其他模型。pssmart其实可以输出叶子节点,可以在这基础上做stacking。

  5. 没有进一步研究更多的trick。用ODPS SQL观察数据还是比不上画图直观,感觉数据中应该还有某些规律我没有抓到。

  6. 创新不足,感觉这类比赛的套路基本能摸清了,以后比赛应该多尝试新东西的。


七、收获

  1. 业务理解和思考产生提升

    • 基础特征的构造是基于站在攻击者的角度思考产生的。
    • 改变样本划分粒度的做法是基于对赛题和数据特点的思考产生的。
  2. 数据观察增进理解

    • 强特征mul的提出是基于数据观察得到的。
    • 在训练完树模型后,根据线下预测状况,发现模型基本上能将全部正例预测为正,但会把相当一部分反例预测为正,换言之,模型过于严格。由于时间关系我没有深入研究,如果还有时间,我应该会设置某些trick或专门提取某些特别能反映反例特色的特征,“纠正”哪些伪正例。
  3. 千万不要随便丢弃效果差的特征
    单独使用day粒度的效果比不上单独使用hour粒度特征的效果,但两者放在一起,能达到更好的效果,最佳提交结果正是如此。在好特征中混入看似不好的特征,甚至有可能构造出特性相差较大的特征子集,从而训练出“好而不同”的基学习器,用来做融合再好不过了。


八、面试中曾经被问到过的问题

  1. RF和GBDT各自的原理和区别?
    RF是bagging,基函数使用不同的样本子集,各自训练时也有feature fraction,从候选特征中选择最佳特征和分裂点,最终平均或voting组合。GBDT是boosting,它由多棵CART树串行叠加,每一轮拟合前一轮模型与真实值的残差,梯度提升版本用梯度代替残差。

  2. 你有什么创新点?
    主要都是特征工程方面的,构造了强特征,提出了规则。

  3. 你怎么做融合的?为什么要这样融合?
    简单加权。因为这是最常用的做法,实际上还有stacking,但由于时间问题没有尝试。

  4. 你的组合特征和基本特征有什么区别?为什么要特地这样提取?
    特征之间的本质区别在于group by的id不一样,表征的物理意义不一样,反映某种特性的层次也不一样。这样提取是因为树模型不能直接学习到这样的交叉特征。

  5. 你的构造特征有什么依据?你觉得为什么他管用?
    依据是对攻击者和普通用户的特征值的观察,攻击者的特征值普遍偏高,不仅最大值高,均值也高。我认为之所以管用,是因为它反映了攻击者在短时间内希望尽可能遍历更多的主机、用户的特性。

  6. 如你所言,原始特征里基本都是ID类,你怎么能直接扔进树模型?
    我并没有把ID类特征直接扔进树模型,事实上我是针对不同的ID提取了统计特征,然后用统计特征代替ID本身。树模型一般不能接受ID类输入的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值