来看雪很久了,写一篇文章,感谢大家的无私奉献!
    最近在Ph4nt0m Webzine第四期上看到一篇文章,卡巴虚拟机启发式扫毒的绕过方法,里面讲了一个方法,就是让虚拟机执行大量无意义的操作,而虚拟机无法完全虚拟这个过程,这个方法也绕过了虚拟机启发式的扫描。但该方法的缺陷是占用了大量的cpu和内存资源,而在某些情况下也会影响木马的正常运行,比如在远程线程插入的时候导致无法实现成功插入。
虚拟机启发式杀毒应该可以理解为在虚拟机中执行和启发式杀毒。虚拟机即构造一个虚拟执行环境或者说一个仿真的环境,将病毒等恶意代码在该仿真的环境中运行。该仿真的环境和用户计算机的真实环境是互相隔离的。
    启发式指的是自我发现并推断或判定事物的方式。启发式杀毒通过分析程序指令的序列或者API函数的调用顺序以及其他恶意代码与正常程序的不同等经验和知识的组合来判定是否是恶意代码。某种程度上说,启发式杀毒已经初具人工智能。
    虽然杀毒技术日益强大,但我们总是有办法规避其查杀机制的,记得曾经也有人证明过,杀毒软件是不可能检测所有的病毒或木马的,其证明过程运用了图灵论的相关知识。
    2008年国内的xyzreg发表了一篇突破卡巴7的虚拟机启发式杀毒的文章.该方法是病毒或者木马在执行入口点进行父进程的判断,如果发现父进程是杀毒软件的进程,便不再执行接下来的真正的病毒代码,自动返回。如果是父进程是explorer.exe、cmd.exe等就运行真正的病毒代码。这样就能躲避卡巴7.0的虚拟机启发式扫描。发现该方法在kis2010下已经不再适用,发现kis2010会将自身进程模拟成explorer.exe。所以检查父进程是否是explorer.exe的方法不行了,但是如果检查自己的父进程是否是cmd.exe就可以。当然这个实用性并不强,因为要求病毒木马必须由cmd.exe启动,有很大的局限性。
    最近在网上看到有人也提出了一种新的方法,即两次启动方法。第一次启动执行时不执行真正的木马代码,第二次执行时发现自己已经执行过一次就执行真正的木马代码,卡巴在查杀的时候,只会执行第一次,所以这样的方式也能绕过虚拟机启发式扫描,但需要两次的启动机会使得木马的生存能力降低了不少,不是最好的解决办法。
    由此看来,只有寻找更可靠、高效的方法来实现对虚拟机启发式扫描的规避才是我们最好的出路。
    下面我们以一个远程线程注入ie进程的操作来实现如何突破kis2010虚拟机启发式扫描。
    主要代码如下:
  GetSystemDirectory(DllPath,sizeof(DllPath));
  strcat(DllPath,"\\insert.dll");//获得待插入的dll路径
  Pid=GetProcessID(“iexplorer.exe”);//获得ie的进程id
  InjectDll(DllPath,Pid);//远程线程插入ie
  该程序会被kis2010查杀,如图所示:
  
  
  
  详细报告如下:
  
  
    虚拟机和真实环境肯定是有区别的。我们得找到这种区别,找到存在一种导致虚拟机无法虚拟的情况就可能突破该机制了。
    Ph4nt0m Webzine的那篇文章也介绍到,kis2010的虚拟机不仅在对api的模拟、程序执行的流程、异常处理机制虚拟得很到位,而且对时间的虚拟也很到位,比如在程序中加入sleep(100000)函数让程序睡眠很长一段时间,但仍被报Invader。
    让我们再来看看针对文件生成的虚拟效果如何。实验代码如下:
  GetSystemDirectory(DllPath,sizeof(DllPath));
  trcat(DllPath,"\\svchost.dll");
  Pid=GetProcessID(“iexplorer.exe”);
  FILE *stream;
  stream=fopen("xyc.exe","w+");
  if (stream!=NULL) 
    {
      InjectDll(DllPath,Pid);
    }
      还是被报Invader!
    那么虚拟访问网络的效果如何呢?如果我们让程序去一个根本不存在的网络地址去下载一个根本不存在的文件,如果失败,就正常执行后面的注入动作。当然结果肯定是下载失败,实际中也是肯定能执行后面的注入代码的。实验代码如下:
           GetSystemDirectory(DllPath,sizeof(DllPath));
  trcat(DllPath,"\\svchost.dll");
  Pid=GetProcessID(“iexplorer.exe”);
  TCHAR szFileName[MAX_PATH] = {0};
  URLDownloadToCacheFile(NULL,"file://c:\\windows\\xyc.exe",szFileName,MAX_PATH,0,NULL);   //从指定的路径下载文件,url是一个根本不存在的地址。
  FILE *stream;
  stream=fopen(szFileName,"rb+");
  if (stream==NULL) //如果下载失败就执行
    {
      InjectDll(DllPath,Pid);
    }
      对程序进行查杀扫描,没有检测到危险,成功。如图所示:

    原因在于卡巴的虚拟机没有真正的像真实环境一样对像       URLDownloadToCacheFile(NULL,"file://c:\\windows\\xyc.exe",szFileName,MAX_PATH,0,NULL); 这样的语句块进行真正的执行。这样就实现了对卡巴虚拟查毒的绕过。
本文过于简陋,意在抛砖引玉,引发大家更多的思考。