学习笔记(十):使用支持向量机区分僵尸网络DGA家族

1.数据搜集和数据清洗

      ·1000个cryptolocker域名

      ·1000个post-tovar-goz域名

      ·alexa前1000域名

       从DGA文件中提取域名数据:

def load_dga(filename):
    domain_list = []
    with open(filename) as f:
        for line in f:
            domain = line.split(",")[0]
            if domain >= MIN_LEN:
                domain_list.append(domain)
    return domain_list

     alexa文件使用CSV格式保存域名的排名以及域名,提取方式:

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

2.特征化

     1)元音字母个数

           正常人在取域名的时候,通常会偏向取”好读“的几个字母组合,这使英文的元音字母比例会比较高。DGA生成域名的时候是随机的,所以元音字母这方面的特征不明显,我们可以通过这个差异来验证我们的想法。

        读取alexa域名数据:

x1_domain_list =  load_alexa("...")

       计算元音字母的比例:

扫描二维码关注公众号,回复: 3615914 查看本文章
def get_aeiou(domain_list):
    x=[]
    y=[]
    for domain in domain_list:
        x.append(len(domain))
        count = len(re.findall(r'[aeiou]',domain.lower()))
        count = (0.0+count)/len(domain)
    return x,y

        分别获取两个僵尸网络DGA域名以及alexa域名数据,并计算元音字母比例:

x1_domain_list = load_alexa("...")
x_1,y_1 = get_aeiou(x1_domain_list)
x2_domain_list = load_dga("...")
x_2,y_2 = get_aeiou(x2_domain_list)
x3_domain_list = load_dga("...")
x_3,y_3 = get_aeiou(x3_domain_list)

         以域名长度为横轴,元音字母比例为纵轴作图:

fig,ax=plt.subplots()
ax.set_xlabel('Domain Lengh')
ax.set_ylabel('AEIOU Score')
ax.scatter(x_3,y_3,color='b',label="dga_post-tovar-goz",marker = 'o')
ax.scatter(x_2,y_2,color='g',label="dga_cryptolock",marker = 'v')
ax.scatter(x_1,y_1,color='r',label="alexa",marker = '*')
ax.legend(loc='best')
plt.show()

    2)去重后字母数字个数与域名长度的比例

        

def get_uniq_char_num(domain_list):
    x=[]
    y=[]
    for domain in domain_list:
        x.append(len(domain))
        count = len(set(domain))
        count = (0.0+count)/len(domain)
        y.append(count)
    return x,y

x1_domain_list = load_alexa("...")
x_1,y_1 = get_uniq_char_num(x1_domain_list)
x2_domain_list = load_dga("...")
x_2,y_2 = get_uniq_char_num(x2_domain_list)
x3_domain_list = load_dga("...")
x_3,y_3 = get_uniq_char_num(x3_domain_list)

    3)平均jarccard系数:定义为两个集合交集与并集元素个数的比值,本次基于2-gram计算。

def count2string_jarccard_index(a,b):
    x=set(' '+a[0])
    y=set(' '+b[0])
    for i in range(0,len(a)-1):
        x.add(a[i]+a[i+1]0
    x.add(a[len(a)-1]+' ')
    for i in range(0,len(b)-1):
        y.add(b[i]+b[i+1]0
    y.add(b[len(b)-1]+' ')
    return (0.0+len(x-y))/len(x|y)

def get_jarccard_index(a_list,b_list):
    x=[]
    y=[]
    for a in a_list:
        j = 0.0
        for b in b_list:
            j+=count2string_jarccard_index(a,b)
        x.append(len(a))
        y.append(j/len(b_list))
    return x,y
    

      4)HMM系数

            正常人取域名的时候都会偏向选取常见的几个单词组合,抽象成数学可以理解的语言,因此以常见单词训练HMM模型,正常域名的HMM系数偏高,僵尸网络DGA域名由于是随机生成的,所以HMM系数偏低。

3.模型验证:SVM分类原理同上篇。

猜你喜欢

转载自blog.csdn.net/weixin_39878297/article/details/83065795