How to run RAW script in MS Defender Live Response
Introduction
Having experience working with CrowdStrike Real Time Response I looked for same approach for running RAW scripts (simply type and execute) in Microsoft Defender Live Response. In CrowdStrike we are having special console window designed to run our RAW script, looks like on below picture.
Scenarios where it can be useful are:
- check output representation before final deployment (sometimes it's returning PSObject, not well formatted like execution from our desktop)
- run quick command
- save output to custom location in specified format
I was expecting is to have same experience in Microsoft Defender Live Response, unfortunately there is no such way. According to Microsoft documentation there are predefined commands but in case of custom ones, you have to upload script file first and then execute. You can check official documentation or Microsoft docs on Github:
Workaround discovery
Knowing all these from MS documentation I had to find way to meet my requirement. Live Response sits on Windows PowerShell at time of writing this post. First idea was to execute powershell.exe from origin path on system and then custom command.
This shows that it's going to be not so easy and I cannot be lazy. I needed more knowledge how it works
behind scenes. Quick Google search and I found nice article showing how it basically works on
workstation where you attempting execute it. Highly recommend go through this article How to troubleshoot Live Response in Defender for Endpoint.
After reading above article I got knowledge that there is child process SenseIR.exe which performing all
Live
Response activities. Next idea was to upload script which will invoke my RAW script as one of parameter
directly from Live Response console, sound crazy but I really wanted achieve my goal (OnScreen is my
custom parameter added to print output directly on screen during tests).
Seems we have it, let's extend with pipe.
Ok error but I like errors which explaining something:
Error: Please avoid using the following characters as part of scripts' parameters: ; & | ! $ ( )
It's shows that there would be required placeholder for not allowed characters and format it correctly
inside script which will invoke it. After couple attempts I also realized that in Windows PowerShell
best placeholders would be ACII ones since other are not interpreted correctly.
Next issue discovered was regarding quotes how are interpreted by Windows PowerShell:
- single quote, mainly used for string literals
- double quote, mainly used for interpolated string and where escape characters and interpreted correctly
Sooner or later our RAW scripts would have spaces and making sure that full content would be interpreted as single parameter for execution we have to encapsulate it within quotes. Examples shows different output.
C:\> run paramtester.ps1 "-Name 'User One' -Age 99 -City OOO"
Name: User One
Age: 99
City: OOO
C:\> run paramtester.ps1 '-Name "User One" -Age 99 -City OOO'
Name: User
Age: 99
City: OOO
Knowing all of this, execution must be encapsulated within double and single quote at the beginning and single and double quote at the end.
C:\> run invoker5.ps1 "'Write-Host ''Hello'''"
Output: Hello
(NOTE! Double single quote around string Hello is required while nesting quotes inside quotes.)
Final script
It was harder than I was thinking while this idea came up. All errors forced me to escape somehow not allowed characters trying to keep code readable and also I added some other functionalities. But goal was achieved. Example test:
C:\> run msdefinvoker.ps1 "'Get-CimInstance Win32_OperatingSystem #P# Select-Object Caption, Version, BuildNumber, OSArchitecture'"
Transcript started, output file is C:\ProgramData\Microsoft\[REDACTED]
[ DEBUG ] Restored command: Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, OSArchitecture
Executing command: Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, OSArchitecture
@{Caption=Microsoft Windows Server 2022 Standard; Version=10.0.20348; BuildNumber=20348; OSArchitecture=64-bit}
[ OK ] Execution complete.
For more detailed usage and examples go on my GitHub. Also there is included converter so you don't have
to replace all characters manually. Feel free to contribute into this or ask me if needed.
Precaution words
Please make sure you are following best practices for scripts execution during Live Response usage:
- allowed personnel \ group able to do it
- enable signed script execution
- audit actions done via Live Response or create analytic rules
This concept was mainly created to quickly troubleshoot commands before final deployment. Make sure you are not exposing yourself or organization on risk.