Apple OSX Mavericks 10.9.x SSL Key Exchange Verification Vulnerability (CVE-2014-1266)

SektionEins released a quick and dirty experimental fix for this vulnerability.

The Vulnerability

Yesterday Apple released iOS 7.0.6 and iOS 6.1.6. Both fix a serious security flaw (CVE-2014-1266) in the SSL handling code inside the Security.framework. The flaw is very serious because it totally compromises the security of SSL and allows for man in the middle attack on otherwise secure SSL connections without any warning on the client side.

Unfortunately it has been discovered that this vulnerability is also present in OSX Mavericks. When you look at the following code snippet that is taken from Security.framework's sslKeyExchange.c you can spot a superfluous "goto fail;" statement. This statement is executed in all cases and completely bypasses the call to sslRawVerify. This means there is actually no verification performed on the signed server key exchange.

static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
                                 uint8_t *signature, UInt16 signatureLen)
{
    ...

    if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
        goto fail;
    if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
        goto fail;
    if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
        goto fail;
    if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;  <---- *** DANGER ***
    if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
        goto fail;

        err = sslRawVerify(ctx,
                       ctx->peerPubKey,
                       dataToSign,                              /* plaintext */
                       dataToSignLen,                   /* plaintext length */
                       signature,
                       signatureLen);
    ...
fail:
    SSLFreeBuffer(&signedHashes);
    SSLFreeBuffer(&hashCtx);
    return err;

}

You can read more information about this vulnerability over at ImperialViolet.

The Patch

Because Apple decided to just release updates for iOS and leave OSX Mavericks users vulnerable over a weekend, we have looked into this issue and created a little binary patch that fixes this vulnerability by re-adding the removed code.

This is of course just a quick and dirty solution to test the impact of this vulnerability. You should not attempt to run this on production systems. And don't forget that we only patch the 64bit version of the Security.framework. If your code is 32bit you have to port the fix to 32bit.

.text
#
# This is the original code inside the Security.framework binary
#
#__text:0000000000086C3B                 lea     r15, _SSLHashSHA1
#__text:0000000000086C42                 lea     rsi, [rbp+var_C8]
#__text:0000000000086C49                 mov     rdi, r15
#__text:0000000000086C4C                 call    _ReadyHash
#__text:0000000000086C51                 mov     ebx, eax
#__text:0000000000086C53                 test    ebx, ebx
#__text:0000000000086C55                 jnz     short loc_86C9C
#__text:0000000000086C57                 mov     r14, [r15+18h]
#__text:0000000000086C5B                 lea     rdi, [rbp+var_C8]
#__text:0000000000086C62                 lea     rsi, [rbp+var_D8]
#__text:0000000000086C69                 call    r14
#__text:0000000000086C6C                 mov     ebx, eax
#__text:0000000000086C6E                 test    ebx, ebx
#__text:0000000000086C70                 jnz     short loc_86C9C
#__text:0000000000086C72                 lea     rdi, [rbp+var_C8]
#__text:0000000000086C79                 lea     rsi, [rbp+var_E8]
#__text:0000000000086C80                 call    r14
#__text:0000000000086C83                 mov     ebx, eax
#__text:0000000000086C85                 test    ebx, ebx
#__text:0000000000086C87                 jnz     short loc_86C9C
#__text:0000000000086C89                 lea     rdi, [rbp+var_C8]
#__text:0000000000086C90                 lea     rsi, [rbp+var_A8]
#__text:0000000000086C97                 call    r14
#__text:0000000000086C9A                 mov     ebx, eax

# we insert the hook at 0x86c90

lea -0xa8(%rbp), %rsi  # signedParams
call *%r14             # SSLHashSHA1.update
mov %eax, %ebx
test %ebx, %ebx
jnz  1f
lea -0xc8(%rbp), %rdi  # hashCtx
lea -0xb8(%rbp), %rsi  # hashOut
call *0x20(%r15)       # SSLHashSHA1.final
mov %eax, %ebx
test %ebx, %ebx
jnz  1f

mov -0x1e0(%rbp), %r8  # signature
xor %rsi, %rsi
inc %rsi
inc %rsi
mov %r8, %rdi
sub %rsi, %rdi
call _SSLDecodeInt
cwde
cdqe
mov  %rax, %r9         # signatureLen
mov %r12, %rdi         # ctx
mov +0x78(%rdi), %rsi  # ctx->peerPubKey
mov -0xb0(%rbp), %rdx  # dataToSign from hashOut.data
mov $20, %rcx          # SSL_SHA1_DIGEST_LEN
cmpb $0, -0x1a8(%rbp)  # isRsa
jz   2f
sub $16, %rdx          # Need MD5 so pos-SSL_MD5_DIGEST_LEN
mov $36, %rcx          # dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN
2:
call _sslRawVerify
jmp label_86C9A

1:
jmp label_86C9C

Download

Please understand that we will not provide further help with applying the patch below. We strongly consider this patch experimental and you should only apply it to your systems if you understand the risk.

Download the BSPATCH here.

Due to popular request we have made the patch a little bit easier to use. Please download the following archive. Double Click to unpack it. Then the usual Ctrl-Click-Open to execute CVE-2014-1266-Patcher.command. This will look like the following.

Download Archive I KNOW WHAT I AM DOING I AM AWARE OF THE RISK

Security.framwork Patcher
Patches a Critical SSL Vulnerability in Mac OSX 10.9.1 (CVE-2014-1266)
----------------------------------------------------------------------
Use with caution and at your own risk of breaking your system.

Enter uppercase "YES" if you REALLY want to do this: YES
[-] This script was not executed as the root user. We therefore cannot patch the Security Framework

[!] We will try to re-execute ourselves with 'sudo'

[!] You have to enter your password to allow this.
[!] checking the Security Framework.
[!] creating a backup copy of the Security Framework.
[+] backup created now checking if it is okay.
[+] Applying the patch.
[+] Writing the patched file to disk.
[+] Verifying patched file on disk.
[+] Replacing the Security.framework.
[!] This is a critical step. Lets pray everything works.
[+] Verifying one last time.


[+] DONE. We suggest you reboot your system now.

Patch in Action

The following images show the patch in action on a VMWARE installation of OSX Mavericks 10.9.1.