欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CTS感染型病毒还原算法解密文件

程序员文章站 2024-03-22 08:23:46
...

前言

这是最近遇到的一个感染型病毒,感染可移动设备和前用户目录下的exe文件,被感染的文件,病毒母体会首先写入文件中,然后将原始文件加密后和感染标记、加***一同存放在附加数据上。对此,我决定分析算法还原文件。

样本信息

名称:CTS.exe
SHA1:cb54a305a566c00742fb972c4ee62266e880ea78

样本简要分析

样本的主函数很短

CTS感染型病毒还原算法解密文件
CTS感染型病毒还原算法解密文件

向windows目录和temp目录下释放CTS.exe文件,设置自启动

CTS感染型病毒还原算法解密文件
开启线程感染可移动设备文件

CTS感染型病毒还原算法解密文件
在本地只感染当前用户目录下的exe文件

CTS感染型病毒还原算法解密文件

判断是否是exe文件

获取0x10位**进行加密读取到缓冲区的文件,病毒母体会首先写入文件中,然后将原始文件加密后和感染标记、加***一同存放在附加数据上

CTS感染型病毒还原算法解密文件

使用010editor对比两个被感染的文件,发现两个文件的前0x6800都是相同的,并且结尾处都有相同的标志

CTS感染型病毒还原算法解密文件

经过分析,文件结尾处最后0x18个字节分别是标志,文件大小和**

CTS感染型病毒还原算法解密文件

加密算法分析

加密算法并不多,只有不到100行的汇编代码

.text:00405060 encrypt_file_buffer proc near           ; CODE XREF: relase_file+55↓p
.text:00405060                                         ; infect_file+74↓p
.text:00405060
.text:00405060 var_109         = byte ptr -109h
.text:00405060 byte_100        = byte ptr -108h
.text:00405060 pe_start_addr   = dword ptr -8
.text:00405060 pe_file_size    = dword ptr -4
.text:00405060 crypt_key       = dword ptr  8
.text:00405060
.text:00405060                 push    ebp
.text:00405061                 mov     ebp, esp
.text:00405063                 sub     esp, 108h
.text:00405069                 mov     [ebp+pe_file_size], edx
.text:0040506C                 mov     [ebp+pe_start_addr], ecx
.text:0040506F                 xor     eax, eax
.text:00405071
.text:00405071 loc_405071:                             ; CODE XREF: encrypt_file_buffer+1E↓j
.text:00405071                 mov     [ebp+eax+byte_100], al
.text:00405078                 inc     eax
.text:00405079                 cmp     eax, 100h
.text:0040507E                 jb      short loc_405071
.text:00405080                 push    ebx
.text:00405081                 mov     ebx, [ebp+crypt_key]
.text:00405084                 push    esi
.text:00405085                 push    edi
.text:00405086                 xor     edi, edi
.text:00405088                 xor     esi, esi
.text:0040508A                 lea     ebx, [ebx+0]
.text:00405090
.text:00405090 loc_405090:                             ; CODE XREF: encrypt_file_buffer+69↓j
.text:00405090                 mov     dl, [ebp+esi+byte_100]
.text:00405097                 mov     eax, esi
.text:00405099                 and     eax, 0Fh       
.text:0040509C                 movzx   ecx, dl
.text:0040509F                 movzx   eax, byte ptr [eax+ebx]
.text:004050A3                 add     edi, eax
.text:004050A5                 add     edi, ecx
.text:004050A7                 and     edi, 0FFh      
.text:004050AD                 inc     esi
.text:004050AE                 mov     al, [ebp+edi+byte_100]
.text:004050B5                 mov     [ebp+esi+var_109], al
.text:004050BC                 mov     [ebp+edi+byte_100], dl
.text:004050C3                 cmp     esi, 100h
.text:004050C9                 jb      short loc_405090
.text:004050CB                 xor     ebx, ebx
.text:004050CD                 xor     esi, esi
.text:004050CF                 xor     edi, edi
.text:004050D1                 cmp     [ebp+pe_file_size], ebx
.text:004050D4                 jbe     short loc_40512D
.text:004050D6
.text:004050D6 loc_4050D6:                             ; CODE XREF: encrypt_file_buffer+CB↓j
.text:004050D6                 inc     esi
.text:004050D7                 and     esi, 0FFh
.text:004050DD                 inc     edi
.text:004050DE                 mov     dl, [ebp+esi+byte_100]
.text:004050E5                 movzx   eax, dl
.text:004050E8                 add     ebx, eax
.text:004050EA                 and     ebx, 0FFh
.text:004050F0                 movzx   eax, [ebp+ebx+byte_100]
.text:004050F8                 mov     [ebp+esi+byte_100], al
.text:004050FF                 mov     [ebp+ebx+byte_100], dl
.text:00405106                 movzx   ecx, [ebp+esi+byte_100]
.text:0040510E                 movzx   eax, dl
.text:00405111                 add     ecx, eax
.text:00405113                 and     ecx, 0FFh
.text:00405119                 movzx   eax, [ebp+ecx+byte_100]
.text:00405121                 mov     ecx, [ebp+pe_start_addr]
.text:00405124                 xor     [edi+ecx-1], al
.text:00405128                 cmp     edi, [ebp+pe_file_size]
.text:0040512B                 jb      short loc_4050D6
.text:0040512D
.text:0040512D loc_40512D:                             ; CODE XREF: encrypt_file_buffer+74↑j
.text:0040512D                 pop     edi
.text:0040512E                 pop     esi
.text:0040512F                 pop     ebx
.text:00405130                 mov     esp, ebp
.text:00405132                 pop     ebp
.text:00405133                 retn    4
.text:00405133 encrypt_file_buffer endp

从代码上看,一共有三个循环

首先看第一个循环,直接看汇编指令就很明显的看出是在创建一个0x100字节大小的数组,并给数组赋值从0x00到0xFF

CTS感染型病毒还原算法解密文件

可转成C代码

char key_table[256] = { 0 };
for (int i = 0; i < 256; i++)
{
	key_table[i] = i;
}

第二个循环,更新数组数据

CTS感染型病毒还原算法解密文件

这里主要关注谁给数组赋值,给数组的那个部分赋值即可

.text:004050B5                 mov     [ebp+esi+var_109], al
.text:004050BC                 mov     [ebp+edi+byte_100], dl

首先看[ebp+esi+var_109],esi从1开始,每次循环只自增1,所以它是key_table[i]

al是从key_table[edi]([ebp+edi+byte_100])中取出的,edi = (edi + key[i]+key_table[i])& 0xFF

dl是key_table[i+1]

可转化成C代码

int esi = 0;
int edi = 0;
int edx = 0;
int eax = 0;
int ecx = 0;
int ebx = 0;
for (int i = 0; i < 256; i++)
{
	edx = key_table[esi];
	eax = esi;
	eax = eax & 0xF;
	ecx = edx;
	eax = key[eax];
	edi = (edi + eax + ecx) & 0xFF;
	esi += 1;
	eax = key_table[edi];
	key_table[esi - 1] = eax;
	key_table[edi] = edx;
}

最后一个循环,异或加密数据

CTS感染型病毒还原算法解密文件

同样,只关注重点即可

xor     [edi+ecx-1], al

然后得到C代码

ebx = 0;
esi = 0;
edi = 0;
for (int i = 0; i < ecrypt_file_size; i++)
{
	esi += 1;
	esi = esi & 0xFF;
	edi += 1;
	edx = key_table[esi];
	eax = edx;
	ebx = (ebx + eax) & 0xFF;
	eax = key_table[ebx];
	key_table[esi] = eax;
	key_table[ebx] = edx;
	ecx = key_table[esi];
	eax = edx;
	ecx = (ecx + eax) & 0xFF;
	eax = key_table[ecx];
	buffer[0x6800 + edi - 1] = buffer[0x6800 + edi - 1] ^ eax;
}

所以,完整的加解密代码如下:

void encrypt_file_buffer()
{
	int esi = 0;
	int edi = 0;
	int edx = 0;
	int eax = 0;
	int ecx = 0;
	int ebx = 0;
	char key_table[256] = { 0 };

	for (int i = 0; i < 256; i++)
	{
		key_table[i] = i;
	}
	for (int i = 0; i < 256; i++)
	{
		edx = key_table[esi];
		eax = esi;
		eax = eax & 0xF;
		ecx = edx;
		eax = key[eax];
		edi = (edi + eax + ecx) & 0xFF;
		esi += 1;
		eax = key_table[edi];
		key_table[esi - 1] = eax;
		key_table[edi] = edx;
	}
	ebx = 0;
	esi = 0;
	edi = 0;
	for (int i = 0; i < ecrypt_file_size; i++)
	{
		esi += 1;
		esi = esi & 0xFF;
		edi += 1;
		edx = key_table[esi];
		eax = edx;
		ebx = (ebx + eax) & 0xFF;
		eax = key_table[ebx];
		key_table[esi] = eax;
		key_table[ebx] = edx;
		ecx = key_table[esi];
		eax = edx;
		ecx = (ecx + eax) & 0xFF;
		eax = key_table[ecx];
		buffer[0x6800 + edi - 1] = buffer[0x6800 + edi - 1] ^ eax;
	}
}

总结

虽然写出的还原看起来有点绕,但其实这个算法并不难。刚开始还原这个算法的时候,我把变量的名字定义的规规矩矩,然后看着看着就把值给对应混了,磕磕绊绊,花了好久才写好。后来才感觉这样做是真的蠢,直接推平之前的还原代码,变量直接对应寄存器,无脑对应汇编,很快就搞定了。算是自己踩的小坑,分享给大家。

相关标签: 病毒分析