pgp-com

by lord- and mandlebro

Points: Dynamic (451)

Solves: 24

Description:

You know how PGP works, right? pgp-com.tar.gz

Given:

A pgp-com.tar.gz containing a private key, a public key and 3 PGP messages.

Solution

TLDR

  • Get the public and private keys from the given file;
  • Get the 3 PGP messages from the given file;
  • Realise that our private key is able to decrypt 2 out of the 3 messages;
  • Realise that they are generating vulnerable session keys;
  • Guess the session key and hack pgppy to use custom session keys;
  • Get the flag!

Detailed solution

First we looked at the keys and messages we were given to try and find some information about them.

The public key:

$ cat public.key | gpg --with-colons --import-options import-show --dry-run --import
pub:-:4096:1:1437E68F5024FDC0:1554216164:::-:::escaESCA::::::23::0:
fpr:::::::::3E5FC53F2B3D0B92057DE7701437E68F5024FDC0:
uid:-::::1554216164::F36F5AB39B717D0386FB4A4F78F5203336B2E68A::Midnight Sun CTF Admin <admin@midnightsunctf.se>::::::::::0:
pub:-:4096:1:EBA63E4B442DB992:1554216169:::-:::escaESCA::::::23::0:
fpr:::::::::6AEEDDD07760D2B83482553BEBA63E4B442DB992:
uid:-::::1554216169::AED77950FA6E5FEC02C2B59E18EBB4551FA07A51::Midnight Sun CTF Participating teams <teams@midnightsunctf.se>::::::::::0:
pub:-:4096:1:BB0EAF2215849295:1554216170:::-:::escaESCA::::::23::0:
fpr:::::::::6CF8DEB045D8200275DE16A3BB0EAF2215849295:
uid:-::::1554216170::2AB8FF2FA90090BAD168AC3F3D1184E71B3F87C4::Midnight Sun CTF Devteam maillist <devs@midnightsunctf.se>::::::::::0:
gpg: Total number processed: 3

The private key:

cat private.key | gpg --with-colons --import-options import-show --dry-run --import
sec:-:4096:1:EBA63E4B442DB992:1554216169:::-:::escaESCA:::#:::23::0:
fpr:::::::::6AEEDDD07760D2B83482553BEBA63E4B442DB992:
grp:::::::::241145EC87E90FAAE45D49AF6E8FE3EED2CDD552:
uid:-::::1554216169::AED77950FA6E5FEC02C2B59E18EBB4551FA07A51::Midnight Sun CTF Participating teams <teams@midnightsunctf.se>::::::::::0:
gpg: Total number processed: 1
gpg:       secret keys read: 1

Checking the uids for each key, we can see that we have a private key for ourselves as a Midnight Sun CTF Participating team and a public key for the teams as well as the CTF Admin and Devteam maillist.

Now lets try to get some information on the messages we have, maybe we can decipher them with our keys?

The messages:

$ gpg message1.pgp
gpg: encrypted with RSA key, ID EBA63E4B442DB992
gpg: encrypted with RSA key, ID BB0EAF2215849295
gpg: encrypted with RSA key, ID 1437E68F5024FDC0
(...)

gpg message2.pgp
gpg: encrypted with RSA key, ID BB0EAF2215849295
gpg: encrypted with RSA key, ID 1437E68F5024FDC0
gpg: decryption failed: No secret key
(...)

$ gpg message3.pgp
gpg: encrypted with RSA key, ID EBA63E4B442DB992
gpg: encrypted with RSA key, ID BB0EAF2215849295
gpg: encrypted with RSA key, ID 1437E68F5024FDC0
(...)

We can see that the first and third messages are encrypted with the same RSA keys, which are actually the keys we have in the public key file above, and we also have the corresponding private key for one of them, so we should be able to decrypt these messages!

We gave it a try using pgppy, and it worked! The first message was as follows:

From: Midnight Sun CTF Admin <admin@midnightsunctf.se>
To: Midnight Sun CTF Participating teams <teams@midnightsunctf.se>, Midnight Sun CTF Devteam maillist <devs@midnightsunctf.se>
Subject: Welcome!
Date: 2019-04-02 17:26:42

Hi,

This is a message just to say hello and welcome you all to the competition.

We are now introducing our own implementation of the super secure PGP messaging format.

We will use it for all important communication during the CTF.

Best regards,
CTF Admin

We can already get some hints at what is vulnerable, given that the admins used their own implementation of PGP. Lets check the other message we have access to (the 3rd one):

From: Midnight Sun CTF Admin <admin@midnightsunctf.se>
To: Midnight Sun CTF Participating teams <teams@midnightsunctf.se>, Midnight Sun CTF Devteam maillist <devs@midnightsunctf.se>
Subject: Implementation problems
Date: 2019-04-02 17:29:22

Hi,

We have received some indications that our PGP implementation has problems with randomness.
The dev team is currently working on fixing the issue.

We will not use this system for further messages until it has been fixed.

Your key pairs were not generatad by this system, and they should be safe even for future use.

Best regards,
CTF Admin

Indeed there was a problem with their implementation! They say that they have a problem with randomness, but they also say that our key pairs were not generated by their system, which we can confirm by dumping the RSA keys and looking at their data, they do seem to be OK.

However, there is one other place we can look for to try and find a vulnerable RNG: the session keys used in the PGP messages. Once again we used pgppy to dump the session keys used in the messages we could decrypt, and they are the following:

./dump_session_key.py message1.pgp
alg=SymmetricKeyAlgorithm.AES256
key=bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x136')

./dump_session_key.py message3.pgp
alg=SymmetricKeyAlgorithm.AES256
key=bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x138')

They seem to be awfully vulnerable, as they are filled with zeroes and have sequential numbers in the end, remember that there is a message that was in-between these messages that we did not have the private key for!

To decrypt the second message, we changed pgppy’s code to use custom session keys to decrypt messages and simply used the key of the first message incremented by one, so that would be \x00\x00...\x13\x37, which promptly yielded the final message:

From: Midnight Sun CTF Admin <admin@midnightsunctf.se>
To: Midnight Sun CTF Devteam maillist <devs@midnightsunctf.se>
Subject:
Date: 2019-04-02 17:27:07

Hi,

How could you implement a system with such bad session key generation!?

Please remeber that midnight{sequential_session_is_bad_session} in the future...

Best regards,
CTF Admin

Everyone should know that a midnight{sequential_session_is_bad_session} :-)