[HN Gopher] Exploiting the Windows Cryptoapi Vulnerability ___________________________________________________________________ Exploiting the Windows Cryptoapi Vulnerability Author : archgoon Score : 76 points Date : 2020-01-16 17:20 UTC (5 hours ago) (HTM) web link (blog.trailofbits.com) (TXT) w3m dump (blog.trailofbits.com) | archgoon wrote: | There is a bit of irony here; as the article mentions, the RSA | key that windows uses for updates is safe. | | Why is that ironic? Well, Trail of Bits also published this | article last year: | | https://blog.trailofbits.com/2019/07/08/fuck-rsa/ | | (Note, the points there are still valid. I just find it funny.) | lucb1e wrote: | I 100% recommend watching that talk near the top of the | article. It's a short talk of 20 minutes but even if you have | only time to watch the first 3, that's where the most | entertaining part is so still recommended. | acqq wrote: | Interestingly it's apparently Windows 10 (and corresponding | server) only. | dguido wrote: | For the short version, see our branded vulnerability page: | https://whosecurve.com | oefrha wrote: | Off topic, but this vulnerability was discovered by the NSA, | right? Then you're not really in the position to brand the | vulnerability, or you come off as trying to take credit where | credit isn't due. (I mean, you have every right to make a | website for it, but giving it a logo and say "Why even patch if | it doesn't have a logo?" as if it now has an official logo | seems to be taking it a bit far.) | | Please excuse me if I got the origin story wrong. | | Edit: Also, from the website: | | > Who's behind this? | | > Trail of Bits | | That could certainly be (mis)interpreted as taking credit for | the vulnerability. | tptacek wrote: | You would be misinterpreting them, since their page | explicitly credits NSA, cites other people's POCs, and even | the HN thread where I wrote down Thomas Pornin's (correct) | guess as to what the vulnerability was. | | The branding thing is a joke, about the fact that neither | Microsoft nor NSA branded the vulnerability. Lighten up. | user5994461 wrote: | The test site doesn't specify whether we have to use a specific | browser to test the vulnerability? I somehow doubt this affects | all desktop browsers IE, Edge, Chrome and Firefox. | | https://bad.whosecurve.com/ | drewbitt wrote: | Firefox is not effected | CiPHPerCoder wrote: | It affects IE and Edge on Windows 10. | | It should also affect Chrome on Windows 10 if you haven't | updated either your browser or your OS. | | It won't affect Firefox on either platform. | kortilla wrote: | Why does a vulnerability need a brand? | dguido wrote: | Do you remember the CVE number of this bug? How about the | Citrix bug from last week? It's a poor way to communicate, | and there's very strong anecdotal evidence that using a real | name promotes patching rates faster than otherwise. | | Plus, the whosecurve.com website includes the information you | want if you only have 10 seconds and it's by the same authors | as the blog linked in the OP. | JshWright wrote: | It has the added "benefit" of making it appear to the | casual observer that Trail of Bits found the vulnerability | in the first place... | tptacek wrote: | The fact that their writeups all credit NSA and link to | other people's descriptions of the vulnerability has the | "benefit" of ensuring that you have to _want_ that | misconception in order to end up with it. | pixl97 wrote: | So IT can tell the Cxx that yes, this problem is so important | to patch that it has a name. Saying we should apply KB123ABC | isnt as productive. | SolarNet wrote: | Correct me if I am wrong, but it seems like firefox (and maybe | chrome) would never have this vulnerability as they use their own | cryptography libraries for everything. | reaperhulk wrote: | Firefox is not vulnerable, but (non-updated) Chrome actually is | (until they replace the platform TLS verifier, which is | happening soon). | CiPHPerCoder wrote: | Chrome already added countermeasures, if it was updated: | | https://chromium- | review.googlesource.com/c/chromium/src/+/19... | technion wrote: | Does anyone have a clear answer on exactly what version I | need to look for/wait for to know this countermeasure is | rolled out? Edit: Found it: | https://chromereleases.googleblog.com/2020/01/stable- | channel... | | Version 79.0.3945.130. | Fnoord wrote: | I suppose a home user desktop machine still uses Windows | Update, and therefore downloads updates with an embedded Edge. | munchbunny wrote: | Maybe. The question isn't "are you using your own cryptography | libraries for cryptographic operations." The question is "are | you using Windows's native certificate chain validation API, or | did you write your own?" | | Even if Firefox/Chrome use their own implementations of | cryptographic algorithms, there's a decent chance that they are | still using Windows's native API for certificate chain | validation in order to plug into the enterprise certificate | management features that come baked into Windows, which IT | teams sometimes use to distribute internal PKI's. Without | having seen how Firefox and Chrome deal with their chain | building, I can't say "yes" or "no" definitively. | SolarNet wrote: | Looking at it they don't even load crypt32.dll so unless one | has a modified version of firefox, or an external plugin, it | seems unlikely they have the vulnerability. | munchbunny wrote: | It looks like Chrome does: https://github.com/chromium/chro | mium/blob/ccd149af47315e4c6f... | | Credit to this person's comment in the Reddit discussion: h | ttps://www.reddit.com/r/netsec/comments/eooyil/cve20200601/ | ... | sroussey wrote: | Curious, why don't we integrate the algorithm and its parameters | into the public key? | tialaramex wrote: | The X.509 structure does put all of this together, it's just | that cryptographers will tend to refer to the actual numbers | which vary from one to another as the "public key" as a | shorthand, they know the rest of the context is important but | it's not what they're talking about right now. | | In RSA for example there's a public exponent, yours is almost | invariably going to be 65537 and most of the time nobody will | even mention this parameter, but the "same" key with exponent 3 | would actually be a different key than yours. | | In code such shorthand becomes a bug. | | If you only allow a handful of named algorithms the bug is | essentially useless to adversaries. Microsoft's non-standard | decision to allow parametrised curves makes it into a huge | attack surface. | sroussey wrote: | Yeah, I get that! There would still be a named curve though, | and things do change over time. | | Sometimes I like to force things in such a way that you can't | avoid dealing with some issues. So, by putting these items in | the public key, you are forced to look at them and deal with | them when you write a library. | | Often, engineers will write code correctly because they know | all the context. But the next engineer will likely have less | and less context as time goes by. | | Thus forcing context acknowledgement, while seemingly | redundant, might be essential to avoiding future bugs. | tptacek wrote: | That's a general description of the problem, but the more | pragmatic question to ask is "why do we support explicit curve | parameters at all?". In practice, nobody uses them; virtually | no organizations are even qualified to use them. Many platforms | don't support them at all; it's not as if there's a serious | compatibility argument for them. | | The right response to this vulnerability is to jettison support | for anything but named curves. | | This is probably an inside-baseball argument for people who | don't pay attention to elliptic curve implementation details. | But it's easy to quickly understand. | | Go to SAFECURVES.CR.YP.TO; you'll see a big long list of | curves, each with their parameters and some implementation | details. In reality, only a subset of these curves are commonly | used (P-224, P-256, Secp256k1, and Curve25519 probably account | for 95% of all curves). | | Further, most specific curves are implemented not as parameters | plugged into a generic elliptic curve scalar multiplication | routine, but rather as curve-specific code (one of the major | reasons we have different curves is to allow specific | implementation optimizations). A browser that supports | Curve25519 certainly uses Curve25519 code, not generic code. | | The "explicit curve" feature that blew up on Microsoft is | designed to allow people to specify their own parameters, not | for well-known curves but for curves they themselves generated. | Nobody does that. There was a time, in the long long ago, when | people thought that might be a good idea; nobody thinks that | anymore; everyone thinks the opposite thing. If anything, we're | trying to _get rid of_ a bunch of curves. Certainly we shouldn | 't be randomly supplying new Weierstrass curves. | | So that's the problem here. A lot of cryptography engineers | were probably surprised this CryptoAPI feature even worked. We | had considered it awhile ago as a cryptopals challenge (and | Sean actually did add it as one in Set 8 a few years ago), but | we never dreamed anyone would be crazy enough to let this bug | happen in the real world. | sroussey wrote: | If it can, it will... :) | archgoon wrote: | So, it sounds like (please correct me if I misunderstood | something) the issue is: # cache signing objects | and get chain cache, chain = | parse_chain_from_cert(full_cert) root = chain[-1] | validate_root_authenticity(root) # go up chain from | leaf to the root for cert in chain[:-1]: parent = | cert.parent() # Wrong Signing object retrieved | here: signing_object = cache[parent.public_key] | signing_object.validate(cert) | | So the leaf signing object is used instead of the roots, as they | share the same public key, but that doesn't contain the | parameters of the curve. | rfoo wrote: | Interested in how exactly it was fucked up I looked at | crypt32.dll. It's more like (heavily-adjusted to demonstrate | the problem without >9k unrelated details): | from the_heavy_lifting_crypto_heavy_module import | verify_signature def is_known_trusted_ca(cert): | # BOOM return cert in root_ca_cache[cert.pubkey] | def verify_cert(cert, issuer): # BOOM if | verified_cache[(cert.pubkey, issuer.pubkey)]: return | True if not verify_signature(cert, issuer): | return False verified_cache[(cert.pubkey, | issuer.pubkey)] = True return True # This | has to be a search instead of simple chain-walking because | servers # do not send a "chain", they only send several | additional certificates and # let the client find a | trusted path out of them, it is also how cross signing # | works. This justifies using a cache above. def | try_to_build_cert_chain(cert, cert_store): if | is_known_trusted_ca(cert): return [cert] for | possible_issuer in | cert_store.find_certs_with_dn(dn=cert.issuer_dn): if | verify_cert(cert, possible_issuer): chain = | try_to_build_cert_chain(possible_issuer, cert_store) | if chain: return [cert] + chain | | Then someone tasked with (why?!) "adding unnamed curve support" | added (correct!) code to | `the_heavy_lifting_crypto_heavy_module.verify_signature` but | didn't know this breaks an assumption made in another module. | | The exact detail does not matter though, you can build up | working exploits even if you don't know the details listed | above. ___________________________________________________________________ (page generated 2020-01-16 23:00 UTC)