X41 D-Sec GmbH Security Advisory: X41-2018-005

Multiple Vulnerabilities in Apple smartcardservices

Overview

Confirmed Affected Versions: e3eb96a6eff9d02497a51b3c155a10fa5989021f

Confirmed Patched Versions: 8eef01a5e218ae78cc358de32213b50a601662de

Vendor: Apple

Vendor URL: https://smartcardservices.github.io/

Credit: X41 D-Sec GmbH, Eric Sesterhenn

Status: Public

Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2018-005-smartcardservices/

Summary and Impact

Attackers with local access can exploit security issues in the smartcard driver. These result in memory corruptions, which might lead to code execution. Since smartcards can be used for authentication, the vulnerabilities may allow an attacker to login to the system without valid credentials as any user.

X41 did not perform a full test or audit on the software.

Product Description

The Smart Card Services project is comprised of several components which, when combined, provide the necessary abstraction layer and integration of smart cards into Apple’s CDSA implementation.

Stack based buffer overflow

Severity Rating: Medium

Vector: APDU Response

CVE: CVE-2018-4300

CWE: 120

CVSS Score: 7.1 (High)

CVSS Vector: CVSS:3.0/AV:P/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

Summary and Impact

In file Tokend/CAC/CACRecord.cpp the function CACCertificateRecord::getDataAttribute() might overwrite the value certificate and possibly other stack data, if a smartcard provides malicious data.

        unsigned char command[] = { 0x80, 0x36, 0x00, 0x00, 0x64 };
        unsigned char result[MAX_BUFFER_SIZE];
        size_t resultLength = sizeof(result);
        uint8 certificate[CAC_MAXSIZE_CERT];
        uint8 uncompressed[CAC_MAXSIZE_CERT];
        size_t certificateLength = 0;

        try
        {
                PCSC::Transaction _(cacToken);
                cacToken.select(mApplication);
                uint32_t cacreturn;
                do
                {
                        cacreturn = cacToken.exchangeAPDU(command, sizeof(command), result,
                                resultLength);

                        if ((cacreturn & 0xFF00) != 0x6300)
                                CACError::check(cacreturn);

                        size_t requested = command[4];
                        if (resultLength != requested + 2)
                PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);

                        memcpy(certificate + certificateLength, result, resultLength - 2);
                        certificateLength += resultLength - 2;
                        // Number of bytes to fetch next time around is in the last byte
                        // returned.
                        command[4] = cacreturn & 0xFF;
                } while ((cacreturn & 0xFF00) == 0x6300);
        }
        catch (...)
        {
                return NULL;
        }

As long as the smartcard returns a return code of 0x63FF, more data is copied into the certificate buffer, causing a stack based overflow. A malicious smartcard is able to control all of the overflowed bytes.

Workarounds

None

Stack based buffer overflow with limited input

Severity Rating: Medium

Vector: APDU Response

CVE: CVE-2018-4301

CWE: 120

CVSS Score: 7.1 (High)

CVSS Vector: CVSS:3.0/AV:P/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

Summary and Impact

In file Tokend/PKCS11/GemaltoKeyHandle.cpp the function GemaltoPrivateKeyRecord::computeDecrypt() might overwrite the value strData if the supplied dataLength is too big.

void GemaltoPrivateKeyRecord::computeDecrypt(GemaltoToken &gemaltoToken, CK_ULONG mech, const AccessCredentials *cred, unsigned char *data, size_t dataLength, unsigned char *output, size_t &outputLength)
{
        GemaltoToken::log("\nGemaltoPrivateKeyRecord::computeDecrypt <BEGIN>\n");
        GemaltoToken::log("GemaltoPrivateKeyRecord::computeDecrypt - mechanism <%lu>\n", mech);
        GemaltoToken::log("GemaltoPrivateKeyRecord::computeDecrypt - cred <%p>\n", cred);
        char strData[6000];
        memset(strData, '\0', sizeof(strData));
        char* str = strData;
        for (size_t i=0; i<dataLength; i++)
        {
                str += sprintf(str, "%02x ", data[i]);
        }
        GemaltoToken::log("GemaltoPrivateKeyRecord::computeDecrypt - dataLength <%lu> - data <%s>\n", dataLength, strData);
        GemaltoToken::log("GemaltoPrivateKeyRecord::computeDecrypt - output <%p>\n", output);
        GemaltoToken::log("GemaltoPrivateKeyRecord::computeDecrypt - outputLength <%lu>\n", outputLength);

The attacker might control the data which is to be decrypted, but exploitation is limited by the sprintf() format string.

Workarounds

None

Timeline

2018-02-03 Issues found

2018-05-22 Vendor contacted

2018-05-22 Automated vendor reply

2018-05-23 Personal vendor reply

2018-06-05 Requesting technical feedback from the vendor

2018-06-22 Vendor states that the bugs are fixed in public git

2018-07-12 CVE IDs assigned

2018-08-03 https://smartcardservices.github.io/security/ updated

Author: Eric Sesterhenn
Date: February 03, 2018