Today we released MS13-098, a security update that strengthens the Authenticode code-signing technology against attempts to modify a signed binary without invalidating the signature. This update addresses a specific instance of malicious binary modification that could allow a modified binary to pass the Authenticode signature check. More importantly, it also introduces further hardening to consider a binary “unsigned” if any modification has been made in a certain portion of the binary. Those improvements to the Authenticode Signature Verification, as described below, require changes from a small but important set of third party application developers, so the new process will not be enabled by default today. Six months from today, on June 10, 2014, binaries will be considered unsigned if they do not conform to the new verification process. If you want to enable the regkey and test the change today, Please see the information posted in the security advisory 2915720.
We’d like to use this blog post to share more about Authenticode and the role of Authenticode in enabling customer confidence while running executables downloaded from the internet.
Authenticode and signed binaries
Authenticode® is a digital signature format that is used to determine the origin and integrity of software binaries. Authenticode is based on Public-Key Cryptography Standards (PKCS) #7 signed data and X.509 certificates to bind an Authenticode-signed binary to the identity of a software publisher.
The idea behind Authenticode is to leverage the reputation of a software developer or company to help customers make a trust decision. If you trust a particular company, you can execute binaries published by that company from any source and media as long as the binary is signed with the company’s valid Authenticode signature. The valid Authenticode signature does not guarantee that the software is safe to run. However, it does prove that the binary has been signed by that particular company and has not been altered afterward. According to the Authenticode Portable Executable format specification the Authenticode signatures can be “embedded” in a Windows PE file, in a location specified by the Certificate Table entry in Optional Header Data Directories. When Authenticode is used to sign a Windows PE file, the algorithm that calculates the file’s Authenticode hash value excludes certain PE fields. When embedding the signature in the file, the signing process can modify these fields without affecting the file’s hash value. These fields are as follows: the checksum, certificate table RVA, certificate table size and the attribute certificate table. The certificate table contains a PKCS #7 SignedData structure containing the PE file’s hash value, a signature created by the software publisher’s private key, and the X.509 v3 certificates that bind the software publisher’s signing key to a legal entity. A PKCS #7 SignedData structure can optionally contain:
- A description of the software publisher
- The software publisher’s URL
- An Authenticode timestamp
The following schema illustrates how an Authenticode signature is included in a Windows PE file:
This design philosophy allows no executable code being omitted from the signature. Once the code is authenticated and attributed to an author, everything that code does is the responsibility of the author.
Installer programs and Authenticode signatures
Downloaders and installers signed by Authenticode require special consideration because they download and execute other executables. As explained above, Authenticode testifies that a particular program’s code was signed by the author and that the executable code has not changed since then. If that particular program is designed to download and run a second executable from the network, the original program needs to verify the second executable’s integrity with Authenticode or by other means. The developers of a program should pay close attention to guarantee the same level of trust and integrity across the full download chain to ensure that executables downloaded by their installer are also trustworthy and cannot be replaced with a malicious program.
Microsoft was informed that a small set of third party installer programs, signed with a valid Authenticode signature, had been modified to download a different executable than the one originally designed to download without invalidating the installer’s Authenticode signature.
We analyzed each of these samples to study the execution flow to learn how they worked. Firstly, the code, which is covered by Authenticode, is executed from the entry point. Then, this code looks for an overlay inside the file to read a stream. Finally, the code decrypts a URL from the stream and downloads and executes an executable from that URL. The programs unfortunately omitted the integrity check before executing the downloaded file.
An overlay is data appended to the physical image of a Portable Executable. Explained simply, one can take a PE binary, append additional content to the end without adjusting the header, and it has an overlay. This data area is not defined as part of the image by the PE header and therefore isn’t part of the virtual image of the loaded PE. The Authenticode verification code verifies that the Attribute Certificate table is the last thing in the file and report an invalid signature if something is appended after that.
In the sample reported to Microsoft, the size of the certificate directory had been increased to cover the overlay. So technically, the certificate directory was the last thing in the file, allowing the test to pass.
There are couple of lessons to learn from this sample:
First, the developer stored the URL stream intentionally inside the certificate directory to allow them to sign once and create different installers. This particular sub-optimal practice enabled the malicious binary modification reported to Microsoft. The MS13-098 hardening, expected to go into effect June 10, 2014, will consider a binary unsigned in this case going forward.
Second, the developer in this particular case was not validating the file subsequently downloaded and executed by any other means.
A better way to enable the scenario desired by the developer would have been to store the URL as a resource inside the PE. In doing so, the URL would have been covered by Authenticode and any attempt to modify the downloaded URL would have resulted in a failed signature verification.
Today, with MS13-098, as described above, the Windows team has added additional hardening and mitigation in order to detect this kind of bad practices and report an invalid Authenticode signature. When enabled, these hardening measures will detect cases where additional unverified data has been placed after the PKCS #7 blob in the certificate directory of a PE image. The check validates that there is no non-zero data beyond the PKCS #7 structure. Although this change prevents one form of this unsafe practice, it is not capable of preventing all such forms; for example, an application developer can place unverified data within the PKCS #7 blob itself which will not be taken into account when verifying the Authenticode signature. However, as this blog post illustrates, developers are strongly discouraged from doing this as it can lead to unsafe application behavior and could potentially put the reputation of the signing company at risk if their application makes use of the unverified data in an unsafe way.
– Ali Rahbar, MSRC engineering team
I would like to thank the Jonathan Ness, Elia Florio and Ali Pezeshk