16.7 示例:识别异常操作

Gitlab的一位系统管理员在给线上数据库做负载均衡工作时,遭受了DDoS攻击。在阻止了攻击之后,运维人员发现了数据库不同步的问题,便开始修复。在修复过程中,错误地在生产环境上执行了数据库目录删除命令(见图16-16),导致300GB数据被删除,Gitlab被迫下线。在恢复的过程中,他们发现只有db1.staging的数据库可以用于恢复,而其他5种备份机制都不可用。db1.staging是6小时前的数据,而且传输速率有限,导致恢复进程缓慢,Gitlab最终丢掉了差不多6个小时的数据。

图16-16 Gitlab被管理员误删除

黑客入侵Web服务器以后,通常会通过系统漏洞进一步提权,获得root权限,内部员工的违规操作同样也可能造成巨大危害。我们试图通过搜集Linux服务器的bash操作日志,通过训练识别出特定用户的操作习惯,然后进一步识别出异常操作行为。完整演示代码请见本书GitHub上的16-7.py。

1.数据清洗与特征化

我们使用SEA数据集涵盖70多个UNIX系统用户的行为日志,这些数据来自UNIX系统acct机制记录的用户使用的命令。SEA数据集中每个用户都采集了15000条命令,从用户集合中随机抽取50个用户作为正常用户,剩余用户的命令块中随机插入模拟命令作为内部伪装者攻击数据。关于SEA数据集的详细介绍请参考第3章中的内容。

逐行读取并加载命令:


def load_user_cmd_new(filename):
    cmd_list=[]
    dist=[]
    with open(filename) as f:
        i=0
        x=[]
        for line in f:
            line=line.strip('\n')
            x.append(line)
            dist.append(line)
            i+=1

每100个命令组成一个向量:


if i == 100:
        cmd_list.append(x)
          x=[]
          i=0

把每个命令当成一个单词,使用词集模型进行处理:


fdist = FreqDist(dist).keys()

使用生成词集的词汇表对操作命令进行编码,将操作命令序列化:


def get_user_cmd_feature_new(user_cmd_list,dist):
    user_cmd_feature=[]
    for cmd_list in user_cmd_list:
        x=[]
        for cmd in  cmd_list:
            v = [0] * len(dist)
            for i in range(0, len(dist)):
                if cmd == dist[i]:
                    v[i] = 1
            x.append(v)
        user_cmd_feature.append(x)
    return user_cmd_feature

2.训练样本

RNN识别异常的流程如图16-17所示。

以User3为例,文件中一共记录了15000个命令共150个命令序列,每个命令序列长度固定,均为100。前80个命令块(序列)作为训练集,后70个命令块为测试集合:


user_cmd_list,dist=load_user_cmd_new("../data/MasqueradeDat/User7")
n_words=len(dist)
user_cmd_feature=get_user_cmd_feature_new(user_cmd_list,dist)
labels=get_label("../data/MasqueradeDat/label.txt",6)
y=[0]*50+labels
x_train=user_cmd_feature[0:N]
y_train=y[0:N]
x_test=user_cmd_feature[N:150]
y_test=y[N:150]

图16-17 RNN识别异常操作流程图

定义RNN结构,其具有两层lstm结构:


net = tflearn.input_data(shape=[None, 100,n_words])
net = tflearn.lstm(net, 10,  return_seq=True)
net = tflearn.lstm(net, 10, )
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net, optimizer='adam', learning_rate=0.1,name="output",
                         loss='categorical_crossentropy')
model = tflearn.DNN(net, tensorboard_verbose=3)

3.验证效果

训练并交叉验证测试集合:


model.fit(x_train, y_train, validation_set=(x_test, y_test), show_metric=True,
         batch_size=32,run_id="maidou")

其中训练集合大小为80,测试集合大小为70,准确率在94%以上,如图16-18所示。

图16-18 RNN识别异常操作结果