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 NAME Get-AppLockerFileInformation SYNTAX 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>] ALIASES None REMARKS 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 Path : %PROGRAMFILES%\NETWORK\SSH\PUTTY\PUTTY.EXE 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 Path : %PROGRAMFILES%\WINSCP\WINSCP.EXE Publisher : O=NO ORGANIZATION AFFILIATION, L=PRAGUE 2, S=PRAGUE, C=CZ\WINSCP\WINSCP.EXE,5.7.0.5125 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 Publisher : O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US\MICROSOFT® WINDOWS® OPERATING SYSTEM\CALC.EXE,6.2.9200.16384 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 21-1D-89-F9-DF-FF-8B-D8-BC-A2-E1-0D-6F-CA-FC-82
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 211D89F9DFFF8BD8BCA2E10D6FCAFC82 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 7A0DFC5353FF6DE7DE0208A29FA2FFC9 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 [Issuer] CN=Microsoft Windows Production PCA 2011, O=Microsoft Corporation, L=Redmond, S=Washington, C=US [Serial Number] 33000000BCE120FDD27CC8EE930000000000BC [Not Before] 8/18/2015 1:15:28 PM [Not After] 11/18/2016 12:15:28 PM [Thumbprint] E85459B23C232DB3CB94C7A56D47678F58E8E51E 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 [Issuer] CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US [Serial Number] 0569BA5E24F30D60C6E204DD7543B9CB [Not Before] 1/2/2016 7:00:00 PM [Not After] 10/22/2016 7:59:59 PM [Thumbprint] 4A14668158D79DF2AC08A5EE77588E5C6A6D2C8F 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 http://go.microsoft.com/fwlink/?LinkID=135170 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 FilePath[1]: Directory: C:\Windows\System32 SignerCertificate Status Path ----------------- ------ ---- E85459B23C232DB3CB94C7A56D47678F58E8E51E Valid cacls.exe PS C:\