In my previous post on Kansa's automated analysis, I mentioned there was another improvement I made to the framework that I would cover in a future post. I thought at that time, that Kansa was at a point where I could go into some details about the new feature, but as it turns out, it wasn't quite ready.
Previously, some of Kansa's collector modules would need to be edited or customized prior to being run. Disk\Get-File.ps1, for example, was one that could acquire a specific file from target machines, but users would have to edit the collector to specify the file they wanted to acquire. Obviously that was less than ideal, so I did some work that would allow users to specify those kinds of things via command line arguments. In my limited testing, this worked... but, my testing was limited.
This week I had a pull request submitted by @z4ns4tsu for a collector module called Get-FilesByHash.ps1 that would allow investigators to take a cryptographic hash (MD5, SHA1, etc.) of a known suspect file, then search for files with that same hash across many machines in the environment. The module was the first that would take multiple arguments, the search path, the hash and the hash type; this is where Kansa had an issue. It couldn't pass multiple arguments to collectors, but after a couple nights of work, now it can.
I also added a few arguments to Get-FilesByHash.ps1, including a file extension regex so the script doesn't hash every single file looking for matches, instead, it will only hash those files with extensions that match the provided file extension regex, the default regex is \.(dll|exe|ps1|sys)$, this greatly reduces the number of files that will be hashed. I also added two more arguments that limit the files that will be hashed based on minimum and maximum file size in bytes.
Here's a command line example showing how this module can be used:
.\Kansa.ps1 -ModulePath ".\Modules\Disk\Get-FilesByHash.ps1 BF93A2F9901E9B3DFCA8A7982F4A9868,MD5,C:\Windows\System32,\.exe$" -target localhost -Verbose
Above Get-FilesByHash.ps1 will search for any files with the MD5 hash of BF93A2F9901E9B3DFCA8A7982F4A9868, in or below the C:\Windows\System32 path and ending with an extension of .exe., Notice that the arguments to Get-FilesByHash.ps1 are not named parameters. Named parameters are not supported for remoting, so they must be positional also note that they are comma separated and the whole module and arguments are quoted.
As with other modules, you can use the .\Modules\Modules.conf file to pass arguments to Get-FilesByHash.ps1 (or any other module that takes arguments) via the conf file itself. Here's the entry for the module above taken from the conf file:
Disk\Get-FilesByHash.ps1 BF93A2F9901E9B3DFCA8A7982F4A9868,MD5,C:\Windows\System32
Note the absence of quotes in the configuration file, and I've also omitted the regex extension argument.
Adding the ability to pass parameters to modules meant I could remove several collectors from Kansa that were written to acquire specific event logs, each one collecting a specific log file, instead, now Kansa has one collector written to generically collect any Windows event log and the specific log is simply passed as an argument. Here's the relevant section of the .\Modules\Modules.conf file:
Log\Get-LogWinEvent.ps1 Security
Log\Get-LogWinEvent.ps1 Microsoft-Windows-Application-Experience/Program-Inventory
Log\Get-LogWinEvent.ps1 Microsoft-Windows-Application-Experience/Program-Telemetry
Log\Get-LogWinEvent.ps1 Microsoft-Windows-AppLocker/EXE and DLL
Log\Get-LogWinEvent.ps1 Microsoft-Windows-AppLocker/MSI and Script
Log\Get-LogWinEvent.ps1 Microsoft-Windows-AppLocker/Packaged app-Deployment
Log\Get-LogWinEvent.ps1 Microsoft-Windows-Shell-Core/Operational
Log\Get-LogWinEvent.ps1 Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
Log\Get-LogWinEvent.ps1 Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational
Log\Get-LogWinEvent.ps1 Microsoft-Windows-Application-Experience/Program-Inventory
Log\Get-LogWinEvent.ps1 Microsoft-Windows-Application-Experience/Program-Telemetry
Log\Get-LogWinEvent.ps1 Microsoft-Windows-AppLocker/EXE and DLL
Log\Get-LogWinEvent.ps1 Microsoft-Windows-AppLocker/MSI and Script
Log\Get-LogWinEvent.ps1 Microsoft-Windows-AppLocker/Packaged app-Deployment
Log\Get-LogWinEvent.ps1 Microsoft-Windows-Shell-Core/Operational
Log\Get-LogWinEvent.ps1 Microsoft-Windows-TerminalServices-LocalSessionManager/Operational
Log\Get-LogWinEvent.ps1 Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational
Above we have a single collector, Log\Get-LogWinEvent.ps1, that replaced nine collectors because it accepts an argument specifying which log to collect.
As you can see, being able to pass command line arguments to collectors is a big benefit, just be mindful that they are positional, not named parameters and as a result, if you want to accept all the default arguments but the last one, you still have to specify every argument, supplying the default values for every argument except the one you want to modify.
You can find more information about Kansa and the latest release at https://github.com/davehull/Kansa/releases.