Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

GnuPG Fail - 12 Vulns- 1872

gnu.failPosted 1 Month Ago
  • The research focuses on Pretty Good Privacy (PGP) implementation from GNU. It's used for many things, like verifying downloads. This started with reviewing the code for fun but turned into a lot of vulnerabilities.
  • The first bug was in the injection of plaintext. The implementation didn't sign headers but claimed to only allow for the SHA256 header. In reality, there was another header that could effectively contain arbitrary data. Since this value is a C string, if you add a nullbyte, vertical tabs and carriage returns, the data is effectively skipped on signing but looks legitimate! With a MitM, an attacker could add arbitrary text into the message being signed.
  • Within another tool called minisign, they found a similar issue with comments as well. If you try to add a newline or carriage return to the comment, it will replace it with a nullbyte and check the signature of that. When the actual string is displayed, it uses the full line though. So, signed\ninjected will become injected when signed but display all of the content. The tldr; is that C strings are hard!
  • In GnuPG and Sequioa, they found an issue with signature wrapping. Given any signed message from a user, you can add data to the top of the file that will be shown but the original data will be verified instead. This was because of slight differences in how the user saw the messages and how they were verified. Notably, if a header didn't have the correct name, it would be effectively ignored, even though the user would still see it.
  • There are full signatures, where the sig is included with the data, and detached signatures, where the sig is included in a separate file. When iterating over each packet (group of bytes), there's a bad state machine that resets a byte to zero with an invalid type. By doing this, verification is effectively skipped. This allows marking unsigned contents as verified. Neat!
  • ANSI allows for arbitrary styling in the terminal. Many things, such as gzip, will specifically not output untrusted binary to the terminal. It's possible to ask to write data to any file, but show different things. This turns into clickjacking effectively in the terminal.
  • Age, an alternative to PGP, supports plugins. When loading these plugins, it's based on some content of the recipient's name. Using a path traversal, it was possible to execute an arbitrary binary. Since this was an issue with the specification, it led to A) a change in the spec and B) 5 implementations being vulnerable.
  • From this, they started looking at some memory corruption issues in the C libraries. They found a for loop that was double incrementing an index that led to an OOB operation. To trigger it, required exploiting an integer overflow in the return value of the same function through multiple calls to it. An additional memory corruption issue was found for an uninitialized variable that led to a downgrade to SHA1 signature in some cases.
  • They found some bad caching logic that allowed them to have an unverified key get linked to an account if loaded from the DB. This enabled the simple verification of a key to have it linked, without succeeding in the verification. In practice, this key linking would allow for a wide-range of bypasses in verification.
  • So much impact with zero exploits in the actual cryptography. Most of the bugs were just in the parsing of signatures and in abusing format quirks. I really cool talk on PGP from non-crypto people!