MS16-065: Description of the TLS/SSL protocol information disclosure vulnerability (CVE-2016-0149): May 10, 2016

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.

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 of Microsoft Security Bulletin MS16-065. This update changes the way that the .NET Framework encryption component sends and receives encrypted network packets.

The following table contains links to the standard entry for each vulnerability in the Common Vulnerabilities and Exposures list.

Vulnerability titleCVE numberPublicly disclosedExploited
TLS/SSL Spoofing VulnerabilityCVE-2016-0149YesNo

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 registry

    Important Follow the steps in this section carefully. Serious problems might occur if you modify the registry incorrectly. Before you modify it, back 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:
    • 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 version

    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 SslStream 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.

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 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:

For applications targeting the Microsoft .NET Framework 4.0 and later versions:

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:

For applications targeting the Microsoft .NET Framework 4.0 and later versions:

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\AppContext
    HKEY_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 mitigationWith 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

>>>>>

Properties

Article ID: 3155464 - Last Review: 05/10/2016 17:04:00 - Revision: 1.0

Microsoft .NET Framework 4.6.1, Microsoft .NET Framework 4.6, Microsoft .NET Framework 4.5.2, Microsoft .NET Framework 3.5.1, Microsoft .NET Framework 3.5, Microsoft .NET Framework 2.0 Service Pack 2

  • kbsecvulnerability kbsecurity kbsecbulletin kbfix kbexpertiseinter kbbug atdownload KB3155464
Feedback