比来,我留意到一个会商Qadars银行木马的论坛主题,而且在事先,Qadars银行木马在VT(virustotal.com)的检测率十分低(4/56),SHA1:563379a48d876f6c35317bb7551efeb55754123056109ab030d1e796ae1b9c2c。
我感觉它是一个很适宜停止深条理手艺探求的候选对象,我将我的剖析进程分为三个局部:
[Asm] 纯文本查看 复制代码 第一阶段:对歹意的顺序流程停止混杂处置;维护并解稀主模块。第两阶段:搜集每一个零碎独有的信息,在零碎上确坚持暂性并运转新的历程。(第三阶段)第三阶段:与号令战节制(C&C)中心树立通讯。
第一阶段
那个阶段包罗两个没有同的局部。那两局部皆用于从检测中维护歹意硬件的主模块。该歹意硬件是经过履行了下列步调去完成的:
[Asm] 纯文本查看 复制代码 经过创立“渣滓”代码去混杂歹意硬件的顺序流程;经过创立一个构造化异常处置(SEH)的异常去改动顺序的节制流程并将节制流程传递给它;将解稀的BLOB数据变成一个新的代码段,并从一个异常中跳到那个新的代码段中;经过履行一个“彩蛋”找到附减的BLOB数据,那个BLOB数据在解稀,解压之后,成了一个新的PE镜像文件。那个文件便是歹意硬件的主模块。
闭于第1阶段(异常处置顺序)的第一局部的其他具体信息:
· 检索KERNEL32的天址;
· 检索HeapCreate的天址,分派的大小为0×2729的缓冲区。
挪用HeapCreate之前的仓库以下,
[Asm] 纯文本查看 复制代码 012F7A0 00040000 ;HEAP_CREATE_ENABLE_EXECUTE012F7A4 00002729 ;initial size012F7A8 00002729 ;max size
在原初文件中与偏偏移0040C9E8处的BLOB数据,然后复造并陈列BLOB数据。
那个BLOB数据被看做一个数组。变形后的数组成了新的代码段然后把节制流程传递给它。
歹意硬件采与的将数组转换到无效代码的步调是复杂位互换基于天生稀钥的偏偏移量停止计算的。该算法以下所示:
1.在堆(heap)平分配缓冲区,然后将BLOB数据复造到该缓冲区中,该缓冲区将被视为一个数组。
2.计算出的偏偏移量为第一个将被交流的字符:
[Asm] 纯文本查看 复制代码 ;Initial key is 0x5A219DBA.;.text:0041F858 8B 45 14 mov eax, [ebp+key];.text:0041F85B 33 D2 xor edx, edx;.text:0041F85D F7 75 10 div [ebp+data_size];.text:0041F860 89 55 E8 mov [ebp+reminder], edx
3.当地存储的后果:
[Asm] 纯文本查看 复制代码 ;.text:0041FAC5 8B 4D 08 mov ecx, [ebp+allocated_buffer];.text:0041FAC8 03 4D E8 add ecx, [ebp+reminder];.text:0041FACB 8A 11 mov dl, [ecx];.text:0041FACD 88 55 E4 mov [ebp+current_char_3], dl
4.计算出的偏偏移量为第两个要交流的字符,并将其存储在当地。那个字符是从数组的终尾加往曾经处置的字符数目失掉的:
[Asm] 纯文本查看 复制代码 ;.text:0041FC18 8B 55 08 mov edx, [ebp+allocated_buffer];.text:0041FC1B 03 55 FC add edx, [ebp+counter];.text:0041FC1E 8A 42 FF mov al, [edx-1];.text:0041FC21 88 45 EC mov [ebp+current_char_1], a
5.交流第一个战第两个字符:
[Asm] 纯文本查看 复制代码 ;.text:0041FD4D 8B 45 08 mov eax, [ebp+allocated_buffer];.text:0041FD50 03 45 E8 add eax, [ebp+reminder];.text:0041FD53 8A 4D EC mov cl, [ebp+current_char_1];.text:0041FD56 88 08 mov [eax], cl ;.text:0041FFCE 8B 45 08 mov eax, [ebp+allocated_buffer];.text:0041FFD1 03 45 FC add eax, [ebp+counter];.text:0041FFD4 8A 4D E4 mov cl, [ebp+current_char_3];.text:0041FFD7 88 48 FF mov [eax-1], cl
例如,前两个字符被交流。交流前的内存为:
[Asm] 纯文本查看 复制代码 00BD0614 0000BD2728 A6
交流后的内存为:
[Asm] 纯文本查看 复制代码 00BD0614 A600BD2728 00
6.计算用于下一次序递次一个字符被交流时所需求计算的稀钥:
[Asm] 纯文本查看 复制代码 ;.text:004201CD 8B 55 14 mov edx, [ebp+key];.text:004201D0 C1 EA 19 shr edx, 19h;.text:004201D3 89 55 F0 mov [ebp+new_key], edx;.text:004203B1 8B 4D 14 mov ecx, [ebp+key];.text:004203B4 C1 E1 07 shl ecx, 7;.text:004203B7 89 4D 14 mov [ebp+key], ecx;.text:00420680 8B 55 14 mov edx, [ebp+key];.text:00420683 0B 55 F0 or edx, [ebp+new_key];.text:00420686 89 55 14 mov [ebp+key], edx;.text:004207FB 8B 55 14 mov edx, [ebp+key];.text:004207FE 2B 55 10 sub edx, [ebp+data_size];.text:00420801 89 55 14 mov [ebp+key], edx;.text:00420AD5 8B 45 14 mov eax, [ebp+key];.text:00420AD8 2D D2 02 96 49 sub eax, 499602D2h;.text:00420ADD 89 45 14 mov [ebp+key], eax
跳转到新创立的代码段:
[Asm] 纯文本查看 复制代码 .text:00406447 FF 55 FC call [ebp+allocated_buffer]
闭于第一阶段的第两局部的更多具体信息(在新创立的代码段局部):
[Asm] 纯文本查看 复制代码 检索API的天址并在运转时立刻挪用那些API;出有导进表的创立;定位XOR减稀的BOLB数据;解稀BLOB数据并对其停止解紧缩;停止解稀,解紧缩后的BLOB数据是歹意硬件的次要模块。
为了查找BLOB数据,该歹意硬件运用了一品种似于在shellcode中运用的“彩蛋”手艺的脚法。起首,它计算出以下数据:
[Asm] 纯文本查看 复制代码 0012F74C 56 6F FC 5A 83 1A 34 D9 6F 5C 41 73 28 94 EF 13 VonZa.4+o\As(ön.0012F75C 31 A8 B9 0B 1¿|
歹意硬件模块主体的内容被复造到了在堆上分派的缓冲区。前8个字节是歹意硬件在可履行文件中搜刮的标记。那便是所谓的“蛋”,它被发如今磁盘上的可履行文件的偏偏移0xE511处。从该文件的尾部开端到头部停止扫描。一旦标志被找到时,歹意硬件管帐算出被减稀的BLOB数据的大小。为了做到那一面,它与了跟在“蛋”前面的4个字节,而且将那个4个字节与下面的BLOB数据中的偏偏移+0×08处的数据停止异或(XOR)。
接着,该文件中的8个字节战上述BLOB数据(偏偏移 +0x0C)被用于计算初初的XOR 稀钥,计算后果将被用于解稀BLOB数据。文件中被减稀的数据是从偏偏移0xE525处开端的;BLOB数据的大小为0xC76A。上面的功用用于BLOB数据的解稀:
[Asm] 纯文本查看 复制代码 debug025:00BD0CBE decode_data_to_decompress proc near debug025:00BD0CBEdebug025:00BD0CBE var_18= dword ptr -18hdebug025:00BD0CBE var_14= dword ptr -14hdebug025:00BD0CBE var_10= dword ptr -10hdebug025:00BD0CBE var_C= dword ptr -0Chdebug025:00BD0CBE var_4= dword ptr -4debug025:00BD0CBE data= dword ptr 8debug025:00BD0CBE size= dword ptr 0Chdebug025:00BD0CBE key= dword ptr 10hdebug025:00BD0CBEdebug025:00BD0CBE 55 push ebpdebug025:00BD0CBF 89 E5 mov ebp, espdebug025:00BD0CC1 83 EC 1C sub esp, 1Chdebug025:00BD0CC4 53 push ebxdebug025:00BD0CC5 56 push esidebug025:00BD0CC6 57 push edidebug025:00BD0CC7 01 FF add edi, edidebug025:00BD0CC9 8B 5D 0C mov ebx, [ebp+size]debug025:00BD0CCC F7 D0 not eaxdebug025:00BD0CCE 42 inc edxdebug025:00BD0CCF 09 55 F0 or [ebp+var_10], edxdebug025:00BD0CD2 83 EB 03 sub ebx, 3debug025:00BD0CD5 0F AF F7 imul esi, edidebug025:00BD0CD8 81 F1 B8 00 00 00 xor ecx, 0B8hdebug025:00BD0CDE 8B 75 08 mov esi, [ebp+data]debug025:00BD0CE1 87 55 EC xchg edx, [ebp+var_14]debug025:00BD0CE4 21 F2 and edx, esidebug025:00BD0CE6debug025:00BD0CE6 loc_BD0CE6: debug025:00BD0CE6 41 inc ecxdebug025:00BD0CE7 83 FB 00 cmp ebx, 0 ; ebx is the counterdebug025:00BD0CEA 74 5C jz short loc_BD0D48debug025:00BD0CEC 49 dec ecxdebug025:00BD0CED 1B 55 F4 sbb edx, [ebp+var_C]debug025:00BD0CF0 8B 06 mov eax, [esi]debug025:00BD0CF2 33 4D F4 xor ecx, [ebp+var_C]debug025:00BD0CF5 01 C9 add ecx, ecxdebug025:00BD0CF7 33 45 10 xor eax, [ebp+key]debug025:00BD0CFA 09 DF or edi, ebxdebug025:00BD0CFC 89 06 mov [esi], eaxdebug025:00BD0CFE 2B 55 EC sub edx, [ebp+var_14]debug025:00BD0D01 F7 DF neg edidebug025:00BD0D03 49 dec ecxdebug025:00BD0D04 8B 45 10 mov eax, [ebp+key]debug025:00BD0D07 87 55 E8 xchg edx, [ebp+var_18]debug025:00BD0D0A 0F AF FA imul edi, edxdebug025:00BD0D0D F7 D7 not edidebug025:00BD0D0F EB 03 jmp short loc_BD0D14 debug025:00BD0D14debug025:00BD0D14 loc_BD0D14: debug025:00BD0D14 C1 C0 07 rol eax, 7debug025:00BD0D17 4A dec edxdebug025:00BD0D18 01 F7 add edi, esidebug025:00BD0D1A EB 01 jmp short loc_BD0D1D debug025:00BD0D1Ddebug025:00BD0D1D loc_BD0D1D: debug025:00BD0D1D 2B 45 0C sub eax, [ebp+size]debug025:00BD0D20 2B 55 FC sub edx, [ebp+var_4]debug025:00BD0D23 87 FF xchg edi, edidebug025:00BD0D25 F7 D7 not edidebug025:00BD0D27 2D D2 02 96 49 sub eax, 499602D2hdebug025:00BD0D2C 83 EA 06 sub edx, 6debug025:00BD0D2F 01 F7 add edi, esidebug025:00BD0D31 89 45 10 mov [ebp+key], eaxdebug025:00BD0D34 81 E2 80 00 00 00 and edx, 80hdebug025:00BD0D3A 0B 4D E8 or ecx, [ebp+var_18]debug025:00BD0D3D 4B dec ebxdebug025:00BD0D3E 11 C7 adc edi, eaxdebug025:00BD0D40 29 C7 sub edi, eaxdebug025:00BD0D42 46 inc esidebug025:00BD0D43 0F AF FB imul edi, ebxdebug025:00BD0D46 EB 9E jmp short loc_BD0CE6debug025:00BD0D48 ;------------------------------debug025:00BD0D48debug025:00BD0D48 loc_BD0D48: debug025:00BD0D48 87 55 EC xchg edx, [ebp+var_14]debug025:00BD0D4B 29 F3 sub ebx, esidebug025:00BD0D4D 5F pop edidebug025:00BD0D4E 5E pop esidebug025:00BD0D4F 5B pop ebxdebug025:00BD0D50 C9 leavedebug025:00BD0D51 C2 0C 00 retn 0Chdebug025:00BD0D51 decode_data_to_decompress endp
接着,被解稀的BLOB数据被解紧缩。挪用RtlDecompressBuffer前的仓库以下:
[Asm] 纯文本查看 复制代码 0012F270 00000002 ;compressionformat ;#define COMPRESSION_FORMAT_LZNT1 (0x0002)0012F274 00C20000 debug027:unk_C20000 ;destination0012F278 00013600 ;uncompressed size0012F27C 00C0857D debug026:00C0857D ;compressed buffer0012F280 0000C76A ;compressed size0012F284 0012F714 Stack[00000BBC]:0012F714 ;final uncompressed size
|