Almost all thick client applications need to update themselves. This is the only way to distribute newer functionality and bug fixes. The updated executables are usually downloaded on the client from the company’s servers. In the past, there have been cases where this “updater” functionality has been found to be insecure. Using a man-in-the-middle attack, an attacker could, on the network, replace the intended update executables with fake malicious executables and get them to run on the victim’s machine. To prevent such an attack, thick client applications usually verify the signature on any downloaded executables before running them.
Moving slightly off-topic (from web applications), in this post I will consider a thick client application that implements the crypto in this “updater module” incorrectly.
Consider a thick client application owned by a fictitious company called “Contoso”. On loading, this application checks to see if a newer version is available. It does so by calling a web service. The web method “GetLatestVersion” returns the latest version available. If this is greater than the currently running version, the application calls another web method to get the URL of a zip file containing the latest executables. It then downloads this zip file, unzips it and runs the executables inside.
To mitigate the threat of an attacker mounting a man-in-the-middle attack and replacing this zip file, this application performs a verification step before running the executables inside.
The updated executables are signed using Authenticode technology . To verify that these executables are signed by “Contoso”, the application extracts the signing certificate from the executable using X509Certificate.CreateFromSignedFile . It then verifies that the certificate had not expired when the file was signed, verifies the entire certificate chain, that the root certificate is trusted on the client, that none of the certificates in the chain have been revoked and that the signing certificate has been issued to “Contoso”.
The developers are now content that this “updater” functionality is secure and that no attacker can create a file that can bypass this verification.
When in fact, this verification is flawed! It is flawed since the verification step does not verify if the signature on the signed file is still valid. It simply extracts the signing certificate and extensively verifies it.
An attacker could take a valid executable signed by “Contoso”, tamper it, and pass it on. This would invalidate the signature, but the signing certificate would still be valid.
A good way to verify the signature on a signed executable is to use the “WinVerifyTrust” API . This is the same API that Internet Explorer uses for signature verification before running a downloaded executable. This API verifies the signature, the certificate used to sign the executable and has various options to configure revocation checks etc.
The only additional check the application needs to perform is to verify that the signing certificate has been issued to its own organization.
 Hot or not: Software update vulnerabilities
 Lenovo SystemUpdate SSL Certificate Issuer Spoofing Vulnerability
 Extracting Digital Signatures from Signed Files with .NET
 Example C Program: Verifying the Signature of a PE File
Vulnerabilities in Web Applications due to improper use of Crypto – Part 1 & Part 2
Security Engineer, ACE Team