完整演示代码请见本书GitHub上的12-4.py。
1.参数建模
DGA通常是基于当前时间、硬编码的常量以及字典,根据一定的算法生成,如图12-11所示。
图12-11 DGA原理图
以僵尸网络cryptolocker的DGA算法为例,生成的DGA与时间关系如下:
wwkahhnyqvxdfq.com,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt kpudegrfqeuadh.net,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt xraxhxvadmpgdn.biz,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt ldjhqijygqrudp.ru,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt yfoctantsymbmt.org,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt mxyfqyrashjxdv.co.uk,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt aaeatqvufpeedj.info,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt rnpwcfjkeiybhu.com,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13,http://osint.bambenekconsulting.com/manual/cl.txt
2.数据处理与特征提取
域名特征提取流程如图12-12所示。
图12-12 域名特征提取
Alexa是一家专门发布网站世界排名的网站。以搜索引擎起家的Alexa创建于1996年4月(美国)。Alexa每天在网上搜集超过1000 GB的信息,不仅给出多达几十亿的网址链接,而且为其中的每一个网站进行排名。可以说,Alexa是当前拥有URL数量最庞大、排名信息发布最详尽的网站。我们使用Alexa全球排名前100万的网站的域名训练HMM模型。
加载域名数据代码如下:
def load_alexa(filename): domain_list=[] csv_reader = csv.reader(open(filename)) for row in csv_reader: domain=row[1] if domain >= MIN_LEN: domain_list.append(domain) return domain_list
数据格式如图12-13所示。
图12-13 Alexa排名数据
搜集常见僵尸网络的DGA数据,具体数据请见本书对应的GitHub链接。
加载DGA数据代码如下:
def load_dga(filename): domain_list=[] #xsxqeadsbgvpdke.co.uk,Domain used by Cryptolocker - Flashback DGA for 13 Apr 2017,2017-04-13, # http://osint.bambenekconsulting.com/manual/cl.txt with open(filename) as f: for line in f: domain=line.split(",")[0] if domain >= MIN_LEN: domain_list.append(domain) return domain_list
特征化逻辑非常简单,直接转化成对应的ASCII即可:
def domain2ver(domain): ver=[] for i in range(0,len(domain)): ver.append([ord(domain[i])]) return ver
3.训练模型
使用默认参数的HMM训练Alexa域名即可:
def train_hmm(domain_list): X = [[0]] X_lens = [1] for domain in domain_list: ver=domain2ver(domain) np_ver = np.array(ver) X=np.concatenate([X,np_ver]) X_lens.append(len(np_ver)) remodel = hmm.GaussianHMM(n_components=N, covariance_type="full", n_iter=100) remodel.fit(X,X_lens) joblib.dump(remodel, FILE_MODEL) return remodel
4.验证模型
使用搜集的两个不同家族的僵尸网络来验证模型,这两个家族分别是cryptolocker和post-tovar-goz:
if __name__ == '__main__': domain_list = load_alexa("../data/top-1000.csv") remodel=joblib.load(FILE_MODEL) x_3,y_3=test_dga(remodel, "../data/dga-post-tovar-goz-1000.txt") x_2,y_2=test_dga(remodel,"../data/dga-cryptolocke-1000.txt") fig,ax=plt.subplots() ax.set_xlabel('Domain Length') ax.set_ylabel('HMM Score') ax.scatter(x_3,y_3,color='b',label="dga_post-tovar-goz") ax.scatter(x_2, y_2, color='g', label="dga_cryptolocker") ax.legend(loc='right') plt.show()
为了方便对比两个家族的聚类效果,我们以域名长度为横轴,HMM值为纵轴作图,结果如图12-14所示。
图12-14 不同僵尸家族聚类效果
可见HMM作为DGA僵尸网络区分的一个变量,非常具有区分性,进一步的区分还需要增加变量,使用SVM等算法作为区分。