carl mehner's blog

OS X Keychain Key Export Authentication Bypass

This vulnerability allows anyone, with log-on access to an OS X machine, the ability to export private keys from the system keystore of OS X. Normally, there are two ways to stop this, only system administrators would have access to use or export system keys and they can be made non-exportable for any user. However, for this vulnerability, those two mitigations matter not. Normally, one would need to authenticate as an administrator, but as you can see below, Apple’s authentication procedure does not error out properly. This means that if an administrator has deployed a certificate solely, meant for system use, anyone else now can use it for their own purposes.

Note:I believe this is the same as CVE-2015-7058, however, I never recived official confirmation of that from Apple. It does seem the same, and appears to be fixed at this time.


Disclosure Timeline:

Technical Details & Description

Affected Product Details:

OS X before 10.11.2
Apple iOS before 9.2
Apple tvOS before 9.1

Security Risk:

A non-privileged user is able to export keys and certificate they should not have access to export. Additionally, they are able to deactivate the non-exportable flag on the key if it was originally imported with '-x'.

How to recreate results / PoC:

Prerequisites

Either:
An asymmetric key exists in the system keystore and is marked as non-exportable. A user (with administrator or non-administrator system access) exists such that said user desires the p and q (aka. private key).

Or, an asymmetric key exists in the system keystore that is exportable by administrators only. A non-administrator exists that wants the key.

The "Attack"

A user logs into the machine. Open Keychain Access, select the system keystore Select the key to export, perform a 'secondary click' (aka 'right-click') on the key, select the export menu item.

A prompt appears asking for a location to save the key:
Choose a place to save the key
A prompt appears to request administrator level credentials:
Gently press the escape key once.
The key is now exportable (if it wasn't before).
A prompt appears to set the exported key’s passphrase.
Choose to enter a password, or leave it blank. Click OK.
The user now has a pkcs#12 file complete with the private key.
Speculation below!

From what I can tell, the code would be something similar to this:



public void exportCertFromKeychain(certID cert) {
bool exportable = true;
	// get place to store exported cert 
	// this should only happen after authorization!
	filename f = getExportLocation();
	// check if access is locked down to only allow
	//   administrators, or if it is non-exportable
	if(isProtected(cert)) {
		// get Authorization 
		int authResult = authenticateAdmin();
/* Authentication returns several different codes
0 is errAuthorizationSuccess
-60005 is errAuthorizationDenied
-60006 is errAuthorizationCanceled */
		if(authResult == 0)
			// here is the non-exportable bug
			// this should be the first thing checked..
			if(markedNonExportable(certID))
				exportable = false;
else if(authResult == -60005) // here is the admin bug
			exportable = false;
		// they should check if 'authResult' was 0,
		// and if not, set the value to false
		// when you cancel, the result is -60006
		// and 'exportable' remains true.
		
	}
// get export password
	string pass = getPassword();
	if(exportable) {
		exportCert(f, cert);
	} else {
		showError();
	}
}


PGP ASCII Art

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

mQENBFWE8g8BCADWwAC1DXKsqGPZU0/OlzZvXr7waI1a15VdeocA5ILIU4IoSlne
9ZLhH/38qRWyk2sS8BtaD3DbA1Izz0STuiztyVOjbKk0yjKL3pWwpaWajD5AyhvV
Ln50e4s9RfyLw1OnOtCeN4G9OgR7Rrqr4JPdF09wUFgYVUWdeOmw9MGIdfTXadey
sU4vTt0maghZa0wDdcnfNFK/7VWJpbqttHncWWLAkLqhirSZA6wU4GRWlNQvsYbJ
BRVs+YrzewxpmBdiIjaTCeBSJPlEyLWlMw6ZPqzheSHjksuL6ElgDP5BZzYAPGCT
xrVHztT2u79M1I/wpPylGaaZgg+D2coTFIAvABEBAAG2AAACt0NhcmwgTSAoLi4u
XC4rIXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXC4rIXxX
I11II11II11II11II11II11II11II11II11II11II11II11II11II11II11II11I
I11I
O000O000O000I11IO000O000O000I11IO000O000O000O000O000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000O000O000O000O000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11IO000I11IO000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11IO000I11IO000I11II11I
I11I
O000I11II11II11IO000O000O000I11IO000I11IO000I11IO000I11II11I
I11I
O000I11II11II11IO000O000O000I11IO000I11IO000I11IO000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11II11II11IO000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11II11II11IO000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000I11II11II11IO000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000I11II11II11IO000I11II11I
I11II11II11II11II11II11II11II11II11II11II11II11II11II11II11II11I
XC4rIXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXC4rIXxX
KSA8Y0BjZW0ubWU+iQE4BBMBAgAiBQJVhPIPAhsDBgsJCAcDAgYVCAIJCgsEFgID
AQIeAQIXgAAKCRBrDTHS1xnT+4mjB/0VXjlVNflzT3qaseILatLSSAt2t1nnBGxs
iJVdgIlQj2vYgb6IkmkeEsmu6avAgFktM0zM5uosx+VDxdI5v1CIUqxjWSDhOeMK
Q3E9BEK/yRrehPKe3Y/NAwaVI67C393jRSuVFPoNFViNfr1ZJU8TGUYOnO2ap+9Q
XlPdEXWXEyXg9luXOJl8H95XX+7b7DiStfAn3A4SXhtChDpMEkSdMD+brryB65Wh
epc7BIqkQyG0w70z22KUXDPeOEdmhEY03grMBpF4MguU7bmHQgI8wFY6rFde7RXz
4djsY/CILcITJcFVM0kThsMphsqLUVCvdFeK/vdZUazA3U/fnj7XuQENBFWE8g8B
CADYXMKMFTfq4BNF66KvI4uAlEg+zQyMRV49IAlxXA3oCKlkxzKvsvACOfjjvPcd
5DLkYA9PYZVaSWO4EU70F9chxxPA5Qkz7Y6/0wL5X3hD0fbmLtr6d0EzclhJPJ6a
XAcVBsY6QZRK4ulHp1xDbGnxVbL+Gi0w0gqKSa5vI94+aP+zFdBUFvZAa9hL7ez3
nm3V8H62X3Tj0Q8eCtCb3dgvDo4dRRJPOXAmydpCCZbH4EF8qI9d5Oup3FW6I8K+
5Zj5OfNAwSnsp3aTIBDq2BxxN6w0CwmnBxMDjho1KwBnxDF5DAX0kJGUjAQr7EGy
23SVqbXxVByWB2pGMIY1ZoozABEBAAGJAR8EGAECAAkFAlWE8g8CGwwACgkQaw0x
0tcZ0/s8ZwgAunktEwPOVDTqcDn39xigdslKikqWFZGZZlp2XwIUToc+wH6qAw8h
/Fc+gXT9YWc+866E3GNOuNAjY4mF/7mLorIhyVuL4lfdfxq33AKa55Bb2QpBc7iA
nVt1knLWBJ9sr2SaFsGDxEfRIJ3OxcXQOCfxtSzLnaH4TnVN45yflCkhcObYVg7X
1sReDDoRJmROOwi+riinSbohVRcNydx6RxaI3acH939IeGCCUUKvd87ShZjw/MxP
8Z6U0qgNnXrOWtTFjLkSt0e1p1JKklc0TYkIwCaSVYeTYH/ycgEg2m/HfKMQueBY
z8QGH8j84zQb4rjCI1gIwfQUbK/bmzcV7A==
=JyOF
-----END PGP PUBLIC KEY BLOCK-----

While I was making the PGP Poster I noticed that the User ID Packet, while broken apart in the UI into: Name, Email, and Comment, was in actuality just a large UTF-8 string. My imagination was spurred on by thoughts of interesting things I could do in that field, I recalled the math done by Ryan Castellucci allowing him to embed messages in an SSL certificate's public key. However, that only allowed for around one line of text, and the message had to be short to not affect the resultant prime. I wanted to be able to create a multiline message that would allow the creation of ASCII-style art. Of course, the User ID packet in the PGP key is ideal since you can put a large amount of arbitrary UTF-8 text inside.

The hardest part is translating UTF-8 into Base64 art. You cannot simply create a great piece of Base64 ASCII Art and throw it into the User ID packet because you first need valid UTF-8.

The translation between UTF-8 and Base64 is tricky because they are 8 and 6 bits respectively. One way to consistently take care of this problem is to find the least common multiple of 6 and 8, which is 24. Dividing 24 by 6 shows that we will have 4 Base64-character blocks to use as our building blocks for the ASCII Art (which if you have not figured out by now is really UTF-8 Art… but that is not as fun to say and there is really not a big difference).

The image below illustrates that showing UTF-8 characters translated into binary (split into 8-bits) and that binary, evenly divided into 6-bit chunks and translated into Base64. utf8 to base64 translation

Next, I wrote a script that printed out all of the valid UTF-8 characters in groups of 3 as translated to the 4 characters of Base64.


#!/usr/bin/python
import base64

for x in range(33, 127) : # printable utf-8
    for y in range(33, 127) :
        for z in range(33, 127) :
            s = chr(x) + chr(y) + chr(z)
            print (base64.b64encode(s, None))

This was a bit unwieldy; rather than search through nearly a half million patterns, I wrote some regex to map out a few of the groups of characters that I thought would make good candidates.

I came up with a few patterns to use; XC4r IXxX XXxX to put across the top and bottom (hint: it spells out ‘xCARLxxxxxxx’) then, to spell out CEM in the middle I used I11I and O000.

The next thing is to pad out the beginning of the User ID packet up to the output newline boundary. This was done by calculating the amount of characters needed and adding that many spaces to the front part of the User ID packet using my poster from the previous post.

Finally, start the key generation process and when it is time for the User ID input part, the default format from PGP keys is <Name> (<Comment>) <Email>. Make sure you factored the name and open parenthesis into the padding you needed, type the name and then, when asked, paste in the UTF-8 encoded Base64 ASCII art. The key generates encoding your glorious block of ASCII art. Print it out in the ASCII Armor'd Radix-64 that we all know and love as a PGP Key and behold:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

mQENBFWE8g8BCADWwAC1DXKsqGPZU0/OlzZvXr7waI1a15VdeocA5ILIU4IoSlne
9ZLhH/38qRWyk2sS8BtaD3DbA1Izz0STuiztyVOjbKk0yjKL3pWwpaWajD5AyhvV
Ln50e4s9RfyLw1OnOtCeN4G9OgR7Rrqr4JPdF09wUFgYVUWdeOmw9MGIdfTXadey
sU4vTt0maghZa0wDdcnfNFK/7VWJpbqttHncWWLAkLqhirSZA6wU4GRWlNQvsYbJ
BRVs+YrzewxpmBdiIjaTCeBSJPlEyLWlMw6ZPqzheSHjksuL6ElgDP5BZzYAPGCT
xrVHztT2u79M1I/wpPylGaaZgg+D2coTFIAvABEBAAG2AAACt0NhcmwgTSAoLi4u
XC4rIXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXC4rIXxX
I11II11II11II11II11II11II11II11II11II11II11II11II11II11II11II11I
I11I
O000O000O000I11IO000O000O000I11IO000O000O000O000O000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000O000O000O000O000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11IO000I11IO000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11IO000I11IO000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000I11IO000I11IO000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000I11IO000I11IO000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11II11II11IO000I11II11I
I11I
O000I11II11II11IO000I11II11II11IO000I11II11II11IO000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000I11II11II11IO000I11II11I
I11I
O000O000O000I11IO000O000O000I11IO000I11II11II11IO000I11II11I
I11II11II11II11II11II11II11II11II11II11II11II11II11II11II11II11I
XC4rIXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXXxXXC4rIXxX
KSA8Y0BjZW0ubWU+iQE4BBMBAgAiBQJVhPIPAhsDBgsJCAcDAgYVCAIJCgsEFgID
AQIeAQIXgAAKCRBrDTHS1xnT+4mjB/0VXjlVNflzT3qaseILatLSSAt2t1nnBGxs
iJVdgIlQj2vYgb6IkmkeEsmu6avAgFktM0zM5uosx+VDxdI5v1CIUqxjWSDhOeMK
Q3E9BEK/yRrehPKe3Y/NAwaVI67C393jRSuVFPoNFViNfr1ZJU8TGUYOnO2ap+9Q
XlPdEXWXEyXg9luXOJl8H95XX+7b7DiStfAn3A4SXhtChDpMEkSdMD+brryB65Wh
epc7BIqkQyG0w70z22KUXDPeOEdmhEY03grMBpF4MguU7bmHQgI8wFY6rFde7RXz
4djsY/CILcITJcFVM0kThsMphsqLUVCvdFeK/vdZUazA3U/fnj7XuQENBFWE8g8B
CADYXMKMFTfq4BNF66KvI4uAlEg+zQyMRV49IAlxXA3oCKlkxzKvsvACOfjjvPcd
5DLkYA9PYZVaSWO4EU70F9chxxPA5Qkz7Y6/0wL5X3hD0fbmLtr6d0EzclhJPJ6a
XAcVBsY6QZRK4ulHp1xDbGnxVbL+Gi0w0gqKSa5vI94+aP+zFdBUFvZAa9hL7ez3
nm3V8H62X3Tj0Q8eCtCb3dgvDo4dRRJPOXAmydpCCZbH4EF8qI9d5Oup3FW6I8K+
5Zj5OfNAwSnsp3aTIBDq2BxxN6w0CwmnBxMDjho1KwBnxDF5DAX0kJGUjAQr7EGy
23SVqbXxVByWB2pGMIY1ZoozABEBAAGJAR8EGAECAAkFAlWE8g8CGwwACgkQaw0x
0tcZ0/s8ZwgAunktEwPOVDTqcDn39xigdslKikqWFZGZZlp2XwIUToc+wH6qAw8h
/Fc+gXT9YWc+866E3GNOuNAjY4mF/7mLorIhyVuL4lfdfxq33AKa55Bb2QpBc7iA
nVt1knLWBJ9sr2SaFsGDxEfRIJ3OxcXQOCfxtSzLnaH4TnVN45yflCkhcObYVg7X
1sReDDoRJmROOwi+riinSbohVRcNydx6RxaI3acH939IeGCCUUKvd87ShZjw/MxP
8Z6U0qgNnXrOWtTFjLkSt0e1p1JKklc0TYkIwCaSVYeTYH/ycgEg2m/HfKMQueBY
z8QGH8j84zQb4rjCI1gIwfQUbK/bmzcV7A==
=JyOF
-----END PGP PUBLIC KEY BLOCK-----

PGP Public Key

Pretty Good Privacy (PGP) has been around since 1991, it has since gained notoriety and ubiquity as one of the most popular[citation needed] person to person publication privacy programs. Now keybase.io and even Facebook are allowing users to receive encrypted communications from their systems, whether or not that is a good idea.

After learning about the ins and outs of certificate structures, I tuned to PGP to learn how they are put together. Some of it is quite elegant, and allows the format to save space, especially in the packet headers where 2 bytes can convey essentially the same information that take 6 bytes in x.509. PGP keys are made up of these packets, each packet is used to convey information about the key as a whole. By default, a key has 5 packets; Public Key (for signing), User ID (just text), Signature packet (times, algorithms, settings, and the Signature [over the Public Key, User ID, and most of the signature packet]), sub-key (for encrypting), and the sub-key signature.

Each header starts with a 8-bit value. The first bit is always set, the second is a switch between old and new packet styles (the new style is used for tag types represented by values larger than 4 bits, by default, keys just have old style), for the old style bits 3 through 6 indicate the packet type, the last 2 bits tell the number of length bits that immediately follow the header packet.

The public key packet contains the signing data and certifying other’s keys, the key for encrypting the data is the sub-key. The User ID packet is just UTF-8 data, this is normally a name, email address, and a comment from the owner (there is quite a bit of room here to store data... make sure you subscribe with feedly, or with rss here). The two signature packets are used to show binding between a held private key by signing the hash of the public key in the particular packet (key or sub-key), and the information specified in the signature packet. Within the signature packet, there are several sub-packets that can contain a multitude of data from signature time policy data like what the key should be used for. This data is encoded in various ways from actual integer values, to hexadecimal values denoting particular values, and binary values where each bit adds a new flag value.

Here is a posterized PGP key, it uses RSA keys (only 1024-bit for brevity) for both signing and encrypting and has an expiration date, the other values are just the OpenPGP defaults.

You can get a copy printed out here

PGP Public Key

PKI Posters

This is a series of posters and along with explanations of what they mean. They go through the entire lifecycle of an SSL certificate; from the creation of the p and q for the private key, to the signing from the certificate authority, and finally to the inclusion of the serial number in revocation structures.

This was originally released as a series of posts. They are still available here: (one, two, three, four, five, six, and seven.)

posters

If you want some high quality prints, or just want to support my work and get cool things to put on your wall you can do that here (you can get a PKI Poster Calendar and watch a cert throughout its lifecycle over a year).

HTTP DANE Validation Assertion

Certificates are typically authenticated via a chain of signatures that lead back to any one of a number of trusted roots. DNSSEC is validated much the same way, however, with DNSSEC there's only one root for delegating authority for the DNS while in certificates, any certificate authority can sign a certificate valid for any domain. There is a way to use this delegated system to verify connections made over TLS called DANE. In short, DANE is a way to use the DNSSEC to get signed records from an authoritative source to validate certificates used in TLS. You can see a great introduction to DANE by the working group co-chair here:
https://www.youtube.com/watch?v=emDxUQl1NvA
Also, some recent slides from a presentation by Dan York are here:
http://www.slideshare.net/Deploy360/3-dnssec-and-dane-ion-tokyo.

In all things there is risk, there are ways to mitigate risk using controls, some are detective controls (CT) some are preventative (DANE, Public Key Pinning). Other's have developed many different ideas in how to ensure that the certificate that makes it to the client's browser is the one which the site owner intended. Some have done analysis of the different methods [Ralph Holz][Ben Laurie][Matt Weeks]. A SecurityWeek article today even positions CT as a replacement for the preventive controls of TACK and DANE. I like certificate transparency (CT) as a way to detect CA compromise, but that is only after the fact (somthing I think that is not quite pointed out in the comparison chart at certificate-transparency.org or in Ben's ACM article from above). However, for a real-time preventitive control, I prefer DANE.


Recently, I uploaded a draft to the IETF with the goal of furthering the adoption of DANE.
https://datatracker.ietf.org/doc/draft-cem-dane-assertion/

hdva

Currently the adoption of DANE is lacking in browsers. The draft I wrote is to allow particular sites to declare themselves as ready to support DANE so that they can further lock down the security of their TLS connections. The method is to use an HTTP "Dane-Validation-Assertion" header or HDVA. I envision this as working as follows: A site sends the DVA header to a browser that tells the browser the browser will then do a lookup over DNSSEC for a TLSA (DANE) record to perform additional validations on the certificate.

Options for this header include the max time to keep/remember the assertion, a way to include subdomains, and a way to require a valid DANE response before continuing. The max-age and include-subdomains are used in the same manner as HTTP Strict Transport Security (HSTS) and HTTP Public Key Pinning (HPKP), the 'require' however, is a concept specific HDVA. The reason I included this directive was because the way DANE works; if you receive a certificate that is valid through the regular means of validating using certificate authorities (PKIX) and do not receive any DANE records, the connection will continue. By using the 'require' directive, the server operator forces the connection to be validated using the traditional method of CAs accompanied by DANE or solely by using DANE.

iOS 8.1 and CVE-2014-4449

Today, Apple released security advisory APPLE-SA-2014-10-20-1 for iOS 8.1 that includes CVE-2014-4449.

This relates to a TLS certificate validation vulnerability in the clients accessing iCloud affecting bookmarks, calendar, tasks, and possibly other data types allowing for modification and disclosure of data.

Exposure of sensitive reminders, meetings, bookmarks (including bookmarklets that could allow logins to other saved websites). Users may store sensitive data within these data objects that are synced to iCloud, these are at risk of exposure through this vulnerability.

...MORE DETAILS...

TLS Quotes

Just some completely random quotes about TLS following the POODLE vulnerability.

"Remember, everything less than TLS 1.2 with an AEAD mode is cryptographically broken."
-Adam Langley

"TLS_FALLBACK_SCSV is mainly about those vulnerabilities that we *can't* list there yet."
Bodo Möller

[Not?] Misissued Certificates:

or, how I was able to get over 2500 certificates for domains that I do not own

Four years ago, in 2010, Kurt Seifried released research on how certificate authorities (CAs) validated hostnames in SSL certificate requests. Colin Keigher followed on by with an actual implementation of that research resulting in his finding of five email providers that allowed the registering of addresses, which effectively allowed him to garner certificates for those domains.

I found that this avenue for procuring certificates still exists in at least two mail providers, which means that I was able to get upwards of 2,500 certificates for various domains that I do not own.

[...READ MORE...]

Bug in Chrome security feature can fill up your hard drive & crash the browser

The security feature in question is one that I have talked about before: HTTP Public Key Pinning (HPKP). This feature allows a website to tell the browser only to connect to the site if it is using a particular set of SSL certificates. For example, a site can specify that the browser only use a particular CA (certificate authority) or set of CAs when communicating with its servers.

On to the bug...

Without this patch an evil website has the ability to fill up your hard drive, or at least up to about 16 exabytes.

[...READ MORE...]

[...more...]