Goatse Security

Gaping Holes Exposed

Clench, our way of saying “screw you” to SSL PKI forever

11 Comments »

Nate Lawson has an excellent post on his blog rightly identifying SRP as a superior solution to the Clench implementation. However, upon examination it appears that SRP is encumbered by a questionable patent situation. I would hope that Stanford would be able to release a BSD-licensed version of their SRP distribution sometime soon to enable its adoption everywhere.

Application layer authentication-inherent validation of public key integrity without the use of a trusted third party
Andrew Auernhemer and Jordan Borges.

This is the initial unveiling of the pre-alpha version of Clench, Goatse Security’s new simple password-based authentication mechanism that rids most organizations of a need to rely upon an untrustable third party to ensure against man-in-the-middle attacks.

un-tl;dr abstract: SSL is broken. Certificate authorities only exist to let the US, Chinese, Turkish, Brazilian etc etc government or Russian mob spy on you (whichever is interested first). Well, I guess they also exist to line the pockets of assholes who want $10-50 for pushing a button. Luckily, we’ve remedied this! We’ve established a way that a client, using only standard password authentication, can validate a server’s public key and ensure that no third party is listening (without the use of a trusted third party such as a certificate authority or manual fingerprint verification). Read on for a wonderfully simple hack and proof of concept code!

Biggest problem we solve: “Trusted” third parties can’t be trusted and criminals or hostile governments are free to launch man in the middle attacks. Extensive research in this area has been done by by  Marlinspike, Dan Kaminsky and Mike Zusman which you really should read.

  • Exploiting web application and business logic vulnerabilities of certificate authorities allow the generation of valid certificates for arbitrary domains you do not own.
  • The number of entities allowed to issue certificates is now massive and not being effectively tracked– criminal organizations outright buy certificate authorities and print certificates for arbitrary domains they do not own.
  • Do you trust the Chinese government not to snoop on your traffic? What about the United States government? Your browser trusts both– either of them can snoop on your “secure” HTTPS sessions.
  • EV SSL is a joke.
  • Who watches the watchers?

The whole SSL architecture is broken and cannot be safely relied upon. Any system of authentication which relies on a “trusted” third party that you have no dominion over is flawed. DNSSEC is only an incremental improvement with the same underlying flaw– I may trust the ICANN, ISC, NIST, NTIA, the Department of Homeland Security, or VeriSign more than the combined ineptitude and maliciousness of every current SSL CA, but I still don’t trust them. The whole idea of a trust anchor is fallacious.

We set out to solve this problem in a way that can reconcile three realities of security:

  • Users cannot effectively comprehend anything but password authentication. They don’t understand key management, and the task of getting hundreds of thousands or millions of users to install a client certificate or generate a keypair (and not accidentally reveal the private key) is a Herculean task that few IT departments want to try.
  • Users cannot be trusted to manually verify fingerprints. Seriously, they just won’t. Even the ones that perceive themselves as sophisticated and security-conscious.
  • The network is now many times more hostile and open to attack than the server.

So we had to create an authentication mechanism in which a user inputs only a username and password, but ends up with a session immune from man-in-the-middle attacks without the use of a trusted third party.

We looked at various authentication schemes. Of note was Livejournal’s. Being the most popular blogging site in Russia, they got user auth details jacked so many times by shady spammers jacking routes with “legitimate” certs that they stopped transmitting the hash plaintext over the wire. They give a nonce to the client and the client hashes locally and then sends the hash to the server. The other source of inspiration was the Socialist Millionaire protocol, which Off-the-Record Messaging utilizes with a shared secret to verify cryptographic fingerprints.

In almost every scenario where security is mission critical, you already have a shared secret from the outset. When an enterprise user is given their new account, or when someone sets up online banking at their bank branch they are given a temporary password. A temporary password is a shared secret, and shared secrets may be leveraged to verify fingerprint information.

Here’s how Clench works:

  1. Client connects to server and sends hello.
  2. Server sends hello back, along with its cert.
  3. Standard Diffie-Helman key exchange happens in SSL/TLS/SSH fashion. Initial handshake is finished, cypher spec is changed, now here comes the magic:
  4. Server sends client the nonce value [ Ticks since unix epoch + 16 bytes of random data ]
  5. Client sends userid/username to server.
  6. Client types in password, but password is not sent to server. Both sides generate a hash.
    Client generates y, a hash of  [ client password + server's public key, as client sees it + nonce from step 4 ]
    Server generates x, a hash of [ client password + server's own public key + nonce from step 4 ]
  7. Client and server use a symmetric and fair zero-knowledge proof to verify that we both have the same hash without revealing the value of the hash to one another. Imagine a two pan scale, and a secret of a given weight of marbles in a bag. If we both place our bag of marbles on the pans at the same time, if they come to an equilibrium we will have verified our shared secret without revealing it to one another.
    • Server picks random exponents a2 and a3,sends client g2a = g1a2 and g3a = g1a3
    • Client picks random exponents b2 and b3,computes g2b = g1b2, g3b = g1b3, g2 = g2ab2 and g3 = g3ab3, picks random exponent r, computes Pb3r and Qb = g1r g2y, sends server g2b, g3b, Pb and Qb
    • Server computes g2 = g2ba2 and g3 = g3ba3, picks random exponent s, computes Pa = g3s and Qa = g1s g2x and Ra = (Qa / Qb)a3, sends client Pa, Qa and Ra
    • Client computes Rb = (Qa / Qb)b3 and Rab = Rab3, checks whether Rab equals (Pa / Pb), sends server Rb
    • Server computes Rab = Rba3 and checks whether Rab equals (Pa / Pb)

    For more information on this step please see the excellent paper “A Fair and Efficient Solution to the Socialist Millionaires’ Problem“.

  8. Upon successful completion of the proof, the server allows the session to proceed.

This method of authentication avoids nearly all of the current pitfalls for current authentication schemes.  Things that cannot be done against our authentication mechanism:

  • Cracking a hash from the wire: No hash is revealed!
  • Man in the middle attacks. Impossible– compared shared secret is incorporating the server’s public key. If there’s an attacker in the middle, client’s hash value y will be built with the wrong public key and thus will fail zero-knowledge proof comparison.
  • Replay attacks. Underlying hash for proof is not revealed, and nonced anyways.
  • Brute force of Socialist Millionaire protocol with a preloaded Rainbow Table: This is doubly impossible.
    1. Even if (x – y) could be extrapolated, the nonce is built with 16 bytes of random data. At least 2-3 bytes of the ticks value are hard to predict, ending up with (18 + password length) bytes of random data results in rainbow table size that is unfeasible to build.
    2. (x – y) cannot be extrapolated by brute force, as a new nonce is built for every authentication attempt, and  potentially meaningful data from (x – y) cannot be generated without multiple attempts on the same shared secret value.

This can be accomplished in either the session layer or the application layer– the latter allowing easy implementation atop current infrastructure with trivial changes to clients.

The roadmap from here.

There’s some barriers to implementation on this for HTTPS. Firstly, there needs to be a javascript function that returns the current public key (or at least the fingerprint) of the https server called to load the page in the current DOM. There also needs to be some mechanism in the GUI of the browser that can’t be mimicked by an attacker to inform the client that the current login form implements a Clench-like authentication mechanism. Because obviously an attacker can just rewrite the form if they’re MitMing and trick the user into sending plaintext.

SSH can be implemented much faster, it’d just need a PAM module.

Hey, wait a second, doesn’t the passphrase have to be stored in plaintext or as an unsalted hash on the server?

Well, possibly yes. The perception of this as being an insurmountable flaw is largely the result of fallacious decisions in SysV in 1988. They were good decisions at the time due to the fact that it was ludicrously easy to break the security of a server then. However, the network has become far more hostile than the server. There are two major ways of ensuring  the safety of a plaintext password or unsalted hash data store:

  • The authenticating server needn’t actually have the password in plaintext, it merely needs access to a more device that has it. A secure hashing device can be implemented on a PIC/Atmel/Xilinx– it’s job is to generate the nonce, give it to the server with a cookie, then when the server responds back with a userid and the cookie it hashes together the nonce, the client’s password (which only the secure device has access to) and the server’s known public key, taken from a whitelist. It then passes the hash to the server. It is trivially easy to build a device in hardware which can only provide nonces, cookies and hashes and write new passwords without ever giving stored passwords up in plaintext, and disallows reprogramming to do anything otherwise. Or if not a hardware device, perhaps a grsec-hardened machine running managed code with no network stack exposed, doing a similar transaction raw over serial port or Infiniband. If my sole goal of a machine is to hash things and keep a file secure, I can confidently make it bulletproof without risk of compromise.
    The potential implementations highlighted above are in development, and will be aired at the first opportunity (provided I evade unjust imprisonment, lol).
  • Make your users make two passphrases– the first of which will be stored in plaintext, to assure no MitM, the second of which will be stored shadowed as normal in case of server’s compromise. Telling grandma she needs two different passwords to use her bank account is a lot easier than teaching her to install a client certificate.

Hey, there’s no way to tell the difference between an attempt at man-in-the-middle and a mistyped password!

With a user-specified password, no. If your initial shared secret has a checksum or LUN check in it, however, the client can notify the user of a potentially mistyped password.

Okay, I’m tired of reading your shit. Where’s the codes?

Here. Enjoy, and know that a meatier paper is on its way (provided I evade unjust imprisonment long enough to do the peer review process for a journal or conference) if you want to read this in academic tripe format.

Switch to our mobile site