Verifying the legitmacy of programs with PowerShell cmdlets

If you need to verify the authenticity or legimacy of a program on a Microsoft Windows system, e.g., if you need to check whether the program has remained unaltered since it was provided by the developer or check that it came from the developer it is purportedly from, you can use Windows PowerShell cmdlets to give you a greater degree of confidence.

Oftentimes a developer website will list a cryptographic hash code for a file. The cryptographic hash code allows you to verify that a program that you have on a system is an unaltered copy of the program as it was delivered by the developer, since changing even a single character/byte in a file will result in a different hash code being calculated for the file when it is checked by a program that can calculate hash codes for files. To calculate a cryptographic hash code for a file, you can use a program like md5sum or, on a Microsoft Windows system, you can obtain a SHA-256 hash code value for a file from a Windows PowerShell prompt using the Get-AppLockerFileInformation cmdlet.

PS C:\> help Get-AppLockerFileInformation


    Get-AppLockerFileInformation [[-Path] <List[string]>]  [<CommonParameters>]

    Get-AppLockerFileInformation [[-Packages] <List[AppxPackage]>]  [<CommonParameters>]

    Get-AppLockerFileInformation -Directory <string> [-FileType <List[AppLockerFileType]> {Exe | Dll |
    WindowsInstaller | Script | Appx}] [-Recurse]  [<CommonParameters>]

    Get-AppLockerFileInformation -EventLog [-LogPath <string>] [-EventType <List[AppLockerEventType]> {Allowed |
    Denied | Audited}] [-Statistics]  [<CommonParameters>]


    Get-Help cannot find the Help files for this cmdlet on this computer. It is displaying only partial help.
        -- To download and install Help files for the module that includes this cmdlet, use Update-Help.

PS C:\>

E.g., for the PuTTY putty.exe file:

PS C:\program files (x86)\putty> Get-AppLockerFileInformation putty.exe | Format-List

Publisher :
Hash      : SHA256 0xA58CC0D7A88656226CBC91C1A95E43CA971CD69C3FC004871078D2BB2CD20965
AppX      : False

PS C:\program files (x86)\putty>

The SHA256 code shown above is A58CC0D7A88656226CBC91C1A95E43CA971CD69C3FC004871078D2BB2CD20965; the 0x at the beginning of the hash code simply means that the number that follow are hexadecimal numbers. In this case the version of putty.exe on the system was an older version, 0.63. The current production version is 0.66 with a 0.67 beta version available. Though there is a link to sha256sums for the current version on the site, in a case like this where there is no longer a SHA256 code available for the older version of putty.exe on the PuTTY developer's website, you can still search for that hash code online to see if it has been linked to any malware. For PuTTY the developer, Simon Tatham, has a post on his web site stating:

2015-05-19 Malware pretending to be PuTTY

A Symantec blog post warns that a trojaned copy of PuTTY has been detected in the wild. Fortunately, it's easily recognisable by its version identification ("Unidentified build, Nov 29 2013 21:41:02"). If you've encountered this version, we suggest you treat any machine that's run the malicious version as potentially compromised, change any passwords that might have been stolen, and resecure the accounts they protect.

A Cisco Blogs posting by Chris Fry on May 18, 2015, Trojanized PuTTY Software, notes:

In late 2013­­­–early 2014, a compromised FTP client dubbed “StealZilla,” based off the open source FileZilla FTP client was discovered. The attackers modified a few lines of code, recompiled the program, and disbursed the trojanized version on compromised web servers. This new attack appears to involve the same actors who reused the same techniques to alter the source code of the widely used open source Telnet/SSH client, PuTTY, and used their network of compromised web servers to serve up similar fake Putty download pages. This new campaign is like the StealZilla campaign in almost every way. This trojanized version of PuTTY harvests credentials and relays the information back to a collection server in the same way too. The operation is very quick and quiet. Login details are sent to attackers using an HTTP GET connection ONLY once.

The primary mode of infection relies on users to search for PuTTY and follow a link to a fake mirror rather than the legitimate PuTTY page....

The article lists the SHA256 hash code for the trojanized version of putty.exe: d3e866e5bf18f2d9c667563de9150b705813e03377312b6974923f6af2e56291. So you could compare the SHA-256 code calculated by Get-AppLockerFileInformation putty.exe | Format-List against the SHA256 code for the modified version of putty.exe produced by the malware author.

For some applications, the cmdlet will reveal publisher information, e.g. for the WinSCP winscp.exe file.

PS C:\program files (x86)\WinSCP> Get-AppLockerFileInformation winscp.exe | Format-List

Hash      : SHA256 0x82E26BF7E973DB030543C035B94134F31C5FC2276D6EF17884738F7E4AC0CA0F
AppX      : False

PS C:\program files (x86)\WinSCP>

The Wikipedia article on WinSCP, which is produced by Martin Přikryl, notes regarding the origin of WinSCP:

Originally it was hosted by the University of Economics in Prague, where its author worked at the time.

So the publisher information above is not an unexpected value. If I was checking a program in C:\Windows\system or C:\Windows\system32 , I would expect to see a reference to Microsoft Corporation in the publisher information. If I didn't, I would be suspicious of the application:

PS C:\> Get-AppLockerFileInformation C:\Windows\system32\calc.exe | Format-List

Path      : %SYSTEM32%\CALC.EXE
Hash      : SHA256 0x0575206B04E78209CBE3F2AB7F3A5950966D3BAB7C1164C0D03316EC7103A085
AppX      : False

PS C:\>

There is also a Get-FileHash cmdlet which will return SHA1, SHA256, SHA384, and SHA512 hash codes, but you will need version 4.0 or later of PowerShell to have that cmdlet on your system. You can check the version of PowerShell on a system by obtaining a PowerShell prompt and typing $PSVersionTable.PSVersion.

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
3      0      -1     -1

PS C:\>

If you have version 4 or later of PowerShell, you can check the hash code as shown below. You can specify the SHA algorithm you wish to use, e.g. SHA1 as opposed to SHA256 by adding -Algorithm {SHA1 | SHA256 | SHA384 | SHA512}, selecting from SHA1, SHA256, SHA384, or SHA512. All but the first of those is a SHA-2 hash function.

PS C:\program files (x86)\winscp> Get-FileHash winscp.exe | Format-List

Algorithm : SHA256
Hash      : B561A14F20DF7143B6D625193C5C64F06E24C7626AA1E3DF94C52B458429A8EA
Path      : C:\program files (x86)\network\ssh\winscp\winscp.exe

PS C:\program files (x86)\winscp> Get-FileHash winscp.exe -algorithm SHA1 | Format-List

Algorithm : SHA1
Hash      : E2737A22558F5995ADE80376D564C9FEA55AE7E2
Path      : C:\program files (x86)\network\ssh\winscp\winscp.exe

PS C:\program files (x86)\winscp>

There are many types of hash codes. If you need an MD5 hash code, which is another commonly used hash code, instead, you can generate that checksum using a technique suggested by vcsjones at How to get an MD5 checksum in PowerShell. E.g.:

PS C:\> $theFile = "C:\Program Files (x86)\WinSCP\winscp.exe"
PS C:\> $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
PS C:\> $hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($theFile)))
PS C:\> echo $hash

You set the value of a variable you create, theFile, to contain the path and file name for the file you wish to check. Since the above code results in a hash code with a dash between each two hexadecimal digits, you can use -replace to remove the dashes - see PowerTip: Use PowerShell to Remove Characters in a String. Since most hash codes posted online do not have dashes in the code, that will put the code in a format that will more readily allow you to search for it online, if needed.

PS C:\> $hash = $hash -replace '[-]'
PS C:\> echo $hash
PS C:\>

If I wished to calculate the hash value for another file, I could then use the following commands:

PS C:\> $theFile = "C:\Program Files (x86)\PuTTY\putty.exe"
PS C:\> $hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($theFile)))
PS C:\> $hash = $hash -replace '[-]'
PS C:\> echo $hash
PS C:\>

Many programs for Microsoft Windows are digitally signed by the developer. If a program has a digital signature, you can confirm that a program you have on your system came from the developer and is not a fake or malicously altered version of a legimate program with the same file name.

A digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or documents. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, that the sender cannot deny having sent the message (authentication and non-repudiation), and that the message was not altered in transit (integrity).

You can Check the digital signature for a file under Microsoft Windows using PowerShell with the Get-AuthenticodeSignature cmdlet.

PS C:\> Get-AuthenticodeSignature C:\windows\system32\calc.exe | Format-List

SignerCertificate      : [Subject]
                           CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US

                           CN=Microsoft Windows Production PCA 2011, O=Microsoft Corporation, L=Redmond, S=Washington,

                         [Serial Number]

                         [Not Before]
                           8/18/2015 1:15:28 PM

                         [Not After]
                           11/18/2016 12:15:28 PM


TimeStamperCertificate :
Status                 : Valid
StatusMessage          : Signature verified.
Path                   : C:\windows\system32\calc.exe
SignatureType          : Catalog
IsOSBinary             : True

PS C:\>

In the above case, I can see that calc.exe is actually from Microsoft Corporation. And for winscp.exe, I can see that the copy I have on the system where I ran the check was signed by the Developer, Martin Prikryl.

PS C:\> Get-AuthenticodeSignature "C:\Program Files (X86)\WinSCP\winscp.exe" | Format-List

SignerCertificate      : [Subject]
                           CN=Martin Prikryl, OU=Individual Developer, O=No Organization Affiliation, L=Prague 2,
                         S=Prague, C=CZ

                           CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec
                         Corporation, C=US

                         [Serial Number]

                         [Not Before]
                           1/2/2016 7:00:00 PM

                         [Not After]
                           10/22/2016 7:59:59 PM


TimeStamperCertificate :
Status                 : Valid
StatusMessage          : Signature verified.
Path                   : C:\Program Files (X86)\WinSCP\winscp.exe
SignatureType          : Authenticode
IsOSBinary             : False

PS C:\>

But if I check the version of putty.exe on the system, I see it is not signed:

PS C:\> Get-AuthenticodeSignature "C:\Program Files (x86)\PuTTY\putty.exe" | Format-List

SignerCertificate      :
TimeStamperCertificate :
Status                 : NotSigned
StatusMessage          : The file C:\Program Files (x86)\PuTTY\putty.exe is not digitally signed. You cannot run this
                         script on the current system. For more information about running scripts and setting
                         execution policy, see about_Execution_Policies at
Path                   : C:\Program Files (x86)\PuTTY\putty.exe
SignatureType          : None
IsOSBinary             : False

PS C:\>

If you prefer, you can also have Get-AuthenticodeSignature prompt you for the file, or files, to be checked.

PS C:\> Get-AuthenticodeSignature

cmdlet Get-AuthenticodeSignature at command pipeline position 1
Supply values for the following parameters:
FilePath[0]: C:\Windows\System32\cacls.exe

    Directory: C:\Windows\System32

SignerCertificate                         Status                                 Path
-----------------                         ------                                 ----
E85459B23C232DB3CB94C7A56D47678F58E8E51E  Valid                                  cacls.exe

PS C:\


TechRabbit ad 300x250

Justdeals Daily Electronics Deals1x1 px