PSScriptPolicyTest Files

There is an often-referenced article here that lays out what these files look like, what they do, and where they originate. From the perspective of trying to identify them however, it was a bit out of date, and nobody really goes over everything that these files can contain. I'm not going to dive into what these files do, but I do want to put something out there with more information on the contents, and show one way to identify malicious script files.

These files appear to have previously contained simply the number 1 and would have had a sha2 256 hash of 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b. At one point they contained the phrase # PowerShell test file to determine AppLocker lockdown mode , which would have a consistent file hash of 96ad1146eb96877eab5942ae0736b82d8b5e2039a80d3d6932665c1a4c87dcf7. This seems odd to me, note the <space> at the end of that string. I have observed this "in the wild" though, without a timestamp, so it's not an error. Currently this no longer appears to be the case. As of 9 Jun 2021 / Windows 10 20H2 Build 19042, the files have a string such as PowerShell test file to determine AppLocker lockdown mode 6/9/2021 15:15:08. Same phrase, but they are now date/time stamped. But wait, it gets better! Different versions of Windows 10 apparently use 24-hour time and AM/PM time!

Every time a new PSScriptPolicyTest file is written it is going to have a different timestamp, and thus a different hash.  We can no longer allow or block these files based on hash. Can we at least tell if they are legitimate?

To find out, I captured one of these files, __PSScriptPolicyTest_d5qbrf5a.j4m.ps1 with a hash of 920d58097771774f43bcf72a1f8fe7039fbe3017a7d46739daa3750230693ac9. The date/time stamp in the hash is 6/9/2021 15:15:08

This was also captured by syslog and ingested into Splunk, note the timestamp is the same as that in the script, 15:15:08.

Sysmon doesn't give me a hash, but we have other tools in our enterprise that do. So maybe we can write something that automatically takes a string, appends a timestamp, calculates a hash, and then compaires that hash against the one that was logged to determine if this is the real thing? Let's start by testing our theory.

To do so, I used Hashcat to calculate these hashes. After all, we have a hash, we have a slightly changing string, and Hashcat is great at turning strings into hashes! So I cracked all of my script test files!

This is where I found out there were two different types of date/time stamps, THANKS MICROSOFT! The 24-hour version above, and a 12-hour AM/PM version that looks like PowerShell test file to determine AppLocker lockdown mode 10/17/2019 3:28:29 PM

I'll save you the results of a ton of testing and command line output. Here's the hashcat command:

hashcat.exe -a 3 -m 1400 --remove --markov-disable --outfile-autohex-disable hashes\sha256.txt masks\powershell.hcmask

*Note above the --outfile-autohex-disable. Because the resulting string contains a :, and hashcat uses : as a delimiter in it's potfile, it will default to writing the results to a potfile as $HEX[<hexstring>]. You can take the hex string and decode it to see the result, or have it disable the autohex. Disabling the autohex will probably screw up things like the --show command. Also, the --remove will remove the cracked hashes from the sha256.txt file, so you will be able to easily recognize any remaining/uncracked hashes.

This is assuming your hashes are stored in .\hashes\sha256.text. The contents of the powershell.hcmask file are below. This could be optimized a bit for speed, e.g. the year is only likely to be ~2017-2021. However, we end up checking 2000-2029. We could duplicate a lot of lines and use static numbers, but the runtime is under about a minute per line so ¯\_(ツ)_/¯.

012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode ?d/?d/20?1?d ?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode ?d/?2?d/20?1?d ?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode 1?1/?d/20?1?d ?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode 1?1/?2?d/20?1?d ?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode ?d/?d/20?1?d ?3?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode ?d/?2?d/20?1?d ?3?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode 1?1/?d/20?1?d ?3?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode 1?1/?2?d/20?1?d ?3?d:?3?d:?3?d ?4M
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode ?d/?d/20?1?d ?3?d:?3?d:?3?d
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode ?d/?2?d/20?1?d ?3?d:?3?d:?3?d
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode 1?1/?d/20?1?d ?3?d:?3?d:?3?d
012,123,0123456,AP,# PowerShell test file to determine AppLocker lockdown mode 1?1/?2?d/20?1?d ?3?d:?3?d:?3?d
\# PowerShell test file to determine AppLocker lockdown mode 
1

One weird thing of note:

There was a single script test file associated with a hash that I -couldn't- crack. The hash of this file comes back as: 5b6fb58e61fa475939767d68a446f97f1bff02c0e5935a3ea8bb51e6515783d8

A VirusTotal check of this showed that it wasn't malicious, but was associated with an odd number of names and sources. I grabbed the file from one machine that had it and checked the contents to find...

My assumption is that something went sideways in the creation of the scriptpolicytest file for it to end up like this, and that this is neither  malicious, nor a proper creation of a script test file. I did see this more than once though, so you might see it in your environment as well.

Wrapping up

In summary, these files should contain one of:
1
# PowerShell test file to determine AppLocker lockdown mode
# PowerShell test file to determine AppLocker lockdown mode %m/%d/%Y %H:%M:%S
# PowerShell test file to determine AppLocker lockdown mode %m/%d/%Y %I:%M:%S %p
I used C standard format codes above, just for illustration, but note that Hour is only zero-padded in 24 hour time, NOT 12 hour time. Neither day, nor month, is zero-padded. Minutes and seconds are zero-padded.

A large number of these files appear to remain around for several years, rather than being removed right away. I looked at all hashes in my environment over the last 30 days, which resulted in 523 unique hashes. The oldest date I found in the string timestamp was 5/9/2018. So unfortunitly, it doesn't look like I can use the runtime timestamp to calculate a hash and check these files on the fly. However, with the help of Hashcat, I can now dump them periodically, "crack" them, and look for anything out of place.