Protect yourself against future threats.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 =========================================================================== AUSCERT External Security Bulletin Redistribution ESB-2018.2351 Multiple Smartcard Vulnerabilities 15 August 2018 =========================================================================== AusCERT Security Bulletin Summary --------------------------------- Product: Smart card software Publisher: X41 Operating System: Windows Linux variants OS X Impact/Access: Execute Arbitrary Code/Commands -- Console/Physical Access Confidential Data -- Console/Physical Resolution: Patch/Upgrade CVE Names: CVE-2018-14780 CVE-2018-14779 CVE-2018-4301 CVE-2018-4300 Original Bulletin: https://www.x41-dsec.de/lab/advisories/x41-2018-001-Yubico-Piv/ https://www.x41-dsec.de/lab/advisories/x41-2018-002-OpenSC/ https://www.x41-dsec.de/lab/advisories/x41-2018-003-pam_pkcs11/ https://www.x41-dsec.de/lab/advisories/x41-2018-004-libykneomgr/ https://www.x41-dsec.de/lab/advisories/x41-2018-005-smartcardservices/ Comment: This bulletin contains five (5) X41 security advisories. - --------------------------BEGIN INCLUDED TEXT-------------------- X41 D-Sec GmbH Security Advisory: X41-2018-001 Multiple Vulnerabilities in Yubico Piv Overview Confirmed Affected Versions: 1.5.0 Confirmed Patched Versions: - Vendor: Yubico Vendor URL: https://www.yubico.com/ Credit: X41 D-Sec GmbH, Eric Sesterhenn Status: Public Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2018-001-Yubico-Piv/ Summary and Impact A buffer overflow and an out of bounds memory read were identified in the yubico-piv-tool-1.5.0, these can be triggered by a malicious token. X41 did not perform a full test or audit on the software. Product Description YubiKey 4, YubiKey 4 Nano, YubiKey 4C, YubiKey 4C Nano, and YubiKey NEO provide Smart Card functionality based on the Personal Identity Verification (PIV) interface specified in NIST SP 800-73, "Cryptographic Algorithms and Key Sizes for PIV." Out of Bounds Write via Malicious APDU Severity Rating: High Vector: APDU Response CVE: CVE-2018-14779 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 File lib/ykpiv.c contains the following code in function ykpiv_transfer_data() if(*out_len + recv_len - 2 > max_out) { fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.", *out_len + recv_len - 2, max_out); } if(out_data) { memcpy(out_data, data, recv_len - 2); out_data += recv_len - 2; *out_len += recv_len - 2; } It is clearly checked whether the buffer is big enough to hold the data copied using memcpy(), but no error handling happens to avoid the memcpy() in such cases. This code path can be triggered with malicious data coming from a smartcard. Workarounds None Out of Bounds Read via malicious APDU Severity Rating: LOW Vector: APDU Response CVE: CVE-2018-14780 CWE: 125 CVSS Score: 2.2 (Low) CVSS Vector: CVSS:3.0/AV:P/AC:H/PR:N/UI:N/S:C/C:L/I:N/A:N Summary and Impact File lib/ykpiv.c contains the following code in function _ykpiv_fetch_object() if(sw == SW_SUCCESS) { size_t outlen; int offs = _ykpiv_get_length(data + 1, &outlen); if(offs == 0) { return YKPIV_SIZE_ERROR; } memmove(data, data + 1 + offs, outlen); *len = outlen; return YKPIV_OK; } else { return YKPIV_GENERIC_ERROR; } In the end, a memmove() occurs with a length retrieved from APDU data. This length is not checked if it is outside of the APDU data retrieved. Therefore the memmove() could copy bytes behind the allocated data buffer into this buffer. Workarounds None Timeline 2018-02-03 Issues found 2018-05-22 Vendor contacted 2018-05-22 Vendor reply 2018-06-05 Requesting technical feedback from the vendor 2018-06-06 Vendor confirms bug 2018-08-01 CVE ID requested 2018-08-02 CVE ID assigned 2018-08-08 Patched version released by vendor Author: Eric Sesterhenn Copyright (C) X41 D-SEC GmbH 2018 - -------------------------------------------------------------------------- X41 D-Sec GmbH Security Advisory: X41-2018-002 Multiple Vulnerabilities in OpenSC Overview Confirmed Affected Versions: 0.17.0 Confirmed Patched Versions: - Vendor: OpenSC Vendor URL: https://github.com/OpenSC/OpenSC Credit: X41 D-Sec GmbH, Eric Sesterhenn Status: Public Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2018-002-OpenSC/ Summary and Impact Multiple issues have been identified in OpenSC, ranging from stack based buffer overflows to out of bounds reads and writes on the heap. They can be triggered by malicious smartcards sending malformed responses to APDU commands. Additionally to those fixes reported here, a lot of minor issues (eg. OOB reads and similar) have been reported and fixed. The OpenSC team (especially Frank Morgner) did an excellent job on identifying and fixing further issues. Due to the large amount of issues, no individual issues have been rated with CVSS / CVE ID yet. X41 did not perform a full test or audit on the software, but tried to help identifying as many bugs as possible in over the course of a year. Product Description OpenSC provides a set of libraries and utilities to work with smart cards. Its main focus is on cards that support cryptographic operations, and facilitate their use in security applications such as authentication, mail encryption and digital signatures. OOB Write in muscle_list_files() In funcion muscle_list_files() in file src/libopensc/card-muscle.c an out of bounds write might occur, since bufLen is not checked. static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) { muscle_private_t* priv = MUSCLE_DATA(card); mscfs_t *fs = priv->fs; int x; int count = 0; mscfs_check_cache(priv->fs); for(x = 0; x < fs->cache.size; x++) { u8* oid= fs->cache.array[x].objectId.id; sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "FILE: %02X%02X%02X%02X\n", oid[0],oid[1],oid[2],oid[3]); if(0 == memcmp(fs->currentPath, oid, 2)) { buf[0] = oid[2]; buf[1] = oid[3]; if(buf[0] == 0x00 && buf[1] == 0x00) continue; /* No directories/null names outside of root */ buf += 2; count+=2; } } return count; } OOB Write in tcos_select_file() In function tcos_select_file) in file src/libopensc/card-tcos.c a filename is extracted from an APDU response and written into the internal file->name variable. case 0x84: memcpy(file->name, d, len); file->namelen = len; break; No check is performed whether the string retrieved from the card fits into the buffer, which could trigger an OOB write. OOB Write in piv_validate_general_authentication() In case piv_validate_general_authentication()in src/libopensc/card-piv.c is called with a datalen parameter greater than 4096, an out of bound write occurs. Currently no caller seems to do this. OOB Write in gemsafe_get_cert_len() The function gemsafe_get_cert_len() in file src/libopensc/pkcs15-gemsafeV1.c might write beyond the gemsafe_prkeys and gemsafe_cert arrays in case more than 12 containers are stored on the card. ind = 2; /* skip length */ while (ibuf[ind] == 0x01) { if (ibuf[ind+1] == 0xFE) { gemsafe_prkeys[i].ref = ibuf[ind+4]; sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d", i+1, gemsafe_prkeys[i].ref); ind += 9; } else { gemsafe_prkeys[i].label = NULL; gemsafe_cert[i].label = NULL; sc_log(card->ctx, "Key container %d is unallocated", i+1); ind += 8; } i++; } OOB Write in util_acl_to_str() In function util_acl_to_str() in file src/tools/util.c no checks are performed whether the string put together fits into line, which could be abused to trigger limited out of bounds writes. OOB Write in read_public_key() and read_private_key() In function read_public_key() in file src/tools/cryptoflex-tool.c the bufsize variable is overwritten with file->size retrieved from the smartcard. This could be bigger than 2048, allowing for a stack based buffer overflow in the sc_read_binary() call. u8 buf[2048], *p = buf; size_t bufsize, keysize; r = select_app_df(); if (r) return 1; sc_format_path("I1012", &path); r = sc_select_file(card, &path, &file); if (r) { fprintf(stderr, "Unable to select public key file: %s\n", sc_strerror(r)); return 2; } bufsize = file->size; sc_file_free(file); r = sc_read_binary(card, 0, buf, bufsize, 0); The same issue can be found in read_private_key() bufsize = file->size; sc_file_free(file); r = sc_read_binary(card, 0, buf, bufsize, 0); OOB Write in decrypt_response() In function decrypt_response() in file src/libopensc/card-epass2003.c an out of bounds overwrite can occur. No check is performed if the plaintext buffer fits into the out buffer before copying, leading to a memory overwrite. memcpy(out, plaintext, in_len - 2); *out_len = in_len - 2; return 0; OOB Write in cac_get_serial_nr_from_CUID() In function cac_get_serial_nr_from_CUID() in file src/libopensc/card-cac.c a serial number is copied into serial->value. The length argument of the memcpy() is the length of the source, not the destination, which can lead to an out of bounds memory write. if (priv->cac_id_len) { serial->len = MIN(priv->cac_id_len, SC_MAX_SERIALNR); memcpy(serial->value, priv->cac_id, priv->cac_id_len); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } Off by One Write in sc_pkcs15emu_esteid_init() In function sc_pkcs15emu_esteid_init() in file src/libopensc/pkcs15-esteid.c an off by one write with a \x00 occurs in case the sc_read_record() functions returns sizeof(buf) read bytes. /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed"); buff[r] = '\0'; Double Free in sc_file_set_sec_attr() In function sc_file_set_sec_attr() in file src/libopensc/sc.c a double free occurs in case sec_attr_len is equal to 0, since the call to realloc() will free file->sec_attr and return NULL. The variable is then freed again in the error handling path. tmp = (u8 *) realloc(file->sec_attr, sec_attr_len); if (!tmp) { if (file->sec_attr) free(file->sec_attr); file->sec_attr = NULL; file->sec_attr_len = 0; return SC_ERROR_OUT_OF_MEMORY; } Double Free in read_file() In function read_file() in file src/tools/egk-tool.c a double free can be triggered in case two calls to sc_select_file() return a file->size of zero. The first call to realloc() frees the memory, the second frees it again. len = file - file->size : 4096; p = realloc(*data, len); if (!p) { goto err; } It is clearly checked whether the buffer is big enough to hold the data copied using memcpy(), but no error handling happens to avoid the memcpy() in such cases. This code path can be triggered with malicious data coming from a smartcard. Double free in sc_pkcs15emu_sc_hsm_init() In function sc_pkcs15emu_sc_hsm_init() in file src/libopensc/pkcs15-sc-hsm.c a double free can occur, since this function can be called twice. The call to realloc() with a size of 0 would free priv->EF_C_DevAut with a second call freeing the already freed memory. /* save EF_C_DevAut for further use */ ptr = realloc(priv->EF_C_DevAut, len); if (ptr) { memcpy(ptr, efbin, len); priv->EF_C_DevAut = ptr; priv->EF_C_DevAut_len = len; } ptr = efbin; Unbound Recursion in iasecc_select_mf()/iasecc_select_file() Function iasecc_select_file() in file src/libopensc/card-iasecc.c calls iasecc_select_mf() in the same file, which calls iasecc_select_file() again. This can lead to an infinite recursion exhausting the stack. Timeline 2018-02-03 Issues found 2018-04-18 Vendor contacted 2018-04-18 Vendor reply 2018-05-18 Technical details provided 2018-05-24 Private git branch created, fixing started 2018-08-11 Patched version released: https://github.com/x41sec/OpenSC Author: Eric Sesterhenn Copyright (C) X41 D-SEC GmbH 2018 - -------------------------------------------------------------------------- X41 D-Sec GmbH Security Advisory: X41-2018-002 Multiple Vulnerabilities in OpenSC Overview Confirmed Affected Versions: 0.17.0 Confirmed Patched Versions: - Vendor: OpenSC Vendor URL: https://github.com/OpenSC/OpenSC Credit: X41 D-Sec GmbH, Eric Sesterhenn Status: Public Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2018-002-OpenSC/ Summary and Impact Multiple issues have been identified in OpenSC, ranging from stack based buffer overflows to out of bounds reads and writes on the heap. They can be triggered by malicious smartcards sending malformed responses to APDU commands. Additionally to those fixes reported here, a lot of minor issues (eg. OOB reads and similar) have been reported and fixed. The OpenSC team (especially Frank Morgner) did an excellent job on identifying and fixing further issues. Due to the large amount of issues, no individual issues have been rated with CVSS / CVE ID yet. X41 did not perform a full test or audit on the software, but tried to help identifying as many bugs as possible in over the course of a year. Product Description OpenSC provides a set of libraries and utilities to work with smart cards. Its main focus is on cards that support cryptographic operations, and facilitate their use in security applications such as authentication, mail encryption and digital signatures. OOB Write in muscle_list_files() In funcion muscle_list_files() in file src/libopensc/card-muscle.c an out of bounds write might occur, since bufLen is not checked. static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen) { muscle_private_t* priv = MUSCLE_DATA(card); mscfs_t *fs = priv->fs; int x; int count = 0; mscfs_check_cache(priv->fs); for(x = 0; x < fs->cache.size; x++) { u8* oid= fs->cache.array[x].objectId.id; sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "FILE: %02X%02X%02X%02X\n", oid[0],oid[1],oid[2],oid[3]); if(0 == memcmp(fs->currentPath, oid, 2)) { buf[0] = oid[2]; buf[1] = oid[3]; if(buf[0] == 0x00 && buf[1] == 0x00) continue; /* No directories/null names outside of root */ buf += 2; count+=2; } } return count; } OOB Write in tcos_select_file() In function tcos_select_file) in file src/libopensc/card-tcos.c a filename is extracted from an APDU response and written into the internal file->name variable. case 0x84: memcpy(file->name, d, len); file->namelen = len; break; No check is performed whether the string retrieved from the card fits into the buffer, which could trigger an OOB write. OOB Write in piv_validate_general_authentication() In case piv_validate_general_authentication()in src/libopensc/card-piv.c is called with a datalen parameter greater than 4096, an out of bound write occurs. Currently no caller seems to do this. OOB Write in gemsafe_get_cert_len() The function gemsafe_get_cert_len() in file src/libopensc/pkcs15-gemsafeV1.c might write beyond the gemsafe_prkeys and gemsafe_cert arrays in case more than 12 containers are stored on the card. ind = 2; /* skip length */ while (ibuf[ind] == 0x01) { if (ibuf[ind+1] == 0xFE) { gemsafe_prkeys[i].ref = ibuf[ind+4]; sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d", i+1, gemsafe_prkeys[i].ref); ind += 9; } else { gemsafe_prkeys[i].label = NULL; gemsafe_cert[i].label = NULL; sc_log(card->ctx, "Key container %d is unallocated", i+1); ind += 8; } i++; } OOB Write in util_acl_to_str() In function util_acl_to_str() in file src/tools/util.c no checks are performed whether the string put together fits into line, which could be abused to trigger limited out of bounds writes. OOB Write in read_public_key() and read_private_key() In function read_public_key() in file src/tools/cryptoflex-tool.c the bufsize variable is overwritten with file->size retrieved from the smartcard. This could be bigger than 2048, allowing for a stack based buffer overflow in the sc_read_binary() call. u8 buf[2048], *p = buf; size_t bufsize, keysize; r = select_app_df(); if (r) return 1; sc_format_path("I1012", &path); r = sc_select_file(card, &path, &file); if (r) { fprintf(stderr, "Unable to select public key file: %s\n", sc_strerror(r)); return 2; } bufsize = file->size; sc_file_free(file); r = sc_read_binary(card, 0, buf, bufsize, 0); The same issue can be found in read_private_key() bufsize = file->size; sc_file_free(file); r = sc_read_binary(card, 0, buf, bufsize, 0); OOB Write in decrypt_response() In function decrypt_response() in file src/libopensc/card-epass2003.c an out of bounds overwrite can occur. No check is performed if the plaintext buffer fits into the out buffer before copying, leading to a memory overwrite. memcpy(out, plaintext, in_len - 2); *out_len = in_len - 2; return 0; OOB Write in cac_get_serial_nr_from_CUID() In function cac_get_serial_nr_from_CUID() in file src/libopensc/card-cac.c a serial number is copied into serial->value. The length argument of the memcpy() is the length of the source, not the destination, which can lead to an out of bounds memory write. if (priv->cac_id_len) { serial->len = MIN(priv->cac_id_len, SC_MAX_SERIALNR); memcpy(serial->value, priv->cac_id, priv->cac_id_len); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); } Off by One Write in sc_pkcs15emu_esteid_init() In function sc_pkcs15emu_esteid_init() in file src/libopensc/pkcs15-esteid.c an off by one write with a \x00 occurs in case the sc_read_record() functions returns sizeof(buf) read bytes. /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed"); buff[r] = '\0'; Double Free in sc_file_set_sec_attr() In function sc_file_set_sec_attr() in file src/libopensc/sc.c a double free occurs in case sec_attr_len is equal to 0, since the call to realloc() will free file->sec_attr and return NULL. The variable is then freed again in the error handling path. tmp = (u8 *) realloc(file->sec_attr, sec_attr_len); if (!tmp) { if (file->sec_attr) free(file->sec_attr); file->sec_attr = NULL; file->sec_attr_len = 0; return SC_ERROR_OUT_OF_MEMORY; } Double Free in read_file() In function read_file() in file src/tools/egk-tool.c a double free can be triggered in case two calls to sc_select_file() return a file->size of zero. The first call to realloc() frees the memory, the second frees it again. len = file - file->size : 4096; p = realloc(*data, len); if (!p) { goto err; } It is clearly checked whether the buffer is big enough to hold the data copied using memcpy(), but no error handling happens to avoid the memcpy() in such cases. This code path can be triggered with malicious data coming from a smartcard. Double free in sc_pkcs15emu_sc_hsm_init() In function sc_pkcs15emu_sc_hsm_init() in file src/libopensc/pkcs15-sc-hsm.c a double free can occur, since this function can be called twice. The call to realloc() with a size of 0 would free priv->EF_C_DevAut with a second call freeing the already freed memory. /* save EF_C_DevAut for further use */ ptr = realloc(priv->EF_C_DevAut, len); if (ptr) { memcpy(ptr, efbin, len); priv->EF_C_DevAut = ptr; priv->EF_C_DevAut_len = len; } ptr = efbin; Unbound Recursion in iasecc_select_mf()/iasecc_select_file() Function iasecc_select_file() in file src/libopensc/card-iasecc.c calls iasecc_select_mf() in the same file, which calls iasecc_select_file() again. This can lead to an infinite recursion exhausting the stack. Timeline 2018-02-03 Issues found 2018-04-18 Vendor contacted 2018-04-18 Vendor reply 2018-05-18 Technical details provided 2018-05-24 Private git branch created, fixing started 2018-08-11 Patched version released: https://github.com/x41sec/OpenSC Author: Eric Sesterhenn Copyright (C) X41 D-SEC GmbH 2018 - -------------------------------------------------------------------------- X41 D-Sec GmbH Security Advisory: X41-2018-004 Multiple Vulnerabilities in Yubico libykneomgr Overview Confirmed Affected Versions: 0.1.9 Confirmed Patched Versions: - Vendor: Yubico / Depreciated Vendor URL: https://www.yubico.com/ Credit: X41 D-Sec GmbH, Eric Sesterhenn Status: Public Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2018-004-libykneomgr/ Summary and Impact An out of bounds write and read was discovered when malicious responses from a smartcard are received. These might lead to memory corruptions. We assume that these are not easily exploitable. X41 did not perform a full test or audit on the software. Please note that the library is deprecated for more than a year and no update will be published by the vendor. Product Description This is a C library to interact with the CCID-part of the YubiKey NEO. There is a command line tool "ykneomgr" for interactive use. It supports querying the YubiKey NEO for firmware version, operation mode (OTP/CCID) and serial number. You may also mode switch the device and manage applets (list, delete and install). Out of Bounds Read/Writes Severity Rating: Medium Vector: APDU Response CVE: 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 File lib/backend_pcsc.c contains the following code in function backend_applet_list() { size_t i; size_t this_len = recv[length++]; for (i = 0; i < this_len; i++) { if (appletstr) { if (real_len + 2 > *len) { return YKNEOMGR_BACKEND_ERROR; } sprintf (p, "%02x", recv[length]); p += 2; } real_len += 2; length++; } if (appletstr) { if (real_len + 1 > *len) { return YKNEOMGR_BACKEND_ERROR; } *p = '\0'; p++; } real_len++; length += 2; } There is an off-by-one write of a '\x00' when the sprintf() is called, since it terminates the string with a trailing null-byte. Additionally reads are performed based on this_len, which is retrieved from the data without further safety checks. Workarounds It is advised to migrate to YubiKey Manager since the vendor does not support the library anymore and will not issue a patch. Timeline 2018-02-03 Issues found 2018-05-22 Vendor contacted 2018-05-22 Vendor reply 2018-06-05 Requesting technical feedback from the vendor 2018-06-06 Vendor confirms bug, but states that library is depreciated, will not be fixed Author: Eric Sesterhenn Copyright (C) X41 D-SEC GmbH 2018 - -------------------------------------------------------------------------- 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 Copyright (C) X41 D-SEC GmbH 2018 - --------------------------END INCLUDED TEXT-------------------- You have received this e-mail bulletin as a result of your organisation's registration with AusCERT. The mailing list you are subscribed to is maintained within your organisation, so if you do not wish to continue receiving these bulletins you should contact your local IT manager. If you do not know who that is, please send an email to auscert@auscert.org.au and we will forward your request to the appropriate person. NOTE: Third Party Rights This security bulletin is provided as a service to AusCERT's members. As AusCERT did not write the document quoted above, AusCERT has had no control over its content. The decision to follow or act on information or advice contained in this security bulletin is the responsibility of each user or organisation, and should be considered in accordance with your organisation's site policies and procedures. AusCERT takes no responsibility for consequences which may arise from following or acting on information or advice contained in this security bulletin. NOTE: This is only the original release of the security bulletin. It may not be updated when updates to the original are made. If downloading at a later date, it is recommended that the bulletin is retrieved directly from the author's website to ensure that the information is still current. Contact information for the authors of the original document is included in the Security Bulletin above. If you have any questions or need further information, please contact them directly. Previous advisories and external security bulletins can be retrieved from: https://www.auscert.org.au/bulletins/ =========================================================================== Australian Computer Emergency Response Team The University of Queensland Brisbane Qld 4072 Internet Email: auscert@auscert.org.au Facsimile: (07) 3365 7031 Telephone: (07) 3365 4417 (International: +61 7 3365 4417) AusCERT personnel answer during Queensland business hours which are GMT+10:00 (AEST). On call after hours for member emergencies only. =========================================================================== -----BEGIN PGP SIGNATURE----- Comment: http://www.auscert.org.au/render.html?it=1967 iQIVAwUBW3Oww2aOgq3Tt24GAQi5ig/7BY5I+s+NgCKcOd0XnXLqU+a5qC5c1zW9 4Zt9PMnRJS3+68B/toAmF11chjIPAv5BsoFoxUvFUKJb6hRJl77msdXWz4XiE1Ip F3kwcxut0cxykYjAv/Ilc5s6MTIrnaKhOuouKRACpvA8oDoNNl2CTpeKOmHC1rLM XsRnKiBxc0qhblhF4ZmWaW89TY+mSL39JQDb7CIBPhKPnIZ4OKDk0FpYX4CPYaSu YIgZ4x+J+Vj2SF9Mt/TL2vcJMl2NXeEGB+UEQHSWkRqUkM9k4kXKDk4oHn2i6D3c XCm87j3HEE8GfWLzru9P5Fnuk6wfbbRJEnxu3ctJHN2jR4emLt+9/Ax4GrZC2FPY cty4YfdTICmpHkSLbPTKE6KBC4WK4M87SWEP+Lfu0D7du7YvOVCV+PQcOKGGChrw 8SC+CIwiE9Rlx4F/tf//HYgypV3i1UX9POeK4DzZRZgQrHKN6HdRAn2zhGPIaXf5 NC/ck9wtkAvs7x4y10qxpQpy2sthJUTdhxRVGpxg9WzgIo51ZIxB57SJa8F9VT1o FLaun2w0ZwINJ8sT4rjRuH/jcMVQAm9tyYqBfVDNjOeJduIHh3/yw/JAo6yvJqvn Deon/oIbawtNdwnC6nuXPLMebkg7/aKMz3CUTpY1M8hgNXeDTmdVrKFcWdqNxFUt S7OCLfjWKH4= =U3EO -----END PGP SIGNATURE-----