Monday, December 17, 2018

PowerShell and file hashes

Microsoft introduced a handy security cmdlet in PowerShell 4; the Get-FileHash cmdlet is very useful for validating the integrity of a file provided you know the hash value of the ‘known good’ version. A hash is essentially a sequence numbers and letters that are calculated using a function, such as SHA256 or SHA384 using (in this case) a file as input.

As an example, let’s say that I build a software application, widget.exe. I run the SHA384 hashing function on it and come up with 38A519CE7. (A real value would be much longer.) If even a single bit changes in widget.exe, the hash value would change the next time the was calculated. I post my widget.exe program on my web site and I also include a note saying that the SHA384 has is 38A519CE7.

Assuming you trust me as a source for software, you download my program and compute the hash value of widget.exe using the SHA384 algorithm. If the value you calculated is not 38A519CE7, then something is amiss. Maybe I posted a new build of widget.exe and did not update the new hash value. Maybe it was corrupted during download. Or, maybe someone modified my program and included hostile code.

Calculating a hash value and checking it against a known-good value is a simple, easy way to verify the integrity of a file, whether the file is a simple text file, spreadsheet, script, executable, or binary. By themselves, security experts will tell you that they are not a 100% perfectly secure solution. After all, if I can modify your software, I can also try and find where you keep your ‘known good’ hashes, recalculate the hash value, and modify your list of known good hashes.

Is the Get-FileHash command available to you? Using the $PSVersionTable variable in PowerShell and make sure you are running at least v4.0. A word of caution, though, you may have scripts written that will only work with earlier versions of PowerShell, so do your homework before updating to new versions of PowerShell.

Let’s go through an example. I have a file in the c:\temp folder called Get-IthicosSystemInfo.PS1. I want be able to detect if changes have occurred that I did not make. I’m going to use the SHA384 hash algorithm since it is a newer, modern, and more secure algorithm. If you do not specify the -algorithm option, then Get-FileHash will use SHA256. If the file hash will be calculated on other operating system platforms, make sure that the other platforms support the hash you will choose. I would type this command at the PowerShell command prompt:
Get-FileHash .\Get-IthicosSystemInfo.ps1 -Algorithm sha384

The Get-FileHash cmdlet will return the hash algorithm used, hash calculated, and the file path. The hash value is actually too wide, so I’ll do a little bit of PowerShell magic to set the hash information as a variable:
$filehash = Get-FileHash .\Get-IthicosSystemInfo.ps1 -Algorithm sha384

Then I can just type $filehash.hash, like so:
PS C:\temp> $filehash.hash


Awesome! I’m almost done. Now, I’ll take that hash code, copy it and paste it in to a JimsHashCodeKnownGoodValues.txt file and save it to the C:\temp folder with the script. Hurray! My script is protected and I can sleep well at night.

Some of you are probably saying to yourself, “Self, if an intruder can get to the temp folder and modify the script, well, the ‘known-good’ values file is right there next to the script...” You would be correct. I should store my known-good hash values in a different place. Of course, I need to apply restrictive NTFS permissions on to my script so that only a small group of trusted admins can edit it. And, if the script is edited, a new hash value needs to be calculated.

At some point in the future, if I want to validate that they script has not been modified, I’ll simply run the Get-FileHash command again using the same hashing algorithm. If the hash value is the same, the file has not been modified.

Using hashes to verify file integrity should never be the only security tool in your arsenal but they can provide you with an additional layer of security for validating file integrity. In another article, I’ll discuss digitally signing code and how that can provide you with a higher level of assurance.

Labels: , ,