lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <201303201454.r2KEsB0H058328@pikmeer.webweaving.org>
Date: Wed, 20 Mar 2013 14:54:11 GMT
From: Dirk-Willem van Gulik <dirkx@...weaving.org>
To: full-disclosure@...ts.grok.org.uk
Subject: CVE-2013-1866: OpenSC.tokend - privacy leak &
	arbitrary file creation (OSX, All versions)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

OpenSC.tokend (1,2) is a Tokend module for OS X CDSA/Keychain subsystem for
accessing smart cards. As is common in such bridges to a relatively slow
medium (chipcards in readers on serial/USB); tokend relies on a cache.

This cache is kept in /var/db/TokenCache. This directory is root owned and
its content only readable by root. It contains directories on a per
chipcard, per token basis. The name for this directory is constructed using
the label of the card, its serial number and the label of the token. These
can contain arbitrary UTF8 strings up to 255 bytes long when exposed
directly through OpenSC.tokend (PKCS#15) its module as picked up by the
the securityd. (There is a related issue with OpenSC its pkcs#11 driver 
via Gemalto/Apple's tokend plugin and then onto securityd; See CVE-2013-1867)

This makes it possible for an attacker to construct card labels or token
labels that may cause the overwriting (by a root process) of somewhat
arbitrary directories (and in some cases files) on the file system (somewhat
limited by a length constraint on the card and token-label) upon insertion.
Symbolic links are followed without ado. As tokend generally runs at all
time - such insertion can be done even when the user is logged out or the
screen locked.

CVE: CVE-2013-1866

Impact:
- -------

1) An attacker with physical access to a reader can create/corrupt a wide
range of directories on the file system.

2) An attacker with physical access to a legitimate smart card (holder) can
substitute/reprogram an existing card to do such when the legitimate 
holder inserts the doctored card at some later point[5].

3) As errors are logged to a public-readable log file - some information
about which token was inserted at what time leaks inadvertently. 
This has issues in certain setting[7]. Such leakage can also be 
'caused' by making the cache directory or disk in-accessible/full.

4) In certain (possibly common) circumstances the attacker can cause one card
to (re)use the cache of another card[6].

5) The attack can be executed with an existing chipcard, already in use
within the organisation; or with virtually any other chipcard (including
blank unprogrammed chipcards) provided that at least one of the token
plugins is able to read the card. 

6) Above also applies to so called 'USB Token's; which are technically
chipcards hardwired (or in the form of a small physical form factor
SIM card) into a reader in a convenient USB thumb-drive style enclosure.

Versions affected:
- ------------------

1) All builds prior to 15th of March 2013; all versions of OSX.

On affected systems syslog will generally show entries such as

	com.apple.SecurityServer[829]: reader RRR inserted token "XX" (XXX) 
		subservice DD using driver com.apple.tokend.opensc

where XXX is a label on the chipcard. 

A failed exploit attempt will appear as

	OpenSC[PID]: error writing cache file: /var/db/TokenCache/...

follewed by errors such as 'Permission denied' or 'No such file or directory'.

Note that a perfectly executed exploit will not leave such traces.

Solution:
- ---------

The 0.13.0 build of 2013-03-19 (or later):

     https://www.opensc-project.org/downloads/macosx/

includes a full and complete fix.

Mitigation:
- -----------

1) Limit physical access; make personnel aware of the risks of inserting a
'rogue' card or loosing control of a card temporarily and using 
it subsequently. Note however that most installations allow the reprogamming
of an already inserted card its (outer) label without root access.

2) Manually upgrade to a version of OpenSC.tokend later than commit:

     c013f819104280eac758d15a57d1aa4848c35654.

3) Update using the attached patches.

4) Consider pruning the installed security agent bundles to an 
absolute minimum.

Note that (as some proprietary vendors may suggest) that removing the
OpenSC #15 based plugin and relying on the Gemalto/Apple PKCS#11 'tokend'
bridge into securityd instead is subject to a similar issue as
described in CVE-2013-1867.

Note that (as some proprietary vendors may suggest) removing the OpenSC 
plugins and PKCS#11 libs and switching to a different vendor is also 
subject to the issue described in CVE-2013-1867 (as it happens one
layer 'higher').

Likewise even though an existing installation may not use tokend or 
may use a vendors plugin that filters/curtails the label - the insertion 
of a different brand of card may still be used to bypass that specific 
vendor's protection when it gets picked up by a (previously possibly
dormant) plugin. 

Long term solution
- ------------------

1) Upgrade OpenSC.tokend to a release post March 2013.

Timeline & Credits:
- -------------------

Discovered by Dirk-Willem van Gulik (dirkx@...weaving.org) as part of the
Artemis/EU project HighProfile. Fix applied to the release branch by 
Martin Paljak.

Footnotes:
- ----------

1: https://www.opensc-project.org/opensc/wiki/MacInstaller 

2: https://github.com/OpenSC/OpenSC.tokend 

3. Although some implementations inadvertently stick/limit this to
16 safe characters the actual range is is defined in 6.1.3 as UTF8 up 
to pkcs15-ub-label charcters (255)[4]. So while arguably too accomodating,
driver authors are 'right' in passing dubious strings up.

4: PKCS #15 v1.1: Cryptographic Token Information Syntax Standard, 
RSA Laboratories June 6, 2000 
<ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-15/pkcs-15v1_1.pdf>

5: it is common for end-user cards to be shipped in read-only state. 
However ti is not uncommon that cards issued can be re-labed with the 
same end-users tools that allow for a PIN change; especially if one 
is willing to re-initialize the card. Common card setups do not require 
the SO/PUK for this - i.e. the card is left 'open' at user level, as 
the cards label is may be seen as outside the card protected area,
e.g. if the card allows for end user PIN changes.

6: E.g. in setttings where the permissions hierarchy is relatively
flat and/or largely relies on identification (with the card carrying
little implied authorization information).

7: E.g. in enterprise settings where such information is shared 
by syslog.

Patches:
- --------

https://github.com/OpenSC/OpenSC.tokend/commit/c013f819104280eac758d15a57d1aa4848c35654
https://github.com/OpenSC/OpenSC.tokend/commit/a62eca9f94f8a60b9fb21d513ae157e643c0c8cd

Index: OpenSC/OpenSCToken.cpp
@@ -32,8 +32,12 @@
 #include "OpenSCRecord.h"
 #include "OpenSCSchema.h"
 #include <security_cdsa_client/aclclient.h>
+#include <CommonCrypto/CommonDigest.h>
+
 #include <map>
 #include <vector>
+#include <sstream>
+#include <iomanip>
 
 using CssmClient::AclFactory;
 
@@ -257,22 +261,25 @@ uint32 OpenSCToken::probe(SecTokendProbeFlags flags,
             score = scconf_get_int(conf_block, "score", score);
             sc_debug(mScCtx, SC_LOG_DEBUG_NORMAL, "  Get Score from config file: %d\n", score);
           }
- -          // Create a tokenUid
- -          if (mScP15Card->tokeninfo->label != NULL)
- -            strlcpy(tokenUid, mScP15Card->tokeninfo->label, TOKEND_MAX_UID);
- -          if (mScP15Card->tokeninfo->serial_number != NULL)
- -            strlcpy(tokenUid + strlen(tokenUid), mScP15Card->tokeninfo->serial_number,
- -              TOKEND_MAX_UID - strlen(tokenUid));
- -
- -          {
- -            /* replace non ASCII chars by '_' */
- -            int i;
- -            unsigned char *c = (unsigned char *)tokenUid;
- -
- -            for (i=0; tokenUid[i]; i++)
- -              if (c[i] > 127)
- -                tokenUid[i] = '_';
+
+          // Create a tokenUid - obscure the label somewhat as it is under
+          // control of the card issuer; and could contain naughtyness.
+          //
+          unsigned char md[CC_SHA1_DIGEST_LENGTH];
+          CC_SHA1_CTX ctx;
+          CC_SHA1_Init(&ctx);
+          CC_SHA1_Update(&ctx, mScP15Card->tokeninfo->label,
+            strlen(mScP15Card->tokeninfo->label));
+          CC_SHA1_Update(&ctx, mScP15Card->tokeninfo->serial_number,
+            strlen(mScP15Card->tokeninfo->serial_number));
+          CC_SHA1_Final(md, &ctx);
+
+          std::ostringstream out;
+          for (std::size_t i=0; i < MIN(TOKEND_MAX_UID/2,CC_SHA1_DIGEST_LENGTH); i++) {
+            out << std::setfill('0') << std::setw(2) << std::hex << (short) md[i];
           }
+          strlcpy(tokenUid,out.str().c_str(),TOKEND_MAX_UID);
+
           sc_debug(mScCtx, SC_LOG_DEBUG_NORMAL, "    score = %d, tokenUid = \"%s\"\n", score, tokenUid);
         }
       }
Index: Tokend/Token.cpp
@@ -33,9 +33,12 @@
 #include "RecordHandle.h"
 #include "Schema.h"
 #include <memory>
+#include <sstream>
+#include <iomanip>
 #include <security_cdsa_utilities/cssmaclpod.h>
 #include <security_utilities/unix++.h>
 #include <security_utilities/logging.h>
+#include <CommonCrypto/CommonDigest.h>
 
 //
 // SPI wrapper macros
@@ -799,10 +802,25 @@ void Token::cacheObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
 std::string Token::cachedObjectPath(CSSM_DB_RECORDTYPE relationId,
   const std::string &name) const
 {
- -  char buffer[9];
- -  sprintf(buffer, "%X", relationId);
+  unsigned char md[CC_SHA1_DIGEST_LENGTH];
+
+  // the name is in effect the label - and can be set to nefarious things
+  // such as '../../etc/foobar'; or alternatively get logged in the log
+  // file all to easily. So mask.
+  //
+  CC_SHA1_CTX ctx;
+  CC_SHA1_Init(&ctx);
+  CC_SHA1_Update(&ctx, &relationId, sizeof(relationId));
+  CC_SHA1_Update(&ctx, name.c_str(), name.length());
+  CC_SHA1_Final(md, &ctx);
+
+  std::ostringstream out;
+  out <<  mCacheDirectory << "/";
+  for (std::size_t i=0; i < CC_SHA1_DIGEST_LENGTH; i++) {
+    out << std::setfill('0') << std::setw(2) << std::hex << (short) md[i];
+  }
 
- -  return mCacheDirectory + "/" + buffer + "-" + name;
+  return out.str();
 }
 
 Cursor *Token::createCursor(const CSSM_QUERY *inQuery)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQCVAwUBUUnNhzGmPZbsFAuBAQJ0lAP8CT/ftKTvxbys/WFwQj3nounRtp+yXovo
wj23G7Lh3NokJFwrHsvfFDmS1bNJO2ZHaC2udVW8kwCxCr6LB9L0Wcv+7NSCHO/W
cjkxlN9zw+ghSRTkwKLPjYFJg+jKUEBzyiX6PUE6Meiv6sfOlgvS+DOhx/wLpdwZ
cfHFYjGnKho=
=EbOP
-----END PGP SIGNATURE-----

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ