Summary
An information disclosure vulnerability exists in the Transport Layer Security protocol and the Secure Sockets Layer protocol (TLS/SSL) as implemented in the encryption component of the Microsoft .NET Framework. An attacker who successfully exploited this vulnerability could decrypt encrypted TLS/SSL traffic.Microsoft Security Bulletin MS16-065. This update changes the way that the .NET Framework encryption component sends and receives encrypted network packets.
To exploit the vulnerability, an attacker would first have to inject nonencrypted data into the security channel and then perform a man-in-the-middle (MiTM) attack between the targeted client and a legitimate server. This update addresses the vulnerability by modifying the way that the .NET encryption component sends and receives encrypted network packets. This vulnerability is fixed as part ofThe following table contains links to the standard entry for each vulnerability in the Common Vulnerabilities and Exposures list.
Vulnerability title |
CVE number |
Publicly disclosed |
Exploited |
---|---|---|---|
TLS/SSL Spoofing Vulnerability |
Yes |
No |
Vulnerability Resolution
The change introduced in Microsoft Security Bulletin MS16-065 causes the first TLS record after the handshake to be split. This causes the SslStream, WebRequest (HttpWebRequest, FtpWebRequest), SmtpClient, and HttpClient (where based on HttpWebRequest) streams to return a single byte for the first read, immediately followed by the rest (n-1) bytes in successive reads. This behavior change only occurs for applications that use TLS 1.0 + Cipher Block Chaining, but not when they use TLS 1.1 or TLS 1.2. Note As a prerequisite, you must install Microsoft Security Bulletin MS12-006 to enable this update. This change may cause some applications that are based on the .NET Framework to break. This article describes two approaches you can use to update your application to work correctly after you apply Microsoft Security Bulletin MS16-065.
Mitigations for compatibility issues
Option 1: Switch to the TLS 1.2 protocol
This option makes the application use the TLS 1.2 protocol by either modifying the registry or programmatically configuring the protocol version.
-
Modify the registryback up the registry for restoration in case problems occur. The .NET Framework 4.0 and the .NET Framework 4.5.x applications that are running on the .NET Framework 4.5 and later versions can switch the default protocol to TLS 1.2, TLS 1.1, and TLS 1.0 by enabling the SchUseStrongCrypto registry key. This registry key is discussed in the Suggested Actions section of the Microsoft Security Advisory 2960358 topic on the Microsoft TechNet website. Important This registry change will only work if the following conditions are true:
Important Follow the steps in this section carefully. Serious problems might occur if you modify the registry incorrectly. Before you modify it,-
Applications that use ServicePointManager-based APIs are not setting the ServicePointManager.SecurityProtocol value explicitly. Examples of such classes include System.Net.Http.HttpClient, System.Net.FtpWebRequest, System.Net.HttpWebRequest, and System.Net.Mail.SmtpClient. Setting the ServicePointManager.SecurityProtocol in code takes precedence over the registry.
-
Applications are using the SslStream AuthenticateAsClient(String) overload.
-
-
Programmatically configure the protocol versionSslStream AuthenticateAsClient(String, X509CertificateCollection, SslProtocols, Boolean) overload must be recompiled, specifying SslProtocols.Tls12, SslProtocols.Tls11, and SslProtocols.Tls as the third parameter. For a complete description of how to use the SslStream class, see the SslStream Class topic on the Microsoft Developer (MSDN) website. Note The .NET Framework 4.6 and later versions use TLS 1.2, TLS 1.1, and TLS 1.0 as the protocol defaults. This is discussed in the Microsoft Security Advisory 2960358 topic on the Microsoft TechNet website.
The .NET Framework 4.0 and 4.5 applications that are running on the .NET Framework 4.5 and later versions and that use the
Option 2: Handle split packets
This update causes a single record to be split into multiple records. Therefore, if an application is expecting the complete record to be available in a single Read call, such applications may break. To make sure that the application behaves correctly, verify that the application handles split packets by performing the Stream.Read call correctly. You can use the sample code available here as a reference for how to fix the application to correctly perform the Read call. For a sample HTTP request that shows the difference in behavior before (with the mitigation) and after (without the mitigation) updates 3147461 and 3147458 were installed, see the "More Information" section. For a complete example of the Stream.Read method, see the Stream.Read Method (Byte[], Int32, Int32) topic on the Microsoft Developer (MSDN) website.
Workarounds to Application Compatibility Issues
Warning These workarounds may make a computer or a network more vulnerable to attack by malicious users or by malicious software such as viruses. We do not recommend these workarounds but are providing this information so that you can implement these workarounds at your own discretion. Use these workarounds at your own risk.
Method 1: Update registry keys (available for all versions of the .NET Framework)
Disable the SCH_SEND_AUX_RECORD structure (globally) Disable SCH_SEND_AUX_RECORD structure for individual applications
Disable SCH_SEND_AUX_RECORD structure (globally)
For all applications, add the following registry subkey:
Registry location:HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\<version_number>
DWORD name: SchSendAuxRecord Value data: 0 Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version. For 32-bit applications that run on 64-bit computers, also add the following registry subkey:Registry location:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\.NETFramework\<version_number>
DWORD name: SchSendAuxRecord Value data: 0 Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version.Workaround
To temporarily disable the secure mode described in this article, click the appropriate link to download a .reg file, and then double-click the downloaded .reg file to make the registry changes.
For applications targeting the Microsoft .NET Framework 3.5:Download the ManualOptOutSchSendAuxRecord20.reg file now. For applications targeting the Microsoft .NET Framework 4.0 and later versions:
Download the ManualOptOutSchSendAuxRecord40.reg file now. To re-enable the secure mode described in this article, click the appropriate link to download a .reg file, and then double-click the downloaded .reg file to make the registry changes. For applications targeting Microsoft .NET Framework 3.5:
Download the ManualOptInSchSendAuxRecord20.reg file now. For applications targeting the Microsoft .NET Framework 4.0 and later versions:
Download the ManualOptInSchSendAuxRecord40.reg file now. For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:
119591 How to obtain Microsoft support files from online services Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.
Disable SCH_SEND_AUX_RECORD structure for individual applications
For all applications, add the following registry subkey:
Registry location:HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\<version_number>\System.Net.ServicePointManager.SchSendAuxRecord
DWORD name: Fully qualified path for the application .exe (for example, C:\MyApp\MyApp.exe) Value data: 0 Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version. For 32-bit applications that run on 64-bit computers, also add the following registry subkey:Registry location:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\.NETFramework\<version_number>\System.Net.ServicePointManager.SchSendAuxRecord
DWORD name: Fully qualified path for the application .exe (for example, C:\MyApp\MyApp.exe) Value data: 0 (The only valid value is 0. Any other value will be ignored.) Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version.Method 2: Change configuration at the application level (available only for the .NET Framework version 4.6 and later versions)
Starting with the .NET Framework 4.6, you can change the configuration at an application level through code or application configuration or registry changes.
In the .NET Framework 4.6, you can set the switch by using any of the following methods. These examples disable the security feature.-
Programmatically
The first thing that the application should do is run the following code. This is because Service Point Manager will initialize only one time.private const string DisableCachingName = @"TestSwitch.LocalAppContext.DisableCaching";
private const string DontEnableSchSendAuxRecordName = @"Switch.System.Net.DontEnableSchSendAuxRecord"; AppContext.SetSwitch(DisableCachingName, true); AppContext.SetSwitch(DontEnableSchSendAuxRecordName , true); -
Application configuration
To change the application configuration, add the following entry:<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchSendAuxRecord=true"/> </runtime> -
Registry key (computer global)
Registry locations:HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContextHKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext
Value: Switch.System.Net.DontEnableSchSendAuxRecord Type: String Value: True Note Switch.System.Net.DontEnableSchSendAuxRecord = False for all applications.
More Information
The following is a sample Client/Server communication pattern before and after this update is installed. This information is provided for illustration for identifying any application breakage because of the installation of this fix.
Without the mitigation |
With the mitigation |
---|---|
[Server] waiting for connections (127.0.0.1:4431) [Client] Connecting to localhost:4431 [Server] Client connected. [Client] Connected. Authenticating... [Server] Client authenticated. [Client] Sending request (94 Bytes) [Client] Waiting for reply… [Server] Received 94 bytes: <<<GET / HTTP/1.0 Host: contoso.com User-Agent: Testing application >>> [Server] Replied with 476 bytes. [Client 1: 476 Bytes] Response: <<<<<HTTP/1.1 200 OK … >>>>> |
[Server] waiting for connections (127.0.0.1:4431) [Client] Connecting to localhost:4431 [Server] Client connected. [Client] Connected. Authenticating... [Server] Client authenticated. [Client] Sending request (94 Bytes) [Client] Waiting for reply... [Server] Received 1 bytes: <<<G>>> [Server] Received 93 bytes: <<<ET / HTTP/1.0 Host: contoso.com User-Agent: Testing application >>> [Server] Replied with 476 bytes. [Client 1: 1 Bytes] Response: <<<<<H>>>>> [Client 2: 475 Bytes] Response: <<<<<TTP/1.1 200 OK … >>>>> |