Wednesday, August 19, 2015

LRN 2 PGP: Don't make it easier for the malicious...

In case you haven't heard, there have been a bunch of fake Cicada 3301 sites popping up recently. I've followed the Cicada challenges for a long time, so naturally I was hanging out on the #cicadasolvers channel on freenode to check out all the buzz.

Amidst all the nonsense that was being thrown around on Monday though, someone posted an interesting Pastebin link in the chat. They claimed it was new information from Cicada that virtually no one had seen before. The note is a PGP signed message and appears to be from part of the 2013 Cicada challenge. It didn't help with the 2014 challenge (which, for all we know, still hasn't been solved), but it was really cool that there was new information. Someone even verified that the message was legitimate! ... except it wasn't.

Upon closer inspection, it was concluded that this message is in fact a forgery. And here's how this forgery was accomplished. The message isn't actually formatted properly. PGP inline signature format consists of a few lines of boilerplate ("armor"), which wraps the message text. After these boilerplate lines, there is supposed to be a blank line, and then your message. However, you can see that there is no blank line before the message in this case. This causes the perceived message body to be considered part of the "armor", which is not signed.

So if that's the case, then why does the signature still appear valid? Well, this is actually Cicada's fault. A while ago, Cicada must have signed a blank (or whitespace) message. Notice how there are 8 blank lines between the "message" and the signature? This is the actual message space. Although this means that the message needs to make sense in the timeline that the blank message was originally signed, it's still pretty powerful for forging messages. We can verify all of this with GPG. First let's try a vanilla verification:

We can see that there's a small warning about an invalid clearsig header, but the signature is actually declared a good signature from "Cicada 3301". Now let's try with verbosity on to see a more detailed error message:

And there it is... the "message" is actually part of the armor header. Now the only thing left is to demonstrate is that modifying the blank space, or actual message space, will render a bad signature. To accomplish this, all I'm going to do is add an extra blank line to the real message space.

So if you're using PGP for message signing, please pay attention to the armor headers of any messages you may come in contact with. And note, you should never sign a blank message. This is what made it possible for someone to forge Cicada's signature.