12.5 示例:使用隐式马尔可夫算法识别DGA域名

完整演示代码请见本书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等算法作为区分。