Unicode-related vulnerabilities have seen an increase in momentum in the past year. Last year, a Black Hat presentation by Jonathan Birch detailed how character normalization NFC/NFKC can lead to glitches in URL and host manipulation. Recently, two vulnerabilities were found in password reset functionality. The two affected applications were
Unicode for Security Professionals
Django and Github. In the previous blog post, we have presented API transforming code points with potential side effects. In this post, we present one of our findings: a vulnerability affecting Oracle JDK and Open JDK host verification in the TLS communication. We are also including details from a similar weakness in Apache HTTP client.
Unicode for Security Professionals
Unicode-related vulnerabilities have seen an increase in momentum in the past year. Last year, a Black Hat presentation by Jonathan Birch detailed how character normalization NFC/NFKC can lead to glitches in URL and host manipulation. Recently, two vulnerabilities were found in password reset functionality. The two affected applications were Django and Github. In the previous blog post, we have presented API transforming code points with potential side effects. In this post, we present one of our findings: a vulnerability affecting Oracle JDK and Open JDK host verification in the TLS communication. We are also including details from a similar weakness in Apache HTTP client.

Root Cause

Character transformations have been implemented in many cases with the intent to display a string to the user. In most languages, the lowercase and uppercase operation will convert specific characters according to the Unicode standard. For a character in the ASCII range, the behavior is predictable. However, some non-ASCII characters could be transformed to a character in the ASCII range in specific circumstances. We consider character collisions when two distinct Unicode characters sequences are converted to the same sequence. These conversions can interfere in the context of security verification.

Here are few examples where a single Unicode character will be converted to one or multiple characters in the ASCII range.

Python

"\u00DF".upper() => "SS"

Java

IDN.toASCII("\u2116dejs.org") => "nodejs.org"

.NET

new URI("https://faceboo\u212A.com").Host =>
"https://facebook.com"
These conversions can have security impacts if they happen during or after a security verification. It could cause different input strings to be considered equal after conversion.

Case Study 1: Oracle HostnameChecker (CVE-2020-14577)

The following code is taken from the class HostnameChecker. It compares the host that it is connecting to (name) and the host that is extracted from the SSL/TLS certificate (template).
private boolean isMatched(String name, String template, boolean chainsToPublicCA) {
       // Normalize to Unicode, because PSL is in Unicode.
       name = IDN.toUnicode(IDN.toASCII(name));
       template = IDN.toUnicode(IDN.toASCII(template));
       [....]
       return matchAllWildcards(name, template);
The transformation IDN.toUnicode() when combined with IDN.toASCII() can lead to an unexpected code point. Some extended Unicode characters get translated to the ASCII range causing collisions with other characters.

The final hostname stored in either name or template will not properly describe the remote host.

Input IDN.toUnicode(IDN.toASCII(Input))
U+FF41 a a
U+FF45 e e
[…]  
U+212A K k
U+2116 ℕ no
U+2121 ℡ tel

Approximately 321 Unicode code points are problematic and can cause this vulnerability.

Risk

An attacker could potentially create a malicious certificate or a certificate signing request (CSR) with the Unicode character U+FF41 to create a collision with a domain name that contains an “a”. This is possible because the common name is part of the subject field in X.509 certificate, which supports UTF-8.

In practice, host checking is only one part of the verification, the second being the chain of trust control. It is very difficult to get an Internet Root authority to sign a CSR with a special common name. Unless there is a weak security control on the authorities’ side, it should not be possible.

Two very narrow scenarios are possible to get the required chain of trust:

  • The targeted client is trusting an internal certificate authority (ie: Windows Server Certificate Authority allows CSR with UTF-8 extended character).
  • The attacker has compromised a certificate authority and he is hiding the malicious certificate with Unicode collision., which is very unlikely.

As you can see, this weakness – although hazardous – will not easily allow an attacker to intercept traffic from all Java applications.

Proof-of-Concept

If you want to see the weakness by yourself, we have published the proof-of-concept submitted to Oracle and OpenJDK. It includes the python script to generate malicious certificates.

Here is a view of the malicious certificate:

Microsoft Active Directory Certificate Services is one of the systems that would allow hostname with extend Unicode characters.

Proposed Solution

Avoiding IDN.toASCII() would solve the problem, as it avoids potential collisions with domains using special Unicode characters.

Timeline

  • Vulnerability reported: January 14, 2020
  • Acknowledgment that an investigation has started: January 14, 2020
  • Fix was released: July 2020

Case Study 2: HTTPClient 4.5.10

The Apache library HTTPClient had a similar weakness.

In HTTPClient 4.4 and higher, the class PublicSuffixMatcherLoader was vulnerable to improper handling of Unicode encoding (CWE-176). This class is used by the DefaultHostnameVerifier class, which is in charge of verifying the hostname during the TLS handshake.

Deep Dive Into the Code

Looking at the matches() method in the PublicSuffixMatcherLoader class, we can see that it relies on the getDomainRoot() method.

public boolean matches(final String domain, final DomainType expectedType) {
        if (domain == null) {
                return false;
        }
       final String domainRoot = getDomainRoot(
       domain.startsWith(".") ? domain.substring(1) : domain, expectedType);
       return domainRoot == null;
}
The key implementation details of the matching are inside the getDomainRoot() method. Before the domain name in the certificate is compared against the requested one, a lowercase transformation is applied:
public String getDomainRoot(final String domain, final DomainType expectedType) {
        [...]
        final String normalized = domain.toLowerCase(Locale.ROOT);
        String segment = normalized;
        String result = null;
The transformation String.toLowerCase() can lead to an unexpected code point. The risk of lowercasing the domain is much lower compared to the IDN.toASCII() that was used in the JDK implementation. There are only two characters that could cause issues: The Kelvin degree symbol and the Capital I with a dot above.
Input Input.toLowerCase()
K (U+212A) k (U+006b)
İ (U+0130) i̇ (U+0069 U+0307)
Here is a small proof-of-concept that demonstrates a malicious certificate with a Kelvin degree symbol. If the hostname verification failed, it would normally throw an exception.
val verifier = DefaultHostnameVerifier();

val cert = mock(X509Certificate::class.java);
`when`(cert.getSubjectX500Principal()).thenReturn(X500Principal("CN=montrehac\u212A.ca,
OU=Fake, O=Fake, C=CA"))

verifier.verify("montrehack.ca", cert);

Risk

This issue found in HTTPClient has similar risks to the previously presented JDK issue. It is however limited to domain names with the letter k.

Fix

You can view the commit made by the HttpClient team for more detail on the fix.

Timeline

  • Vulnerability reported: January 9, 2020
  • Vulnerability fixed: January 14, 2020
  • Release: January 23, 2020

Conclusion

This article summarizes our findings in the Java Runtime Environment and the library HTTPClient. As explained previously, the weakness affecting the HostnameChecker is not allowing TLS interception completely. An attacker would still need to get a certificate signed by a trusted authority.

GoSecure Titan® Managed Extended Detection & Response (MXDR)​

GoSecure Titan® Managed Extended Detection & Response (MXDR)​ Foundation

GoSecure Titan® Vulnerability Management as a Service (VMaaS)

GoSecure Titan® Managed Security Information & Event Monitoring (Managed SIEM)

GoSecure Titan® Managed Perimeter Defense​ (MPD)

GoSecure Titan® Inbox Detection and Response (IDR)

GoSecure Titan® Secure Email Gateway (SEG)

GoSecure Titan® Threat Modeler

GoSecure Titan® Identity

GoSecure Titan® Platform

GoSecure Professional Security Services

Incident Response Services

Security Maturity Assessment

Privacy Services

PCI DSS Services

Penetration Testing Services​

Security Operations

MicrosoftLogo

GoSecure MXDR for Microsoft

Comprehensive visibility and response within your Microsoft security environment

USE CASES

Cyber Risks

Risk-Based Security Measures

Sensitive Data Security

Safeguard sensitive information

Private Equity Firms

Make informed decisions

Cybersecurity Compliance

Fulfill regulatory obligations

Cyber Insurance

A valuable risk management strategy

Ransomware

Combat ransomware with innovative security

Zero-Day Attacks

Halt zero-day exploits with advanced protection

Consolidate, Evolve & Thrive

Get ahead and win the race with the GoSecure Titan® Platform

24/7 MXDR FOUNDATION

GoSecure Titan® Endpoint Detection and Response (EDR)

GoSecure Titan® Next Generation Antivirus (NGAV)

GoSecure Titan® Security Information & Event Monitoring (SIEM)

GoSecure Titan® Inbox Detection and Reponse (IDR)

GoSecure Titan® Intelligence

OUR SOC

Proactive Defense, 24/7

ABOUT GOSECURE

GoSecure is a recognized cybersecurity leader and innovator, pioneering the integration of endpoint, network, and email threat detection into a single Managed Extended Detection and Response (MXDR) service. For over 20 years, GoSecure has been helping customers better understand their security gaps and improve their organizational risk and security maturity through MXDR and Professional Services solutions delivered by one of the most trusted and skilled teams in the industry.

EVENT CALENDAR

LATEST PRESS RELEASE

GOSECURE BLOG

SECURITY ADVISORIES

 24/7 Emergency – (888)-287-5858