1.简介
在安全厂商日趋成熟的背景下,编写免杀马的难度和成本日益增长。好用新兴的开源项目在短时间内就被分析并加入特征库。笔者调研了部分开源项目,其中也有项目做了类似的分析 [1],目前能够免杀的项目初步统计,其特征一是star数不过千,二是发布时间不会很长。尽管以上开源测试项目已经无法免杀,也有两种可以发展的方向,一个是学习其思想,自己实现并去特征免杀;二是改造原有项目,自己查特征、去特征,经过测试也能达到免杀。
免杀方法和思路很多,但据笔者观察,目前免杀分为两大流派。一是二进制流,利用汇编配合上C++,调用系统底层函数进内核的方式免杀。杀软如果直接在用户态检测其行为特征会比较困难。二是新工具新项目、小众工具流,其主要思想是寻找反病毒厂商未覆盖的方法和工具,一个是寻找新的语言工具和项目,跟厂商比速度。另一个是偏僻语言,用户量小,厂商一直并未发现或者工作重心不在上面。举个例子,可以用各种语言二次编译,配合上一些语言特性如python反序列化达成免杀。通过现有工具的组合有效提高复杂度,在反病毒人员的盲区里进行。两种各有优劣,后续若有文章会测试更多的免杀用例。这里推荐一个静态免杀学习项目[2]和52pojie上的免杀项目,利用了大部分后文中提到的免杀技术[3]。
2.杀毒软件检测方法
以下的内容多为前人总结。因为云查杀本质上也是基于特征查杀,顾不单独列出。
2.1特征码检测
对文件或内存中存在的特征做检测,一般的方法是做模糊哈希或者机器学习跑模型,优点是准确度高,缺点是对未知木马缺乏检测能力。所以目前依赖厂商的更新,厂商做的更新及时能有效提高杀软的防护水平。目前一些杀软对相似的病毒有一定的检测能力,猜测是基于模糊哈希做的。部分杀软同样对于加壳也有检测能力,对于不同的厂家有不同的策略,有些会对文件进行标记,而某数字会直接告警。
2.1.1关联检测
检测的特征不仅仅是恶意payload的特征,也可能是一组关联的代码,把一组关联信息作为特征。比如在使用加载器加载shellcode时,需要开辟内存,将shellcode加载进内存,最后执行内存区域shellcode。这些步骤就被反病毒人员提取出来作为特征,在调用了一组开辟内存的函数比如virtualAlloc之后对该内存使用virtualProtect来更改标示位为可执行并且对该内存进行调用就会触发报毒。以上只是一个简单的例子,具体情况具体分析,部分厂商对其进行了扩展,所以现在使用另外几个函数进行调用也无法免杀。不过其本质还是黑名单,还存在没有被覆盖到的漏网之鱼。
2.2行为检测
行为检测通过hook关键api,以及对各个高危的文件、组件做监控防止恶意程序对系统修改。只要恶意程序对注册表、启动项、系统文件等做操作就会触发告警。最后,行为检测也被应用到了沙箱做为动态检测,对于避免沙箱检测的办法有如下几个:
延时,部分沙箱存在运行时间限制
沙箱检测,对诸如硬盘容量、内存、虚拟机特征做检测
部分沙箱会对文件重命名,可以检测自身文件名是否被更改
2.3小结
以上是对杀软检测做的一个小结,目前学术界对恶意代码的检测集中在机器学习上,已经有部分杀软已经应用落地了,如微软。对杀软检测手法更多的了解有助于我们写免杀马。
3.绕过技术
目前,随着cs的流行,越来越多的人使用cs的shellcode,而放弃了自己开发编写的木马,或者使用改造的msf马。本篇文章也会以shellcode加载器作为例子。后续文章将会涉及更深入的内容。
3.1经典技术
经典免杀技术如下,由于篇幅所限,本篇只含部分免杀技术。
特征码修改
花指令免杀
加壳免杀
内存免杀
二次编译
分离免杀
资源修改
白名单免杀
3.2修改特征
一个加载器存在两个明显的特征,一个是shellcode和硬编码字符串。我们需要消除这些特征,比较方便的方案,使用base64等对上述特征进行编码,最好使用多种编码手段。对于shellcode,使用base64并不安全,所以更安全的方案是加密,一个简单的异或加密就能消除shellcode的特征。第二个是加载器的关联特征也需要消除,对于代码中出现连续调用的virtualAlloc,virtualProtect进行插入花指令,通过加入无意义的代码干扰反病毒引擎。
笔者的一点想法,进一步混淆源代码,在不加壳的情况下稍微增加静态分析难度。也有论文提出可以使用ROP来提高代码的分析难度,因为现存的代码分析引擎对间接跳转和调用的支持存在瑕疵,复杂逻辑的代码更需要人工分析[12]。
3.3内存免杀
shellcode直接加载进内存,避免文件落地,可以绕过文件扫描。但是针对内存的扫描还需对shellcode特征做隐藏处理。对windows来说,新下载的文件和从外部来的文件,都会被windows打上标记,会被优先重点扫描。而无文件落地可以规避这一策略。同时申请内存的时候采用渐进式申请,申请一块可读写内存,再在运行改为可执行。最后,在执行时也要执行分离免杀的策略。
3.4修改资源
杀软在检测程序的时候会对诸如文件的描述、版本号、创建日期作为特征检测[7]。可用restorator对目标修改资源文件。
3.5隐藏IAT
每调用一个系统函数就会在导入表中存在,这对于反病毒人员是个很好的特征,直接通过检测导入表中有没有调用可疑函数。这里就需要隐藏我们的导入函数。一个比较通用的办法是直接通过getProcessAddress函数获取所需要函数的地址。知道地址也就能直接调用,这样整个程序内除了getProcessAddress其他函数都不会出现在IAT表中。尽管这样已经能绕过上面的检测,但还有种更保险的做法,用汇编从Teb里找到kernel32.dll的地址,再从其导出表中获取所需系统函数。

出自(https://www.52pojie.cn/thread-1360548-1-1.html)
3.6分离免杀
整个shellcode加载器分为两个部分,分离下载shellcode和执行。加载器处在stage0阶段,其作用除了加载大马外并无其他作用。但是直接执行大马会被检测到,所以需要用到分离免杀。

出自(https://www.anquanke.com/post/id/190354)
通常杀软只检测一个进程的行为,所以如果存在两个恶意进程通过进程间通信就能逃过检测、达到免杀。
分离免杀的方法多种多样,既可以用windows的管道[4][6],也可以用socket通信[5]。
3.7二次编译免杀
像msf或者cs的shellcode在各个厂商里都盯的比较严,对于这些shellcode已经提取好特征只要使用就会被检测出。所以会使用各种编码器进行免杀。编码器有很多种,这里仅推荐msf的shikata_ga_nai,是一种多态编码器,每次生成的payload都不一样。
3.7.1其他语言编译免杀
因为各种语言特性不同,对于不同语言编写的加载器厂商不一定第一时间跟进,导致了一段时间内可以绕过。在2020年初的时候,使用python作为加载器[11]免杀一阵,现在针对这类加载器逐渐严格,导致直接加载报毒,需要更多的混淆还改进。在2020年5月,奇安信红队出过一篇文章,利用python反序列化来加载python加载器[8],目前截止本文测试2021年1月已经无法使用了,是个比较好的思路。
3.8系统函数白名单免杀-uuid方式
Gamma实验室在2021年2月3号发布了一篇微信公众号的文章[9],分析了Check Point Research研究的apt攻击的文章。其中的亮点在内存中shellcode的编码方式和调用都没有使用传统编码和调用的方式,利用了系统函数的特性,这次的例子是uuid。使用的是系统给UuidFromStringA函数将payload的uuid数组转化为shellcode加载进内存,其特点就是程序中存在大量硬编码的uuid。另一个,调用使用的是EnumSystemLocalesA函数,它的第一个参数是回调函数指针,也就意味着参数一只要传入shellcode首地址就会执行恶意命令。现已被杀,但是这里给出一个比较重要的思路,还有其他可以利用的Windows系统函数可以利用。另外现已经有项目实现了使用调用guid来进行免杀。
3.9某数字公布的stage uri检测
因为cs密钥都是硬编码的,被逆向出来后,只要使用stage分阶段的方式加载cs,其流量都会被解密并能检测其特征[10]。对抗的方式,二次打包改密钥,或更改cs的配置文件使得关闭stage。同时使用stageless,也得更换自己的dll,cs的beacon.dll同样在检测列表中。其实用改造过的msf马也不错,这也就是上文提到的过的开源项目,目前这个项目已经被某数字检测了,所以需要对项目进行改造。
4.总结
以上总结了主流的免杀方式,后文的免杀就是以上技术的混合使用。本文还未涉及到诸如加壳,dll以及使用powershell免杀等,这些会在之后的文章中提出。
5.参考文献
[1] https://github.com/TideSec/BypassAntiVirus
[2] https://github.com/Rvn0xsy/BadCode
[3] https://www.52pojie.cn/thread-1360548-1-1.html
[4] https://payloads.online/archivers/2019-11-10/4
[5] https://payloads.online/archivers/2019-11-10/5
[6] https://www.anquanke.com/post/id/190354
[7] https://cloud.tencent.com/developer/article/1512006
[8] https://mp.weixin.qq.com/s/gZ28MvCPTQbTAVtQjO7T8w
[9] https://mp.weixin.qq.com/s/1DvYNDiZc2iV1pXEn7GZEA
[10] https://mp.weixin.qq.com/s/fhcTTWV4Ddz4h9KxHVRcnw
[11] https://www.secpulse.com/archives/151899.html
[12] https://arxiv.org/pdf/2012.06658.pdf
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解
文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景 最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。 在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记
我在安装“redcarpet”gem时遇到以下错误。它在我friend的机器上安装没有问题。(我想安装它来运行yard)ruby版本:1.9.3命令输出:D:\Learning\Common_POM_FW\SampleProjects>yard[error]:Missing'redcarpet'gemforMarkdownformatting.Installitwith`geminstallredcarpet`D:\Learning\Common_POM_FW\SampleProjects>geminstallredcarpetTemporarilyenhancingPATHtoinc
我们正在开发一个需要推送通知的WP8应用程序。为了测试它,我们使用CURL命令行运行推送通知POST请求,确保它实际连接,使用客户端SSL证书进行身份验证并发送正确的数据。我们确实知道,当我们收到对设备的推送时,这项工作是有效的。这是我们一直用于测试目的的CURL命令:curl--certclient_cert.pem-v-H"Content-Type:text/xml"-H"X-WindowsPhone-Target:Toast"-H"X-NotificationClass:2"-XPOST-d"MytitleMysubtitle"https://db3.notify.live.ne
我在Windows7上运行Jekyll时遇到问题。当我运行时jekyll出现以下错误C:\temp\jekyll\kouphax.github.com>jekyllConfigurationfromC:/temp/jekyll/kouphax.github.com/_config.ymlBuildingsite:C:/temp/jekyll/kouphax.github.com->C:/temp/jekyll/kouphax.github.com/_siteunit-testingYouaremissingalibraryrequiredforTextile.Pleaserun:$[s