一、课题内容和要求
1、 原理综述
域名生成算法(DomainGenerationAlgorithm,DGA)是一项古老但一直活跃的技术,是中心结构僵尸网络赖以生存的关键武器,该技术给网络安全人员造成了不小的麻烦。针对基于DGA的僵尸网络,研究人员需要快速掌握域名生成算法和输入,对生成的域名及时进行处置。DGA依赖时间、字典和硬编码的常量动态生成域名[1]。算法如下演示:
1. def rand(r, seed):
2. return (seed - 1043968403*r) & 0x7FFFFFFF
3.
4. def dga(date, seed):
5. charset = string.ascii_lowercase + string.digits
6. tlds = [".net", ".org", ".top"]
7. unix = int(time.mktime(date.timetuple()))
8. b = 7*24*3600 c = 4*24*3600
9. r = ((unix//b)*b + c)
10. for i in range(200):
11. domain = ""
12. for _ in range(12):
13. r = rand(r, seed)
14. domain += charset[r % len(charset)]
15. r = rand(r, seed)
16. tld = tlds[r % 3]
2、对决策树算法的介绍
决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。在机器学习中,决策树是一个预测模型,他代表的是对象属性与对象值之间的一种映射关系。Entropy = 系统的凌乱程度,使用算法ID3, C4.5和C5.0生成树算法使用熵。这一度量是基于信息学理论中熵的概念。[2]
决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。
分类树(决策树)是一种十分常用的分类方法。它是一种监督学习,所谓监督学习就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,那么通过学习得到一个分类器,这个分类器能够对新出现的对象给出正确的分类。这样的机器学习就被称之为监督学习。
优点:
(1)决策树易于理解和实现,人们在在学习过程中不需要使用者了解很多的背景知识,这同时是它的能够直接体现数据的特点,只要通过解释后都有能力去理解决策树所表达的意义。
(2)对于决策树,数据的准备往往是简单或者是不必要的,而且能够同时处理数据型和常规型属性,在相对短的时间内能够对大型数据源做出可行且效果良好的结果。
(3)易于通过静态测试来对模型进行评测,可以测定模型可信度;如果给定一个观察的模型,那么根据所产生的决策树很容易推出相应的逻辑表达式。
缺点:
(1)对连续性的字段比较难预测。
(2)对有时间顺序的数据,需要很多预处理的工作。
(3)当类别太多时,错误可能就会增加的比较快。
(4)一般的算法分类的时候,只是根据一个字段来分类。
二、源程序代码
本程序数据文件以及基础的数据处理是基于【程序设计-在校整理-07 DGA域名识别(MLP初探)】进行的,可以理解为再上一篇博客的基础上,运用了决策树进行试验的小示例。
// 代码很烂,轻喷。注:仅供参考学习使用。
# --coding = 'utf-8'--
import warnings
import pandas as pd
import sklearn.tree as st
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
# 数据文件路径
dga_file = "../data/dga/dga.txt"
alexa_file = "../data/dga/top-1m.csv"
# 读入alexa(top-1m.csv)文件中的域名数据
def read_alexa():
x = []
data = pd.read_csv(alexa_file, sep=",", header=None)
x = [i[1] for i in data.values]
return x
# 读入dga.txt文件中的域名数据
def read_dga():
x = []
data = pd.read_csv(dga_file, sep="\t", header=None,
skiprows=18)
x = [i[1] for i in data.values]
return x
# 构造N-Gram模型特征
def ngram_feature(start, end):
alexa = read_alexa()
dga = read_dga()
x = alexa + dga
max_features = 10000
y = [0] * len(alexa) + [1] * len(dga)
CV = CountVectorizer(
ngram_range=(start, end),
token_pattern=r'\w',
decode_error='ignore',
strip_accents='ascii',
max_features=max_features,
stop_words='english',
)
x = CV.fit_transform(x)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.4)
return x_train.toarray(), x_test.toarray(), y_train, y_test
# 决策树模型建立
def do_tree(x_train, x_test, y_train, y_test):
tree = st.DecisionTreeClassifier(
criterion="entropy",
splitter="best",
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features=None,
random_state=1,
max_leaf_nodes=10000,
min_impurity_decrease=0.,
min_impurity_split=None,
class_weight=None,
)
tree.fit(x_train, y_train)
y_pred = tree.predict(x_test)
print(metrics.classification_report(y_test, y_pred))
print('precision_score:%.4f' % (metrics.precision_score(y_test, y_pred)))
print('recall_score:%.4f' % (metrics.recall_score(y_test, y_pred)))
print('f1_score:%.4f\n' % (metrics.f1_score(y_test, y_pred)))
if __name__ == '__main__':
warnings.filterwarnings('ignore') # 去除一些不必要的warning
x_train, x_test, y_train, y_test = ngram_feature(2, 2)
do_tree(x_train, x_test, y_train, y_test)
三、测试总结
在本次试验的过程中,我充分了解了,说明是DGA域名,及其危害,了解了DGA域名生成算法在实际中的产生情况。在基于决策树的分类试验过程中,我充分体验到,自己动手找数据,处理数据的快乐与满足感,本次试验使得我深入学习了机器学习的算法——决策树分类。对于本次试验的最终结果也使得我很满意,但是N-Gram模型在DGA域名下存在一定的欺骗性,因为DGA域名常常会有大量重复字符,这会使得决策树结点上有大量重复数据的叶子,对DGA域名进行多样化的特征提取将会是本实验的优化方向之一。
程序运行的部分就不贴图啦。有兴趣的话,大家自己运行一下吧~
四、其他
以上以及博客中含有在校整理字样的博客内容,均是本人本科在校学习期间所写的代码,源文件以及数据文件等在个人主页资源区可以获取。本人水平很低,大佬轻喷。整理出来是为了帮助初学者学习的过程中,在有需要的情况下能够有所参考。再次声明:仅供学习交流使用。大家有什么问题,欢迎留言~