16.5 示例:识别WebShell

完整演示代码请见本书GitHub上的16-5.py。

1.数据清洗与特征化

我们使用ADFA-LD数据集中关于WebShell的数据进行实验,ADFA-LD数据集详细介绍请阅读第3章相关内容。ADFA-LD本质上是通过HIDS记录系统在正常与被入侵情况下的系统调用情况。系统调用本身就具有时序性,如图16-13所示。

图16-13 ADFA-LD数据时序化示意图

逐行读取文件,并记录当前系统调用序号的最大值,系统调用序号使用整数记录:


def load_one_flle(filename):
    global max_sys_call
    x=[]
    with open(filename) as f:
        line=f.readline()
        line=line.strip('\n')
        line=line.split(' ')
        for v in line:
            if len(v) > 0:
                x.append(int(v))
                if int(v) > max_sys_call:
                    max_sys_call=int(v)
    return x

加载正常系统调用序列,并标记为正常:


def load_adfa_training_files(rootdir):
    x=[]
    y=[]
    list = os.listdir(rootdir)
    for i in range(0, len(list)):
        path = os.path.join(rootdir, list[i])
        if os.path.isfile(path):
            x.append(load_one_flle(path))
            y.append(0)
    return x,y

加载WebShell运行下系统调用序列,并标记为WebShell:


def load_adfa_webshell_files(rootdir):
    x=[]
    y=[]
    allfile=dirlist(rootdir,[])
    for file in allfile:
        if re.match(r"../data/ADFA-LD/Attack_Data_Master/Web_Shell_\d+/UAD-W*",file):
        x.append(load_one_flle(file))
        y.append(1)
    return x,y

将正常数据与异常数据混合,随机分配成训练数据集和测试数据集:


x1,y1=load_adfa_training_files("../data/ADFA-LD/Training_Data_Master/")
x2,y2=load_adfa_webshell_files("../data/ADFA-LD/Attack_Data_Master/")
x=x1+x2
y=y1+y2
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.4, random_state=0)

2.训练样本

构造RNN,使用LSTM算法:


net = tflearn.input_data([None, max_sequences_len])
net = tflearn.embedding(net, input_dim=max_sys_call+1, output_dim=128)
net = tflearn.lstm(net, 128, dropout=0.8)
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net, optimizer='adam', learning_rate=0.1,
                         loss='categorical_crossentropy')

实例化RNN,默认序列长度为100,不足时使用0补齐:


trainX = pad_sequences(trainX, maxlen=max_sequences_len, value=0.)
testX = pad_sequences(testX, maxlen=max_sequences_len, value=0.)
trainY = to_categorical(trainY, nb_classes=2)
testY = to_categorical(testY, nb_classes=2)
model = tflearn.DNN(net, tensorboard_verbose=3)
model.fit(trainX, trainY, validation_set=(testX, testY), show_metric=True,
         batch_size=32,run_id="maidou")

3.验证效果

使用测试数据集合验证效果,准确率约93%,效果图见图16-14。

图16-14 RNN检测ADFA-LD数据集中的WebShell效果图