转载

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

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

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

例如,在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:

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

在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时间戳。分配如下:

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

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

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

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

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

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)

原文  http://www.freebuf.com/articles/network/102019.html
正文到此结束
Loading...