Exploitable heap overflow in libgcrypt 1.9.0 (┛ಠ_ಠ)┛彡┻━┻

It's the crypto library that gpg uses. Homebrew has 1.9.0 right now. 🚨

dev.gnupg.org/T5259
It's in cipher/hash-common.c (!) and looks like it's hit when extra data is hashes after finalizing the hash.

Doing that is a partial mitigation for timing side channels on the length of a hashed message. Very partial.

dev.gnupg.org/rC512c0c752769…
Reported-by: Tavis Ormandy <taviso@gmail.com>

👋 @taviso
Right, so there are function pointers and stuff, but this is in sha256_final.

If there's no space in the block for the length suffix, it uses space from the 128 byte buf to fit another one.

Then it leaves count, the buffered data length, at 120.

No idea why it sets count.
But then! md_write might still be called in a very mild attempt at mitigating timing side channels.

blocksize is 64, (blocksize - hd->count) underflows, the if doesn't hit, so buf_cpy copies the whole input to buf.

If it's more than 8 bytes, heap overflow.
What went wrong? Of course, in primis, it's C and memory unsafety.

Arithmetic errors happen. In C they instantly become exploitable vulnerabilities. In a hash function!!

There's also a lot of reliance on distant state invariants, which is unsafe even by C standards.
A defensive strategy here would be to use a copy function that is aware of the constant size of buf.

Instead the patch just adjusts the invariance ad-hoc in md_final.

I still don't understand why md_write sets count to 120. It wrote two blocks, reasonable values are 0 and 128.
Another fun angle is that this vulnerability is introduced by timing side channel mitigations.

Previously: blog.cloudflare.com/yet-another-pa…

Not good ones, though. The suffix is always written at the beginning of a block, and md_final is not constant time.
I applied the same mitigation to crypto/tls in 2016. (It was my first contribution to the Go crypto libraries! 🤩)

Notice how the md_final equivalent is constant time, and leaves state unmodified. Not perfect, but the number of compressions is constant.

golang.org/cl/18130
I am physically uncomfortable with how state is handled in there.

There is clearly an implicit assumption that (hd->count <= blocksize), but md_write can still leave count at 120, after flushing the buffer.

Why not set it to zero then! Why do it in md_final! 😱
Now the question is what code uses md_write after md_final.

Does gpg??

Taking a break to PR libgcrypt 1.9.1 into Homebrew because no one did that yet. Back soon.

Maybe this should have been a filippo.io/newsletter issue. Maybe it should still be.
github.com/Homebrew/homeb…

Now, breakfast. Then we look at GnuPG code.

It's a fun friday...
"Just decrypting some data can overflow a heap buffer with attacker controlled data, no verification or signature is validated before the vulnerability occurs." — @taviso

lists.gnupg.org/pipermail/gnup…
Oh you've got to be kidding me. The fixed version, libgcrypt 1.9.1, breaks the build on Intel CPUs because of unrelated changes.

This is why Go security releases branch and ship ONLY security fixes.

github.com/Homebrew/homeb…
--disable-asm builds of the fixed version are just broken on x86_64.

The breakage was introduced by a refactor that made regular code depend on a #define only set when asm is enabled.

The commit includes some RDRAND changes, 'cause why not.

dev.gnupg.org/rC8d404a629167…
Alright, I dropped a patch for --disable-asm builds of libgcrypt 1.9.1 in the Homebrew PR. It's trivial enough.

You might also consider reverting to 1.8.7.

github.com/Homebrew/homeb…
Jesus Christ. /cc @hanno
It goes on. @hanno points out that libgcrypt and GnuPG don't seem to have CI, suggests running tests with ASAN. This is the reply.

(Indeed, libgcrypt 1.9.0 had to be patched in Homebrew because its tests weren't passing. libgcrypt 1.9.1 doesn't build.)
This... might be such an incredibly perfect heap overflow bug that it's possible even I could exploit it on a modern system.

The last time I wrote an exploit was when microcorruption.com came out.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Filippo Valsorda 💚🤍❤️ ✊

Filippo Valsorda 💚🤍❤️ ✊ Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @FiloSottile

27 Jan
This is neat, the new SoloKey sports an updateable Rust firmware.

Now, hear me out @nickraystalder @0x0ece: you already have 25519 code, give us a scalarmult op and we can make an age plugin that works with native recipients!

kickstarter.com/projects/conor…
The Solo V2 supports PIV like the high-end YubiKeys, so it already works out of the box with yubikey-agent for SSH, nice.

I'm guessing it also supports Ed25519, so I should get around to landing github.com/FiloSottile/yu…. Image
Hey, a Wireguard plugin is basically an age plugin! Image
Read 4 tweets
16 Jan
Alright folks, do you want to see this happen? Me and @tqbf discussing "don't roll your own crypto" on Twitch?

How about a fundraising drive for Partners In Health? At $1000 we drop a recording, at $2000 we livestream. Send receipts!

pih.org/?form=donate
@tqbf We've crossed $1500, so hell yeah this is happening! Now, is it happening live?!

Read 6 tweets
18 Nov 20
Here we go, let's see how the new M1 chips do on Go benchmarks!

(Might be a good time to mute #M1, I have a new toy and I took time off work until the end of the month.)

First step is

$ GOOS=darwin GOARCH=arm64 ./bootstrap.sh

on my corp MacBook.
Well, it couldn't be too easy I suppose.

Ran bootstrap[.]sh (which is just a convenience wrapper for make + mv bin/darwin_arm64/go bin/go + tar), sent it over with webwormhole.io, cleared the quarantine xattr, and...

zsh: killed ./go-darwin-arm64-bootstrap/bin/go

#M1
Frank has it right, after codesigning bin/* and pkg/tool/darwin_arm64/* I got the compiler running.

Still, this needs fixing, it stops "go run" and "go test" from working. I wonder if the dev kits had it disabled.

Read 13 tweets
10 Aug 20
YIKES.

It's important to destigmatize therapy, but giving permanent therapy transcripts to a VC-backed engagement-optimized tech startup is TERRIFYING.

Teletherapy should be ephemeral by law, and it should not be allowed to optimize for more therapy.

YIKES. YIKES. YIKES. ImageImageImage
CLIENT RETENTION BONUSES. For therapists!

What the actual fuck. This can't be ethical.
Ephemerality is fundamental to therapy. The patient decides whether they trust the therapist to uphold confidentiality today.

What if in ten years some law is passed weakening client confidentiality, and Talkspace is subpoena'd? People can't model that!
Read 6 tweets
31 May 20
The police is arresting, shooting, and macing journalists.
They are driving tanks into cities and escalating.
They're getting recorded and they don't care.

Defund the police. Disarm them. Drop qualified immunity.
A black CNN reporter was arrested after identifying himself while filming on a highway that was blocked by police and protesters.

An MSNBC live crew is shot at and cornered by police as they yell "press press press press" and "don't shoot".

Read 14 tweets
27 Dec 19
🚨 The age-encryption.org reference implementation reached beta! 🥳

age(1) — a simple, modern, secure file encryption tool.
Easy UNIX piping! No config options! Modern crypto! No keyrings! Public keys that fit in a tweet! No more looking up how to encrypt a file on StackOverflow. 💥

age1t7r9prsqc3w3x4auqq7y8zplrfsddmf8z97hct68gmhea2l34f9q63h2kp

Try it out and send feedback 👉 age-encryption.org Image
I'm particularly happy that thanks to @str4d we have two interoperable implementations of age-encryption.org from the get-go.

Both in memory safe languages, they provide maturity and future proofing for the format, spec and ecosystem.

github.com/str4d/rage Image
Read 10 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!