1, User Account Control (UAC)
2, PowerShell (scripts, interactive use, and dynamic code calculation)
3, Windows Script Host (wscript.exe and cscript.exe)
4, JavaScript and VBScript
5, Office VBA macros
For engineers and defenders engaged in security defense detection, as well as for attack researchers interested in mature evasion techniques, I have raised the following questions for everyone:
1, Which actual PE files are associated with the components supported by AMSI?
2, Is the information provided by Microsoft accurate, or are there any missing components in the above list?
3, Can AMSI be used without registering the AMSI program as a terminal security provider?
AMSI component enumeration
To solve the first two problems, we need to figure out a way to automatically identify and discover AMSI components. The entire process involves a series of EXE or DLL files that contain the ASCII or Unicode string 'amsi.dll'. So why search for the 'amsi.dll' string?
1, amsi.dll can provide functions required for scanning buffer, that isAmsiScanBuffer,AmsiScanStringand AmsiUacScan.
2, This string means that EXE or DLL will be statically imported (for example, it can be stored in the PE file in the form of an ASCII string) or dynamically loaded at runtime (for example, it can be stored in the PE file in the form of a Unicode string) as amsi.dll.
The following PowerShell code may help answer our questions:
$UserPEs = Get-CimInstance -ClassName CIM_DataFile -Filter 'Drive = "C:" and (Extension = "exe" or Extension = "dll")' -Property 'Name' | Select -ExpandProperty Name
$AMSIReferences1 = $UserPEs | % { Select-String -Encoding ascii -LiteralPath $_ -Pattern 'amsi\.dll' }
$AMSIReferences2 = $UserPEs | % { Select-String -Encoding unicode -LiteralPath $_ -Pattern 'amsi\.dll' }
$AMSIReferences1.Path
$AMSIReferences2.Path
The above PowerShell code snippet uses WMI to enumerate all EXE and DLL files. The reason for choosing this method over Get-ChildItem is that it may throw exceptions when trying to access files it does not have permission to access.
Next, it will use Select-String (equivalent to grep in PowerShell) to scan each file and search for ASCII and Unicode text strings - 'amsi.dll' within the files.
After filtering the results, the following AMSI components were found:
1, %windir%\System32\consent.exe
2, %windir%\System32\jscript.dll
3, %windir%\System32\vbscript.dll
4, %windir%\System32\wbem\fastprox.dll
5, %windir%\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
6, %windir%\Microsoft.NET\Framework64\v4.0.30319\clr.dll
7, %ProgramFiles%\WindowsApps\Microsoft.Office.Desktop_16051.11929.20300.0_x86__8wekyb3d8bbwe\VFS\ProgramFilesCommonX86\Microsoft Shared\VBA\VBA7.1\VBE7.DLL
After studying, we classify the aforementioned AMSI components according to the documents provided by Microsoft:
1, User Account Control: consent.exe
2, PowerShell: System.Management.Automation.dll
3, JavaScript and VBScript: jscript.dll, vbscript.dll
4, Office VBA Macro: VBE7.dll
5, Unclassified: clr.dll, fastprox.dll
So, what are these unclassified AMSI components? 'clr.dll', which is the Common Language Runtime, mentioned by Microsoft in .NET 4.8, scans the compiled loads in memory. Researchers are already studying related bypass mechanisms, see the references at the end of this article. Next, we will analyze 'fastprox.dll', please be patient.
WMI and AMSI
The 'fastprox.dll' is located in the 'System32\wbem' directory, and the description of 'fastprox.dll' is 'WMI Custom Marshaller', which is self-explanatory and clearly related to WMI. To further verify, we can use PowerShell to identify which process the 'fastprox.dll' is loaded with:
> Get-Process | Where-Object { $_.Modules.ModuleName -contains 'fastprox.dll' }
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ ---- -- -----------
2196 274 219988 232044 14,573.92 1192 5 chrome
1162 47 85544 38524 803.86 14580 5 mmc
692 42 129920 55564 1,081.20 2408 5 powershell
874 47 77144 87852 73.48 4040 5 powershell
686 39 71132 42608 42.78 12620 5 powershell
229 13 2596 10072 0.13 2956 0 svchost
480 20 3840 6728 69.66 3376 0 svchost
613 34 26776 17356 4,370.64 3648 0 svchost
217 43 2572 4148 18.64 6728 0 svchost
564 33 11276 16544 4.34 11520 0 svchost
129 7 1496 2196 0.77 5232 0 unsecapp
1650 67 318004 256536 99.28 16576 5 vmconnect
898 29 62664 23660 1,267.36 4776 0 vmms
386 16 8492 13408 21.77 14220 0 WmiPrvSE
176 10 2684 8592 1.36 15772 0 WmiPrvSE
We can use the following PowerShell command to parse the services corresponding to the svchost.exe process:
> Get-Process | Where-Object { $_.Modules.ModuleName -contains 'fastprox.dll' -and $_.ProcessName -eq 'svchost' } | ForEach-Object { Get-CimInstance -ClassName Win32_Service -Filter "ProcessId = $($_.Id)" } | Format-Table -AutoSize
ProcessId Name StartMode State Status ExitCode
--------- ---- --------- ----- ------ --------
2956 Netman Manual Running OK 0
3376 iphlpsvc Auto Running OK 0
3648 Winmgmt Auto Running OK 0
6728 SharedAccess Manual Running OK 0
11520 BITS Auto Running OK 0
It seems that any process that wants to interact with WMI needs to use this DLL. Now, we directly examine the code to determine how fastprox.dll interacts with amsi.dll. Currently, the only 'amsi.dll' reference appears in the JAmsi::JAmsiInitialize function, and the following is the relevant code:
Firstly, the AMSI will be initialized only when the current process is not %windir%\System32\wbem\wmiprvse.exe. After calling loadlibrary in amsi.dll and parsing the required related export functions (such as amsiscanbuffer), we find that the unique cross-reference of amsiscanbuffer is the JAmsi::JAmsiRunScanner function:
JAmsiRunScanner is called by JAmsi::JAmsiProcessor, and this function will be called by the following functions:
1, CWbemSvcWrapper::XWbemServices::ExecNotificationQueryAsync
2, CWbemSvcWrapper::XWbemServices::CreateInstanceEnum
3, CWbemSvcWrapper::XWbemServices::ExecQueryAsync
4, CWbemSvcWrapper::XWbemServices::ExecQuery
5, CWbemSvcWrapper::XWbemServices::CreateInstanceEnumAsync
6, CWbemSvcWrapper::XWbemServices::GetObjectW
7, CWbemSvcWrapper::XWbemServices::ExecMethod
8, CWbemSvcWrapper::XWbemServices::ExecMethodAsync
9, CWbemSvcWrapper::XWbemServices::ExecNotificationQuery
10, CWbemSvcWrapper::XWbemServices::GetObjectAsync
11, JAmsi::JAmsiProcessor (called by CWbemInstance::SetPropValue)
Except for the last function, the other functions correspond toIWbemServices interfaceThe method implemented, while the last function is likely to correspond toIWbemClassObject::PutMethod.
Next, we need to run logman to capture all AMSI events and try to capture related WMI events:
logman start trace AMSITrace -p Microsoft-Antimalware-Scan-Interface (Event1) -o amsi.etl -ets
Next, run the following code to trigger the event test:
$CimSession = New-CimSession -ComputerName .
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine = 'notepad.exe'} -CimSession $CIMSession
$CIMSession | Remove-CimSession
The above command can create a local CIM session to enumerate remote WMI connections, stop event capture after completing WMI interaction:
logman stop AMSITrace -ets
Next, use PowerShell to identify any WMI events:
> $AMSIEvents = Get-WinEvent -Path .\amsi.etl -Oldest
> $AMSIEvents[5] | Format-List *
Message: AmsiScanBuffer
Id: 1101
Version: 0
Qualifiers:
Level: 4
Task: 0
Opcode: 0
Keywords: -9223372036854775807
RecordId: 5
ProviderName: Microsoft-Antimalware-Scan-Interface
ProviderId: 2a576b87-09a7-520e-c21a-4942f0271d67
LogName:
ProcessId: 7184
ThreadId: 8708
MachineName: COMPY486
UserId:
TimeCreated: 10/3/2019 12:14:51 PM
ActivityId: 95823c06-72e6-0000-a133-8395e672d501
RelatedActivityId :
ContainerLog : c:\users\testuser\desktop\amsi.etl
MatchedQueryIds : {}
Bookmark : System.Diagnostics.Eventing.Reader.EventBookmark
LevelDisplayName : Information
OpcodeDisplayName : Info
TaskDisplayName :
KeywordsDisplayNames : {}
Properties : {System.Diagnostics.Eventing.Reader.EventProperty, System.Diagnostics.Eventing.Reader.EventProperty...}
> $AMSIEvents[5].Properties
Value
-----
0
1
1
WMI
300
300
{67, 0, 73, 0...}
{131, 136, 119, 209...}
False
> [Text.Encoding]::Unicode.GetString($AMSIEvents[5].Properties[7].Value)
CIM_RegisteredSpecification.CreateInstanceEnum();
Win32_Process.GetObjectAsync();
Win32_Process.GetObject();
SetPropValue.CommandLine("notepad.exe");
> Get-CimInstance -ClassName Win32_Service -Filter "ProcessId = $($AMSIEvents[5].ProcessId)"
ProcessId Name StartMode State Status ExitCode
--------- ---- --------- ----- ------ --------
7184 WinRM Auto Running OK 0
Firstly, the sixth event (index 5) is the only one that contains the attribute value “wmi” among the four attribute values. Additionally, the eighth attribute value contains binary data that looks like a Unicode string. After decoding, it reflects the execution of win32_process create in the above example. It is worth noting that the recorded process ID-7184 is the source of the AMSI event, which is a svchost.exe process.
WMI is very “messy”, the operating system regularly uses WMI for legitimate operations, and suspicious operations also involve WMI, and many WMI operations are not recorded. The reason behind this is obvious, because only when JAmsi::JAmsiIsScannerNeeded returns TRUE, JAmsi::JAmsiRunScanner will execute.
The operation context string of WMI has a specially calculated CRC checksum, and only when the checksum matches the value in the whitelist will the WMI event be recorded:
During the research process, we found that the whitelist contains the following CRC checksums:
0x788c9917, 0x96b23e8a, 0xb8da804e, 0xc0b29b3d, 0xd16f4088, 0xd61d2ea7, 0xef726924, 0x46b9d093, 0xf837efc3
It is obvious that as long as the attacker can recover the checksum in the whitelist, they can bypass the operating system's records of WMI operations. The next result, I believe everyone knows!
Summary
The method introduced in this article can be used to identify AMSI components, study their implementation (using WMI as an example), and infer context based on AMSI ETW events. This method is very effective for attackers trying to bypass AMSI detection.
Reference materials
1、https://twitter.com/mattifestation/status/1071034781020971009
2、https://modexp.wordpress.com/2019/06/03/disable-amsi-wldp-dotnet/
* Reference source:specteropsFB editor Alpha_h4ck compiled, please indicate the source as FreeBuf.COM when转载

评论已关闭