当前位置: 首页 > 科技观察

基于签名和行为检测的区别

时间:2023-03-18 15:30:41 科技观察

在本文中,我们将介绍基于签名和基于行为的检测之间的主要区别。此外,还说明了绕过个别检测的示例。为什么在相关Packer发布后仍检测到MSF-或CobaltStrike-(CS)有效载荷的问题经常被提出。答案有两个:1.绕过基于签名的检测;2.基于行为的检测被触发并终止进程。使用我们的自定义打包程序将导致反扫描。封装后的MSFpayload如下:但这并不意味着,在运行时执行时,这些防病毒程序不会检测到payload。为什么会这样?基于签名的检测基于签名的检测非常简单。最早的防病毒程序有一个带有文件哈希的签名数据库,它们只是将磁盘上任何可执行文件的哈希值与已知的恶意可执行文件哈希值进行比较。例如,数据库包含Mimikatz发布二进制文件的SHA1/MD5哈希值。更改可执行文件的散列就像操作其中的单个字节一样简单,因此这种检测是不可靠的。基于这一事实,安全供应商转而检测特定的BytePattern签名。因此,继续Mimikatz的示例,具体的字节模式/十六进制值标记如下:可以看出,不仅为每个已知的恶意二进制文件/有效负载标记一个模式,而且标记多个常见模式。Mimikatz始终是基于签名的检测的一个很好的例子,因为通常供应商有几十种用于Mimikatz二进制检测的模式。通过这种方式,也可以检测到略有修改的版本。使用yara规则可以构建更高级的检测。这些规则可以扫描文件或内存内容,并允许更复杂的条件和不同模式的组合。Mimikatzyara规则的一个例子如下:在这个例子中,如果在文件或内存中找到上述三个字符串,则触发此规则,AV/EDR程序可以执行警报或终止进程等操作。例如,我们在关于构建自定义Mimikatz二进制文件的文章中描述的技术可以绕过此类检测。加壳器的内部工作原理始于了解加壳器如何工作的基础知识,它能做什么和不能做什么。最后,一个程序用于将有效载荷包装在另一个程序中,以避免对其进行基于签名的检测。因此,如果像Mimikatz这样的有效载荷包含某些字符串,这些字符串将不再在生成的二进制文件中可见。包装过程可以通过某种编码/混淆或加密来完成。我个人更喜欢加密的有效负载,因为这会产生最好的随机性,因此基于签名的检测最少。这种编码或加密的有效负载必须在生成的加载程序中解码/解密,以便可以从内存中执行明文有效负载。根据有效载荷,加壳器还可以在当前进程或远程进程中删除更多检测:如果您的加壳器正在修补/绕过AMSI,您可以从内存中安全地执行不同的已知恶意脚本(PS1、VBA、JS等)。)或C#程序集。为了绕过基于ETW的检测,加壳者还可以通过不同的发布技术修补/绕过ETW。可以通过取消挂钩或直接/间接使用系统调用来绕过基于挂钩的Win32API检测。基于熵的检测将检测到许多加壳程序,因为有效载荷的加密会由于随机性而导致非常高的熵。这可以通过向生成的二进制文件添加数千个单词来绕过,因为这再次减少了熵。但是,即使应用了所有这些技术,仍然存在更多潜在的“问题”:1.内存扫描;2.行为检测;3.攻击者。一般内存扫描也可以使用加壳来绕过,但是这个非常有限。内存扫描和常见的绕过技术由于基于签名的检测很容易被加壳技术绕过,因此越来越多的AV/EDR供应商倾向于使用扫描来进行内存分析。这些扫描通常不会在所有进程中一直运行,因为这会消耗太多资源,但可能会在某些情况下触发。例如,内存扫描通常出现在以下情况:产生了一个新进程,例如运行可执行文件;进程的行为触发了内存扫描;第一个很容易绕过。例如,即使是加壳器也可以在解码/解密真正的有效载荷之前睡一会儿。在这种情况下,将进行内存扫描,但不会发现任何内容,因为有效负载仍处于加密状态。仍然有一些方法可以检测基于Win32睡眠的内存扫描绕过,例如此处演示的。作为使用Sleep的替代方法,您还可以在特定时间内执行伪代码或执行计算。除了使用Sleep,还有许多其他选择。但总的来说,绕过内存扫描的方法有以下三种:更改/修改有效负载的源代码,以避免基于签名的检测;更改有效负载的行为,以便永远不会触发内存扫描;内存加密。我个人更喜欢第一个选项,它是每个程序一次性的,只要新代码库不公开,将来也不应该检测到它。绕过基于行为的内存扫描更加困难,具体取决于您的有效负载的行为。想象一下Mimikatz操作(例如,使用OpenProcess打开LSASS的句柄)触发扫描,此时Mimikat无法从内存中隐藏,因为它需要加密才能工作。因此,Mimikatz不会选择内存加密。对于像CobaltStrike这样著名的C2框架,最常见的选择是内存加密。但是,如果您无权访问源代码,则不可能通过修改它来避免内存检测。一般来说,C2框架是这种技术的首选,因为它们大部分时间都处于休眠状态。如果一个程序什么都不做,它的内存内容可以在这段时间内被加密,没有任何问题。基于行为检测的一些示例和绕过但是什么行为会在运行时触发AV/EDR操作或内存扫描?基本上一切都很好。将内容写入内存、以特定顺序或时间范围加载特定库、创建注册表项、执行初始HTTP请求或其他任何操作。我这里举几个例子,介绍相应的绕过技术。根据我个人的经验,AV/EDR很少会在检测到某种行为后立即杀死进程。这是因为AV/EDR供应商不希望出现太多误报结果。由于误报结果和终止过程的行为,这已经足以导致生产中断。所以他们需要几乎100%确定某个动作肯定是恶意程序终止了相应的进程。这就是为什么许多供应商将行为检测与内存扫描结合起来以验证他们是否发现了恶意内容的原因。FodhelperUAC绕过示例基于行为的检测的一个很好的例子是使用WindowsDefender的FodhelperUAC绕过。这种方法非常流行,但也很容易被利用,因为它只需要创建一个注册表项,然后调用fodhelper.exe:在启用防病毒的情况下执行此操作将导致以下检测:此警报既不会终止已执行的进程也不会新终止产生的进程,但仍会导致在任何攻击中被检测到。检测本身无法绕过AMSI,修补ETW也无济于事。因为那是触发此警报的特定行为。我对此处标记的内容进行了一些简单的试错分析,发现防病毒软件不喜欢HKCU:\Software\Classes\ms-settings\Shell\Open\command(Default)条目以及目录*C:\windows\system32*和*C:\windows\syswow64*中的任何.exe。因此触发警报的操作是使用这些字符串之一在上述目录中创建一个注册表项。幸运的是,我们不需要指定.exe来执行二进制文件,也不需要两个目录来使攻击起作用。因此,作为替代方案,我们可以直接复制e.G.一个C2-Stager进入任何可写目录并使用UAC-Bypass执行它而不调用扩展。但到2022年,许多OffSec用户将意识到在安装了AV/EDR的系统上运行任何未签名的可执行文件可能不是一个好主意。因此,作为替代方案,我们还可以执行任何已签名的可信可执行文件并将相应的Sideloading-DLL放在同一目录中。还有第三种选择,我们可以将rundll32.exe复制到我们的可写目录并在那里执行。Meterpreter基于行为的检测切记不要使用分段的有效载荷,它们会被防病毒软件捕获。因此,在我们的示例中,我们将生成一个非碎片化的反向HTTPSshellcode来执行。这可以通过以下命令实现:shellcode的执行方式本文不做介绍,因为我只是想展示行为检测,但通常你需要以下内容:Shellcode在运行时加密和解密以避免登录disk,或者在运行时从远程web服务器加载它;使用直接或间接系统调用执行,否则shellcode将在执行前被标记;在这种情况下,无需修补AMSI/ETW即可让Meterpreter运行。然而,即使您使用系统调用绕过基于签名的磁盘检测和shellcode检测,您也应该能够看到一个新的Meterpreter会话传入:但这仅意味着我们的初始有效载荷已成功执行。一秒钟后,进程终止并进行以下检测:同样,这是一个基于行为的检测,由附加的DLL文件触发,通过普通Win32API和反射DLL注入技术加载。在这种情况下,stdapi-DLL的注入触发了警报。在msfconsole提示符下,您可以使用以下命令禁用stdapiDLL的加载:这样,您应该能够很好地接收Meterpreter会话:但是,禁用stdapi加载将导致您的Meterpreter中几乎没有命令/模块-会话,只有“内核命令”可用。等待几分钟后,您可以使用以下命令手动加载stdapi,但应该仍然没有检测:Whatisthisbehavior-basedinstrumentationabout?我不能100%确定,但很可能是以下因素的组合:1.新生成的进程;2.新进程在为反射加载的DLL调用特定WindowsAPI之前的时间帧x;3.内存扫描,用4.Meterpreter检测内存并终止进程的操作。注意:这是绕过Meterpeter防御行为检测的唯一可能方法。如上所述,绕过内存扫描的一种常见方法是修改源代码以避免内存中的签名。绕过内存扫描的一种常见方法是修改源代码以避免内存中的签名,因此修改源代码是另一种选择,Meterpreter源代码混淆的自动化方法可以在这里找到。这样做之后,我们能够在启用autostdapi-Loading的情况下避免这种检测。第三种方法是内存加密,这在Meterpreter中不容易实现,因为HTTP/HTTPS源代码不会像许多其他c2框架一样在请求命令之前在时间帧x上休眠。它只是抛出许多HTTP(S)请求,中间有一些小的延迟。所以内存加密打破了这个过程。如果你使用这种方法,那么你需要在源代码中自己集成一个带有内存加密的自定义睡眠功能。CobaltStrike检测CobaltStrike很可能是最复杂、分析最深入的C2框架。这可能是因为在过去几年中它已被许多不同的攻击组织在野外使用。不更改默认设置在大多数环境中是不可用的,因为这会立即被检测到。即使使用自定义打包器/加载器和系统调用来执行shellcode,它在许多环境中仍然会失败。因此,我将解释作为操作员使用此框架所需完成的最低要求和修改。C2服务器/基础设施最低要求:1.在Malleable配置文件中禁用分段,如果启用,您的植入将几乎立即终止,因为有许多互联网范围的自动扫描程序下载第二阶段来分析和共享它。2.您必须使用具有许多不同重要绕过设置的自定义MalleableC2-Profile才能绕过某些检测。3、C2服务器前必须使用重定向器。此重定向器应释放/阻止已知的沙盒IP范围,并仅允许和重定向与MalleableC2配置文件匹配的请求。RedWarden或RedGuard是自动化此过程的最佳工具。使用它还可以避免在第一次连接后对CobaltStrike服务器进行指纹识别和检测。植入的最低要求:1.使用加密/混淆和运行时解密/反混淆打包shellcode。如果不这样做,加载程序将在磁盘或内存中签名(取决于加载方式);2.使用直接或间接系统调用来执行CS-Shellcode或从内存加载工件。如果不这样做,将导致在大多数环境中进行即时检测,因为shellcode始终具有相同的IoC,并且很容易被AV/EDR挂钩检测到。3.使用环境键控绕过潜在的沙箱或自动EDR云提交分析。4.您必须通过相关工具包修改CobaltStrike中默认的睡眠面具模板。如果在MalleableC2Profile中启用,信标将加密堆和堆栈内存,以便在成功执行后从内存扫描器中隐藏自己。但由于这个默认的睡眠面具源代码本身也受到AV/EDR签名的严重攻击,它也会被内存扫描器标记。您不应使用任何未经修改的公共Github睡眠加密代码,因为这也会被标记。所有这些(睡眠面罩修改除外)都可以使用完全自定义的打包器/加载器或使用相关工具包(ArsenalKit)来完成,它已经提供了大量样板代码。如果您打算使用ArsenalKit,您必须熟悉C/C++并大量自定义模板代码以绕过检测。睡眠掩码的修改也适用于原始shellcode输出,因此当您使用自己的自定义加载程序时,您甚至可以在ArsenalKit中修改它。但是,通过上述修改,MicrosoftDefenderforEndpoint在我的测试中仍然检测到很多恶意行为。注意:即使您应用了上述所有要求,您的植入物仍会在成熟环境中被检测到。根据目标环境中使用的EDR,这还不够。还有一些问题:如果你收到一个信标连接,不要以为你能找到任何东西。在许多环境中,我能够让Beacon运行,但在发出命令/模块后,植入程序立即被检测到并终止。正如我所说,CS可能是目前最复杂的框架,查看这些yara规则,您会发现供应商确实为每个命令/模块实施了检测规则。这些基于行为的检测让我个人只能使用CobaltStrike来启动一个反向的SocksConnection,而不能避免本地系统IoC,并且通过Socks来做网络上的所有事情。因此,在我的许多项目中,CobaltStrike或多或少成为了一个独立的socks5反向代理。对于自动AV/EDR分析,简单的内存加密可能没问题,但在这种情况下,您需要避免更多IoC,如RWX/RX内存权限,您不能使用Win32Sleep,因为这很容易被检测利用。在某些环境中,甚至在回调之前就会检测到我的Beacon/Process。老实说,我不知道这些监视器是干什么用的,老实说,我也不知道如何绕过它们。一些更有经验的CobaltStrike用户向我暗示,用户定义的反射加载器(UDRL)有几乎无限的可能性,例如TitanLdr。在成熟的环境中,通过可延展的配置文件选项调整CobaltStrike行为是不够的。例如,内核将始终使用Win32API(具有潜在的检测)而不是直接使用系统调用。直到有人将系统调用选项与更新集成在一起。但是使用UDRL,您还可以使用导入地址表挂钩修改所有CobaltStrike内核行为。例如,您可以将内核的HookVirtualProtect设置为NtProtectVirtualMemory。因此,由于CS内核本身的限制,它可能是坚持使用UDRL而不是使用自定义打包器/加载器或修改后的ArsenalKit的最隐蔽的方法。就我个人而言,这不再是一种选择。挂钩IAT会修改闭源程序的内核,以绕过基于行为的检测。在某些时候,我决定不为了让这个框架的c2连接正常工作而越来越深入地研究Windows内部结构,至少现在是这样。在一年的时间里,我只开发了很少的没有仪器的环境和一些带有反向Socks代理的环境,我决定使用其他框架。以前没有CS我很好,以后也会很好。真的需要这些旁路技巧吗?我不这么认为,所有这些绕过技术最终都只是用来绕过签名。如果您使用的是自行生成的shellcode,您可以选择再次坚持使用Win32API。WriteProcessMemory或CreateThread将导致检测输入参数和分析shellcode入口点。但如果没有已知的恶意签名,它会正常运行,不会被阻止。如果您使用的是内部工具或经过大量修改的开源代码,AMSI将永远不会检测到您,因为它正在搜索已知的签名。如果您使用的是经过混淆的开源C2框架或自行开发的框架,则内存扫描不会抓到您。本文翻译自:https:s3cur3th1ssh1t.github.io/Signature_vs_Behaviour///