7.4 示例:检测WebShell(一)

我们基于WebShell的文本特征进行WebShell的检测。我们将互联网上搜集到的WebShell作为黑样本,当前最新的wordpress源码作为白样本。将一个PHP文件作为一个字符串处理,以基于单词的2-gram切割,遍历全部文件形成基于2-gram的词汇表,如图7-3所示。然后,进一步将每个PHP文件向量化。完整演示代码请见本书GitHub上的7-2.py。

图7-3 基于2-gram获取词汇表

1.数据搜集和数据清洗

定义函数,用于将PHP文件转换成一个字符串:


def load_file(file_path):
    t=""
    with open(file_path) as f:
        for line in f:
            line=line.strip('\n')
            t+=line
    return t

遍历样本集合,将全部PHP文件以字符串的形式加载:


def load_files(path):
    files_list=[]
    for r, d, files in os.walk(path):
        for file in files:
            if file.endswith('.php'):
                file_path=path+file
                print "Load %s" % file_path
                t=load_file(file_path)
                files_list.append(t)
    return  files_list

针对黑样本集合,以2-gram算法生成全局的词汇表,其中2-gram基于单词切割,所以设置token的切割方法为:r'\b\w+\b'。


webshell_bigram_vectorizer = CountVectorizer(ngram_range=(2, 2), decode_error="ignore",token_pattern = r'\b\w+\b',min_df=1)
webshell_files_list=load_files("../data/PHP-webSHELL/xiaoma/")
x1=webshell_bigram_vectorizer.fit_transform(webshell_files_list).toarray()
vocabulary=webshell_bigram_vectorizer.vocabulary_

其中,需要特别说明以下3个参数。

·ngram_range:设置成(2,2),表明基于2-gram;

·decode_error:设置成ignore,表明忽略异常字符的影响;

·token_pattern:设置成r'\b\w+\b',表明按照单词切割。

2.特征化

使用黑样本生成的词汇表vocabulary,将白样本特征化,其中非常重要的是设置CountVectorizer函数的vocabulary,这样才能以黑样本生成的词汇表来进行向量化:


wp_bigram_vectorizer = CountVectorizer(ngram_range=(2, 2), decode_error="ignore",
token_pattern = r'\b\w+\b',min_df=1,vocabulary=vocabulary)
wp_files_list=load_files("../data/wordpress/")
x2=wp_bigram_vectorizer.fit_transform(wp_files_list).toarray()
y2=[0]*len(x2)
x=np.concatenate((x1,x2))
y=np.concatenate((y1, y2))

3.训练样本

创建NB实例:


clf = GaussianNB()

4.效果验证

我们使用三折交叉验证,所谓k折交叉验证,就是将数据集a分为训练集b和测试集c,在样本量不充足的情况下,为了充分利用数据集对算法效果进行测试,将数据集a随机分为k个包,每次将其中一个包作为测试集,剩下k-1个包作为训练集进行训练:


print  cross_validation.cross_val_score(clf, x, y, n_jobs=-1,cv=3)

测试结果如下,准确率80%左右,还有提升空间。


[ 0.73584906  0.86538462  0.75      ]