QADARS V3恶意软件域名生成算法分析

2016-04-20 327248人围观 ,发现 3 个不明物体 网络安全

在今年三月份,下面的样本引起了我的兴趣——因为是通过DGA(域名生成算法)来和C&C服务器进行通信:

Clipboard Image.png

例如,在4月12号,生成的前10个域名如下:

nctqrgta7o52.net

khqzwlib0pun.org

lun0lmr4xe7k.com

qvc9inkxy3o9.com

z8daz8ti3wxy.net

k1ar8levktun.net

1ij05qzgta70.org

6bwdyvw5if45.com

jwde7stqb0da.org

05azc52rs1yb.org

这些是什么?

Virustotal扫面了malwr analysis上的样本,除了” Qihoo-360”其他杀软均显示样本正常。360的检测结果显示的是“HEUR/QVM07.1.0000.Malware.Gen”

恶意软件的特征码都是通过和10个字节的XOR密钥(FC 57 91 BC 75 9A 12 CC A4 26)加密的。可以在这里看到完整的文本字符串,如下:

klpszVersion

gBitness

kdwTimestamp dData fLength flpData@

hmainType.gsubType

这些字符串和银行木马Qadars很相似,可以在这篇安全报告中看出。

Qadars二进制文件包含一些硬编码的版本字符串。在我的例子中,版本字符串为3.0.0.0:

Clipboard Image.png

在Qadars2.0.0.0的安全智能报告中没有提及域名生成算法,而这个特征将在Qadars3.0.0.0版本中体现。

反汇编DGA

下面的列表是DGA算法的反汇编代码。这里我们直接先跳到下一节中,查看基本的DGA属性。

text:004095F0 ; BOOL __cdecl dga(void *pDomain, size_t sld_len)

.text:004095F0 dga             proc near               ; CODE XREF: sub_409FD0+20_x0019_p

.text:004095F0

.text:004095F0 charset         = byte ptr -38h

.text:004095F0 tlds            = dword ptr -10h

.text:004095F0 pDomain         = dword ptr  8

.text:004095F0 sld_len         = dword ptr  0Ch

.text:004095F0

.text:004095F0                 push    ebp

.text:004095F1                 mov     ebp, esp

.text:004095F3                 sub     esp, 38h

.text:004095F6                 push    ebx

.text:004095F7                 push    esi

.text:004095F8                 mov     [ebp+tlds], offset a_com ; ".com"

.text:004095FF                 mov     [ebp+tlds+4], offset a_org ; ".org"

.text:00409606                 mov     [ebp+tlds+8], offset a_net ; ".net"

.text:0040960D                 push    edi

.text:0040960E                 mov     edi, edi

.text:00409610

.text:00409610 loc_409610:                             ; CODE XREF: dga+166_x0019_j

.text:00409610                 mov     ebx, [ebp+pDomain]

.text:00409613                 mov     ecx, 9

.text:00409618                 mov     esi, offset charset ; "abcdefghijklmnopqrstuvwxyz0123456789"

.text:0040961D                 lea     edi, [ebp+charset]

.text:00409620                 rep movsd

.text:00409622                 movsb

.text:00409623                 test    ebx, ebx

.text:00409625                 jz      loc_409740

.text:0040962B                 mov     edi, [ebp+sld_len]

.text:0040962E                 cmp     edi, 5

.text:00409631                 jbe     loc_409740

.text:00409637                 cmp     domain_nr, 0

.text:0040963E                 jnz     short loc_40966D

.text:00409640                 push    0

.text:00409642                 call    ds:_time64

.text:00409648                 add     esp, 4

.text:0040964B                 push    0

.text:0040964D                 mov     esi, eax

.text:0040964F                 sub     eax, 345600

.text:00409654                 push    604800

.text:00409659                 sbb     edx, 0

.text:0040965C                 push    edx

.text:0040965D                 push    eax

.text:0040965E                 call    _allrem

.text:00409663                 sub     esi, eax

.text:00409665                 and     esi, 7FFFFFFFh

.text:0040966B                 jmp     short loc_409673

.text:0040966D ; ---------------------------------------------------------------------------

.text:0040966D

.text:0040966D loc_40966D:                             ; CODE XREF: dga+4Ej

.text:0040966D                 mov     esi, r

.text:00409673

.text:00409673 loc_409673:                             ; CODE XREF: dga+7Bj

.text:00409673                 push    edi             ; size_t

.text:00409674                 push    0               ; int

.text:00409676                 push    ebx             ; void *

.text:00409677                 call    memset

.text:0040967C                 lea     eax, [ebp+charset]

.text:0040967F                 add     esp, 0Ch

.text:00409682                 lea     edx, [eax+1]

.text:00409685

.text:00409685 loc_409685:                             ; CODE XREF: dga+9A_x0019_j

.text:00409685                 mov     cl, [eax]

.text:00409687                 inc     eax

.text:00409688                 test    cl, cl

.text:0040968A                 jnz     short loc_409685

.text:0040968C                 sub     eax, edx

.text:0040968E                 xor     ecx, ecx

.text:00409690                 add     edi, 0FFFFFFFBh

.text:00409693                 mov     ebx, eax

.text:00409695                 jz      short loc_4096CB

.text:00409697                 jmp     short loc_4096A0

.text:00409697 ; ---------------------------------------------------------------------------

.text:00409699                 align 10h

.text:004096A0

.text:004096A0 loc_4096A0:                             ; CODE XREF: dga+A7j

.text:004096A0                                         ; dga+D9_x0019_j

.text:004096A0                 imul    esi, 3E39B193h

.text:004096A6                 mov     edx, 89F5h

.text:004096AB                 sub     edx, esi

.text:004096AD                 and     edx, 7FFFFFFFh

.text:004096B3                 mov     esi, edx

.text:004096B5                 xor     edx, edx

.text:004096B7                 mov     eax, esi

.text:004096B9                 div     ebx

.text:004096BB                 inc     ecx

.text:004096BC                 mov     al, [ebp+edx+charset]

.text:004096C0                 mov     edx, [ebp+pDomain]

.text:004096C3                 mov     [ecx+edx-1], al

.text:004096C7                 cmp     ecx, edi

.text:004096C9                 jb      short loc_4096A0

.text:004096CB

.text:004096CB loc_4096CB:                             ; CODE XREF: dga+A5j

.text:004096CB                 imul    esi, 3E39B193h

.text:004096D1                 mov     ecx, 89F5h

.text:004096D6                 sub     ecx, esi

.text:004096D8                 and     ecx, 7FFFFFFFh

.text:004096DE                 mov     eax, 55555556h

.text:004096E3                 imul    ecx

.text:004096E5                 mov     eax, edx

.text:004096E7                 shr     eax, 1Fh

.text:004096EA                 add     eax, edx

.text:004096EC                 lea     eax, [eax+eax*2]

.text:004096EF                 mov     r, ecx

.text:004096F5                 sub     ecx, eax

.text:004096F7                 mov     ecx, [ebp+ecx*4+tlds]

.text:004096FB                 mov     eax, ecx

.text:004096FD                 lea     ecx, [ecx+0]

.text:00409700

.text:00409700 loc_409700:                             ; CODE XREF: dga+115_x0019_j

.text:00409700                 mov     dl, [ecx]

.text:00409702                 inc     ecx

.text:00409703                 test    dl, dl

.text:00409705                 jnz     short loc_409700

.text:00409707                 mov     edi, [ebp+pDomain]

.text:0040970A                 sub     ecx, eax

.text:0040970C                 mov     edx, ecx

.text:0040970E                 dec     edi

.text:0040970F                 nop

.text:00409710

.text:00409710 loc_409710:                             ; CODE XREF: dga+126_x0019_j

.text:00409710                 mov     cl, [edi+1]

.text:00409713                 inc     edi

.text:00409714                 test    cl, cl

.text:00409716                 jnz     short loc_409710

.text:00409718                 mov     ecx, edx

.text:0040971A                 shr     ecx, 2

.text:0040971D                 mov     esi, eax

.text:0040971F                 mov     eax, domain_nr

.text:00409724                 rep movsd

.text:00409726                 mov     ecx, edx

.text:00409728                 and     ecx, 3

.text:0040972B                 rep movsb

.text:0040972D                 inc     eax

.text:0040972E                 xor     edx, edx

.text:00409730                 mov     ecx, 0C8h

.text:00409735                 div     ecx

.text:00409737                 mov     ebx, [ebp+pDomain]

.text:0040973A                 mov     domain_nr, edx

.text:00409740

.text:00409740 loc_409740:                             ; CODE XREF: dga+35j

.text:00409740                                         ; dga+41j

.text:00409740                 push    ebx

.text:00409741                 call    gethostbyname   ; ws2_32.gethostbyname

.text:00409747                 neg     eax

.text:00409749                 sbb     eax, eax

.text:0040974B                 neg     eax

.text:0040974D                 jnz     short loc_40976B

.text:0040974F                 cmp     domain_nr, 0

.text:00409756                 jnz     loc_409610

.text:0040975C                 mov     edx, [ebp+sld_len]

.text:0040975F                 push    edx             ; size_t

.text:00409760                 push    0               ; int

.text:00409762                 push    ebx             ; void *

.text:00409763                 call    memset

.text:00409768                 add     esp, 0Ch

.text:0040976B

.text:0040976B loc_40976B:                             ; CODE XREF: dga+15Dj

.text:0040976B                 xor     eax, eax

.text:0040976D                 cmp     domain_nr, eax

.text:00409773                 pop     edi

.text:00409774                 pop     esi

.text:00409775                 setnz   al

.text:00409778                 pop     ebx

.text:00409779                 mov     esp, ebp

.text:0040977B                 pop     ebp

.text:0040977C                 retn

.text:0040977C dga             endp

.text:0040977C

.text:0040977C ; ---------------------------------------------------------------------------

DGA属性特征

在测试gethostbyname的时候,Qadars的域名生成算法已经产生了200多个不同的域名,如果这200个域名都没有办法得到解析,那么Qadars将会sleep 20s(这个不在之前反汇编代码中),接着从第一个域名开始解析。

这个DGA使用线性同余实现而不是通过随机数算法生成。而这个乘法的增加也是不常见的:

r←(35317−1043968403⋅r)mod2147483647

随机数生成的初始值是系统当前日期:

text:00409640                 push    0

.text:00409642                 call    ds:_time64

.text:00409648                 add     esp, 4

.text:0040964B                 push    0

.text:0040964D                 mov     esi, eax

.text:0040964F                 sub     eax, 345600

.text:00409654                 push    604800

.text:00409659                 sbb     edx, 0

.text:0040965C                 push    edx

.text:0040965D                 push    eax

.text:0040965E                 call    _allrem

.text:00409663                 sub     esi, eax

.text:00409665                 and     esi, 7FFFFFFFh

上述反汇编代码算法:

r=(u−(u−4⋅24⋅3600))mod7⋅24⋅3600

U是当前unix时间戳。分配如下:

Clipboard Image.png

计算机的结果在每周四晚上的深夜的值都是不一样的,因为1970年1.1日式星期四。所有的Aadars V3将会生成相同的域名,因为随机数生成的起始值都是一样的。

DGA算法使用硬编码的顶级域名:.com,.org以及.net。第二级别的域名包括12个随机字符串,字符串是从小写字母和数字当中选取。

总结,DGA算法的特性如下:

Clipboard Image.png

DGA算法重实现

下面的代码以python的形式显示Qadar的DGA。你也可以在其他地方找到这个算法,例如在我的GitHub上。

import argparse

import time

from datetime import datetime

import time

import string

 

def rand(r):

    return  (35317 - 1043968403*r) & 0x7FFFFFFF

 

def dga(date):

    charset = string.ascii_lowercase + string.digits

    tlds = [".com", ".org", ".net"]

    unix = int(time.mktime(date.timetuple()))

    b = 7*24*3600

    c = 3*24*3600

    r = ( (unix//b)*b - c) & 0x7FFFFFFF

 

    for i in range(200):

        domain = "" 

        for _ in range(12):

            r = rand(r)

            domain += charset[r % len(charset)]

        r = rand(r)

        tld = tlds[r % 3]

        domain += tld

        print(domain)

 

if __name__ == "__main__":

    parser = argparse.ArgumentParser()

    parser.add_argument("-d", "--date", 

            help="date for which to generate domains")

    args = parser.parse_args()

 

    if args.date:

        d = datetime.strptime(args.date, "%Y-%m-%d")

    else:

        d = datetime.now()

dga(d)

*参考来源:johannesbader.ch,FB小编东二门陈冠希编译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

Loading...

特别推荐

推荐关注

填写个人信息

姓名
电话
邮箱
公司
行业
职位
css.php