As many of you know, GnuPG 1.4.15 was released a few days ago with:
* Fixed possible infinite recursion in the compressed packet
parser. [CVE-2013-4402]
http://lists.gnupg.org/pipermail/gnupg-announce/2013q4/000334.html
There's now a nice writeup by Taylor R. Campbell, who invented the
attack on GnuPG, and it applies to more than just GnuPG:
http://mumble.net/~campbell/blag.txt
I'll quote it below for those reading oss-security archives a while
later, not to rely on it still being near the beginning of blag.txt.
---
2013-10-08 On compression in data formats
If you have a large message which you want to sign and encrypt with
OpenPGP, you might compress it first. Or you might compress it
second. Or, if you're not thinking much about it, you might
`compress' it last, although if that actually reduces the size
there are some cryptographers who would like to have a word with
you.
In any case, the OpenPGP message format lets you do any of these,
because there is a type of OpenPGP packet for compressed data,
whose content is interpreted as another OpenPGP packet. OpenPGP
agents, such as GnuPG, are expected to recursively process packets
they encounter in a message, decrypting ciphertext and verifying
signatures and decompressing compressed data, until they hit a
ground case, usually a literal data packet.
Since messages are built up by starting with a literal data packet
and layering encryption, signature, and compression atop it, this
process should always halt at a ground case, right? Well, no.
Decryption and verification (or, removing a signature) always yield
smaller packets than you began with, so there has to be a ground
case for those, but decompressing usually yields a larger packet
than you began with.
So you might play a cruel trick on your friend by sending a very
small email with a compressed packet that decompresses to a
terabyte of zeros. Or you could send an email with a compressed
packet that decompresses to...itself.
How does that work? The Lempel-Ziv compression language is
powerful enough to write a quine -- that is, a program that prints
its own source code. Rather than repeat the story here, I'll defer
to Russ Cox's article on how to write these:
Russ Cox, `Zip Files All The Way Down', 2010-03-18.
http://research.swtch.com/zip
In the case of OpenPGP, it was particularly easy because OpenPGP
supports a number of compression algorithms including an option
without any CRC, so one can write a program that just spits out an
OpenPGP compression quine without iterating over CRCs or solving a
horrible system of equations.
The result is CVE-2013-4402, and the lesson is that systematic
recursive compression is no good -- not only that it's not useful,
but it is actively harmful. It's especially harmful for programs
that process input sent unsolicited from anywhere on the internet,
namely mail readers.
And OpenPGP isn't the only data format that supports recursive
compression. PGP/MIME, which recursively interleaves MIME entities
and OpenPGP packets, can probably exhibit the same issue, and the
small bound on recursion that GnuPG now imposes while processing
packets will be thwarted by the interleaving. S/MIME 3.1 supports
a compressed data message type, although nobody seems to have
implemented it. I'm sure there are formats outside mail that can
also involve recursive compression. Which ones can you find?
---
Alexander