Getting Started with WMI Weaponization – Part 6
Covert File Storage
Lets look at another practical example of weaponizing WMI using PowerShell. Earlier we went over how to create a custom WMI class. Using this class along with the Set-WmiInstance command we can create a class that we can then use to store files as Base64 Encoded strings.
To simplify this process, I created a module called Invoke-WMIFS.ps1. To start we will import the module:
PS C:\> Import-Module Invoke-WMIFS.ps1
This module provides the following functions:
- Get-WmiLength
- New-WmiClass
- ConvertTo-Base64
- ConvertFrom-Base64
- Invoke-InsertFile
- Invoke-RetrieveFile
To start, we use the function New-WmiClass to create a class that is preconfigured to store the files.
PS C:\> $ClassName = "WMIFS" PS C:\> New-WmiClass -ClassName $ClassName Path : \\.\root\cimv2:WMIFS RelativePath : WMIFS Server : . NamespacePath : root\cimv2 ClassName : WMIFS IsClass : True IsInstance : False IsSingleton : False PS C:\> Get-CimClass -ClassName $ClassName NameSpace: ROOT/cimv2 CimClassName CimClassMethods CimClassProperties ------------ --------------- ------------------ WMIFS {} {FileName, FileStore, Index}
This new class has three properties: FileStore, FileName, and Index.
We then use the function Get-WmiLength to retrieve the max length of a string that can be inserted into the class. This can vary somewhat and should be discovered each time.
PS C:\> $Length = Get-WmiLength -Verbose -ClassName $ClassName VERBOSE: Testing Length 8000 [TRUNCATED] VERBOSE: Testing Length 8143 Set-WmiInstance : Quota violation At C:\Invoke-WMIFS.ps1:19 char:27 + ... $Insert = Set-WmiInstance -Class $ClassName -Arguments @{ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Set-WmiInstance], ManagementException + FullyQualifiedErrorId : SetWMIManagementException,Microsoft.PowerShell.Commands.SetWmiInstance PS C:\> $Length 8143
In this test we are looking for WMI to throw a Quota Violation indicating the string is too long to be inserted.
In this example, we are inserting an executable file, and for this we use the ConvertTo-Base64 function.
PS C:\> $FileName = "payload.exe" PS C:\> $EncodedText = ConvertTo-Base64 -FileName $FileName -Verbose VERBOSE: Reading C:\Windows\System32\payload.exe VERBOSE: Encoding C:\Windows\System32\payload.exe VERBOSE: Finished Encoding C:\Windows\System32\payload.exe
Then to place the file into out WMIFS WMI class we use the Invoke-InsertFile function. This will slice the file into lengths predetermined by Get-WmiLength and place the chunks into the class we created.
PS C:\> Invoke-InsertFile -EncodedText $EncodedText -FileName $FileName -ClassName $ClassName -StrLen $Length -Verbose VERBOSE: Inserting Section: 0 to 8100 [TRUNCATED] VERBOSE: Inserting Section: 1927800 to 1935900
To later retrieve the file, we use the Invoke-RetrieveFile, which operates Invoke-InsertFile in reverse. It will retrieve the file from WMI and then reassemble it in order.
PS C:\> $File = Invoke-RetrieveFile -FileName $FileName -ClassName $ClassName -Verbose3 VERBOSE: Reading Section 0 (8100) [TRUNCATED] VERBOSE: Reading Section 238 (7468)
Then to write the file back to disk, we use the ConvertFrom-Base64 function.
PS C:\> ConvertFrom-Base64 -EncodedText $File -FileName 'C:\innocuous.pdf' -Verbose VERBOSE: Decoding File VERBOSE: Finished Decoding File VERBOSE: Writing File to Disk as C:\innocuous.pdf
Additionally, the option to use the pipeline and encrypt the file store is available. By default, it uses the current user’s certificate as the encryption key, but optionally a key can be explicitly specified.
PS C:\> ConvertTo-Base64 -FileName .\SuperSecret.pdf -Verbose | Invoke-InsertFile -FileName SuperSecret.pdf -ClassName WMIFS -Encrypt -Verbose VERBOSE: Reading .\SuperSecret.pdf VERBOSE: Encoding .\SuperSecret.pdf VERBOSE: Finished Encoding .\SuperSecret.pdf VERBOSE: Inserting Section: 0 to 1904 (0) VERBOSE: Inserting Section: 1904 to 3808 (1) VERBOSE: Inserting Section: 3808 to 5712 (2) VERBOSE: Inserting Section: 5712 to 7616 (3) ...
Later the file can be retrieved and decrypted.
PS C:\> Invoke-RetrieveFile -FileName SuperSecret.pdf -ClassName WMIFS -Decrypt -Verbose | ConvertFrom-Base64 -WriteToDisk -FileName .\SuperSecret.pdf VERBOSE: Reading Section 0 (7908) VERBOSE: Reading Section 1 (7908) VERBOSE: Reading Section 2 (7908) VERBOSE: Reading Section 3 (7908) ...
Explore more blog posts
Celebrating NetSPI’s Partners of the Year 2024
Congratulations to NetSPI’s 2024 Partner of the Year Recipients Defy Security, VLCM, Softcat, Enduir, Evotek, and AWS
Exploiting Second Order SQL Injection with Stored Procedures
Learn how to detect and exploit second-order SQL injection vulnerabilities using Out-of-Band (OOB) techniques, including leveraging DNS requests for data extraction.
CTEM Defined: The Fundamentals of Continuous Threat Exposure Management
Learn how continuous threat exposure management (CTEM) boosts cybersecurity with proactive strategies to assess, manage, and reduce risks.