117 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ---
 | |
| layout: post
 | |
| title: "Trouble with OCSP"
 | |
| date: 2019-08-06
 | |
| comments: true
 | |
| tags: ocsp, tor, security, privacy
 | |
| ---
 | |
| 
 | |
| > This is a post about side channel information leak present in OnionBrowser OCSP requests. This post omits a lot of details about OCSP protocol.
 | |
| 
 | |
| Digital certificates usually have long expiration, to reduce
 | |
| maintenance overhead. Most of the cases CAs issue a certificate for
 | |
| few years.
 | |
| 
 | |
| But what are we to do when a certificate is compromised? We can
 | |
| re-issue a certificate, but compromised certificate is still in the
 | |
| wind. Online Certificate Status Protocol (OCSP) is designed to help
 | |
| with this exact situation. It defines a way to check validity of a
 | |
| certificate in a timely[^1] manner.
 | |
| 
 | |
| OCSP[^2] works roughly as follows in an https connection:
 | |
| 
 | |
| 1. Client looks up the OCSP responder server from `AuthorityInfoAccess` section in the certificate.
 | |
| 2. Client crafts a OCSP request and sends it to OCSP responder (server provided by the CA).
 | |
| 3. Responder returns the current status of the certificate, one of `good`, `revoked` or `unknown`
 | |
| 
 | |
| There are many other interactions defined in the OCSP ecosystem. Maybe the most important one is [OCSP Stapling](https://en.wikipedia.org/wiki/OCSP_stapling). In stapling the original request server sends back OCSP validation message with the certificate itself, removing the need for another seperate request.
 | |
| 
 | |
| ## Dissecting an OCSP Request
 | |
| If the request is less than `255 bytes`, OCSP allows it to be passed as a GET path. A typical request looks like this
 | |
| 
 | |
| ```bash
 | |
| GET http://ocsp.int-x3.letsencrypt.org/MFgwVqADAgEAME8wTTBLMAkGBSsOAwIaBQAEFH7maudymrP8%2BKIgZGwWoS1gcQhdBBSoSmpjBH3duubRObemRWXv86jsoQISA6D%2BPqgUVCy3wtolHIxq%2Bk0e
 | |
| 
 | |
| ```
 | |
| 
 | |
| The request is  `URL-Encoded > BASE64 encoded > ASN-1` data. After decoding, one can use `ocsptool` from [GnuTLS](https://www.gnutls.org/) to read it.
 | |
| 
 | |
| ```bash
 | |
| echo -n "MFgwVqADAgEAME8wTTBLMAkGBSsOAwIaBQAEFH7maudymrP8%2BKIgZGwWoS1gcQhdBBSoSmpjBH3duubRObemRWXv86jsoQISA6D%2BPqgUVCy3wtolHIxq%2Bk0e" \
 | |
| 	| python -c "import sys, urllib.parse as ul; print(ul.unquote(sys.stdin.read()));" \
 | |
| 	| base64 -d \
 | |
| 	| ocsptool -i
 | |
| OCSP Request Information:
 | |
| 	Version: 1
 | |
| 	Request List:
 | |
| 		Certificate ID:
 | |
| 			Hash Algorithm: SHA1
 | |
| 			Issuer Name Hash: 7ee66ae7729ab3fcf8a220646c16a12d6071085d
 | |
| 			Issuer Key Hash: a84a6a63047dddbae6d139b7a64565eff3a8eca1
 | |
| 			Serial Number: 03a0fe3ea814542cb7c2da251c8c6afa4d1e
 | |
| ```
 | |
| 
 | |
| .. and then lookup the cert parameters
 | |
| 
 | |
| ```bash
 | |
| curl https://crt.sh/?serial=03a0fe3ea814542cb7c2da251c8c6afa4d1e
 | |
| ```
 | |
| 
 | |
| ```bash
 | |
| ...
 | |
|  Issuer: (CA ID: 16418)
 | |
|                           commonName                = Let's Encrypt Authority X3
 | |
|                           organizationName          = Let's Encrypt
 | |
|                           countryName               = US
 | |
|                       Validity
 | |
|                           Not Before: Mar 29 00:08:51 2019 GMT
 | |
|                           Not After : Jun 27 00:08:51 2019 GMT
 | |
|                       Subject:
 | |
|                           commonName                = check.torproject.org
 | |
| ...
 | |
| ```
 | |
| 
 | |
| ## Privacy Takes a Backseat.
 | |
| 
 | |
| Careful examination of above workflow will reveal that the OCSP flow
 | |
| is happening over HTTP. With the above dissecting example, an attacker
 | |
| will know that it is highly probable that user is accessing
 | |
| <https://check.torproject.org>.
 | |
| 
 | |
| Most issuers seem to stick to http; possibly to avoid cyclical
 | |
| dependencies. This means man-in-the-middle leakage of certificates a
 | |
| user is validating is happening, and by extension leakage of websites
 | |
| user is accessing.
 | |
| 
 | |
| ## Onion Browser
 | |
| iOS has inbuilt mechanism for checking revocations. They seem to be
 | |
| only enforced for
 | |
| [EV](https://en.wikipedia.org/wiki/Extended_Validation_Certificate)
 | |
| certificates though. This is not a bad thing at all, but it creates a
 | |
| weird situation where it leaks urls with EV certs from [Onion
 | |
| Browser](https://apps.apple.com/us/app/onion-browser/id519296448). Semi-Official
 | |
| (as far as I can tell) Tor browser on iOS.
 | |
| 
 | |
| Whenever Onion Browser accesses a website with EV cert, (for e.g
 | |
| <https://check.torproject.org>), the OCSP request is routed via
 | |
| **regular** transport, not via onion network as one would assume.
 | |
| 
 | |
| An attacker observing network can see any of the OCSP requests, and
 | |
| thus know a subset of sites user is visiting, even if they are on Tor.
 | |
| 
 | |
| A weird detail is that the [**`.onion` endpoint of NYTimes has
 | |
| an EV certificate**](https://crt.sh/?id=939411753). The ocsp request
 | |
| for it is send via plain transport and gets leaked, if you were using
 | |
| OnionBrowser to access it.
 | |
| 
 | |
| I stumbled upon this accidently while inspecting requests from my
 | |
| iPhone with [mitmproxy](https://mitmproxy.org/). The bug was reported
 | |
| to Onion Browser team and [they have a nice write up of the
 | |
| situation](https://github.com/OnionBrowser/OnionBrowser/wiki/2019-178:-sites-with-EV-HTTPS-certificates-leak-information-via-OCSP). Unfortunately,
 | |
| it is hard to fix. :-(
 | |
| 
 | |
| > Many thanks to [\@konarkmodi](https://twitter.com/konarkmodi) for helping me verify my findings and reviewing this post.
 | |
| 
 | |
| [^1]: Opposed to checking against a [Certificate Revocation List](https://en.wikipedia.org/wiki/Certificate_revocation_list).
 | |
| [^2]: Familiar readers will note that this is plain OCSP, the non-stapling kind.
 | 
