“Windows PowerShell is a Windows command-line shell designed especially for system administrators. Windows PowerShell includes an interactive prompt and a scripting environment that can be used independently or in combination.” – Microsoft
PowerShell has been around for some time and is often used by sysadmins to automate tasks or to remotely manage systems. It comes inbuilt within Windows so if you login to you Windows server or client, you will see it. As with everything, it was created for good but is being used for bad.
The reason why is simple; It’s powerful and is already there. If an attacker gained access to your machine, they would be somewhat restricted. The system they land on would often have an Anti-virus installed or some level of security policies/controls in place. Should the system be connected to a corporate network, they may face even more restrictions as their traffic may be restricted/inspected through Firewalls or Proxies.
Downloading malicious tools may also alert the security team should the AV spot them. They could try and trick you remotely (Phishing/USB dropper) by hidding malware inside of a genuine file however this may also be flagged by your AV.
This is why certain malicious parties are using techniques such as “Living of the land” and Fileless malware.
These techniques use the inbuilt system tools already installed on the machine in order to carry out malicious attacks. Your antivirus is not going to flag PowerShell running basic commands as it’s a legitimate tool developed by Microsoft. Because of this, an attacker can run reconnaissance or run malicious code. This can either be done locally or due to automation, remotely.
There are some of the more well known PowerShell tools which are often used by hackers today (Good or bad):
- Mimikatz (dogz, yakz etc…)
These tools can harvest credentials, steal data or wreak havoc on your network.
Microsoft have been improving PowerShells security capabilities over the last 10 years or so however, PowerShell is a double edged sword. Another problem is that these controls aren’t enabled by default therefore can go unchecked.
For instance, if you are running Windows 10 with PowerShell V5 installed, you will have the option to enable all of the new fancy features. This is because the latest versions has far better logging capabilities and inbuilt security policies that can help prevent against the above attacks. If it doesn’t prevent, it can at least give you a chance to understand what has gone on due to the level of logging.
All of this is pointless however if you still have V2 enabled. The reason why is that attackers can downgrade PowerShell to version 2, so that they leave less of a footprint and evade detection. Version 2 doesn’t have all the bells and whistles and is therefore the devils choice.
You can easily test if you have V2 installed by loading PowerShell and running:
powershell -v 2
If within the same console, it loads, you have this feature enabled:
To disable through PowerShell:
Client: Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root
Server: Disable-WindowsFeature PowerShell-V2
Although deprecated Microsoft still enabled this by default for backwards capabilities reasons. The version itself isn’t a threat however you have to accept the fact that version 2 has simple logging capabilities which may not give your security team any indication of post exploitation. It’s more beneficial to either limit or remove the version to enforce better protection.
bare in mind, unless heavily locked down, PowerShell won’t be able to prevent Mimikatz from running so you will need to help from your anti-virus endpoint.
What it does give you is more of an insight should you go threat hunting or need to investigate an attack. Below are just some of the logging features which when enabled can help. If these are forwarded to your SOC or SIEM, they can be used to alert on any suspicious activity.
All the below can be enabled via group policy:
Module Logging (Win-Event ID 4103)
This will record all execution details of PowerShell modules ran. You can enable only a few Modules such as the example given; Microsoft.PowerShell.* however, you can also log everything using *
Script Block Logging (Win-Event ID 4104,4105,4106)
This records all lines of code as they are executed by PowerShell. The stop/start events are optional and if enable may create a large volume of logs so bare that in mind.
If you wished to check all of this and more, I’ve written a module which can help identify the status of the above and any suspicious activity.
It will first check the status of PowerShell and if V2 is enabled. If so, it will check for any history of downgrading using PSReadLine. The PSReadLine history is enabled by default on the latest Windows 10 images.
It will then check your auditing which are the logging policies mentioned above:
It will then check PSReadLine for any known scripts or module such as Mimikatz and then search for past invoke commands:
It will then finish by checking Windows events for the logging mentioned above:
The whole script or Module can be found here: https://github.com/securethelogs/Bluechecker
These will give you better auditing however, restricting PowerShell completely will help protect against PS attacks. Remember that PowerShell doesn’t just run locally. It can also run scripts and commands remotely using the WinRM service which is enabled by default.
I’ve also created a Module which can help scan for the WinRM service. WinRM Scanner can also use the service to brute-force credentials should you wish to test it out.
Should you want the simple option of checking and connecting to a remote machine, you can use the following as a template: https://github.com/securethelogs/Powershell/blob/master/RemoteWinRM.ps1
If you are wanting to restrict or disable remote PowerShell, you can do the following via GP. Within Computer Policies > Administrative Templates > Windows Components >Windows Remote Management (RM) you will see Allow remote server management through WinRM as well as a few more, which you should consider. Inside of this policy will be the option to restrict based on source. This is something you can also do quite simply using the Windows Firewall. Create a rule that only accepts 5985 (http) and 5986 (https) from your trusted source.
Should you leave it open or on the defaults, it could be an attackers way in. The reason why is because it allows them to execute PowerShell scripts remotely without having to be on the server. They could either run Enter-PSSession or Invoke-Command.
If you think that they won’t be able to execute certain commands or executables without admin privilege you would be correct however, executing malicious code isn’t all that attackers do. Take this line of code for example:
dsquery user -name *smith* | dsget user -email >> C:\Temp\emails.txt
This will query the domain for all users with Smith in them and pipe their email into a text file. You may think, ohh well but imagine if they used: admin, service, root or simply *. This would give them all of your email addresses and will certainly not be flagged by your AV.
Net group “domain admins” /domain >> C:\Temp\admins.txt
This will list all of the domain admins within the domain and their usernames. As you can see pretty powerful stuff and the worst part…..that didn’t need admin rights.
These commands can be ran as a user as long as they can reach a domain controller (Network). I’ve covered more Recon commands here: https://securethelogs.com/2019/08/20/windows-shell-discovery-stage/
If PowerShell wasn’t on your radar, it will hopefully be on there now. PowerShell is a…well…..powerful tool however its trusted by default which makes it very dangerous.
I will most likely do a second part which will show how the malicious PowerShell scripts/modules work…..