/ misc

EkopartyCTF - The Fake Satochi (misc300)

Énoncé :

Hello Mr. Giarc, upload again your false PGP key to pgp.mit.edu and send us any file you want with its signature to prove you are the fake Satoshi!

The key on the server should look like the following line (case sensitive):

Type bits/keyID     Date       User ID
pub  1024R/5EB7CB21 2008-10-30 Fake Satoshi EKOPARTY12 (P_TE) <satoshin@gmx.com>

http://a493e192124c317fc34511a73d63d1ae7334e132.ctf.site:40000/

On nous donne une clé PGP. Nous utiliserons GPG, qui est une implémentation libre de PGP. Cette clé est composée de plusieurs éléments :

  • pub 1024R : C'est une clé publique, de type (R)SA 1024 bits.
  • keyID 0x5EB7CB21 : L'identifiant court de la clé PGP.
  • Date 2008-10-30 : La date de création de la clé.
  • User ID : Identifiant avec le nom et l'email de l'utilisateur.

En allant sur le site Web en lien, nous avons une application Web qui nous fourni le flag une fois validé les élements suivants :

  • Que la clé téléchargée sur le serveur de clé pgp.mit.edu corresponde à celle de l'énoncé
  • Que la signature uploadée avec le fichier correspondant soit bien valide avec la clé précédemment téléchargée

Avec tous ces éléments, nous devons donc à priori ici forger une clé PGP avec les bonnes caractéristiques, l'envoyer sur le serveur de clé, signer un fichier et ensuite envoyer le fichier et sa signature à l'application qui validera la bonne signature.

L'utilisation des short IDs de clé PGP est dangereuse, et la présentation à la DefCON du projet evil32 permet de s'en convaincre. Ce projet fourni néanmoins un outil extrêment intéressant qui est Scallion.

Scallion est un projet qui nous permet de forger des clés RSA (notamment pour avoir un joli nom de domaine en .onion qui vous correspond) mais aussi de forger des clés PGP. Parfait !

Scallion utilise les bibliothèques OpenCL pour faire ses calculs sur un GPU. Pour ce challenge, une carte nVidia a donc été utilisée. Après avoir téléchargé les binaires Windows, on lance donc le programme pour générer notre clé PGP. Mais sans oublier de modifier la date de son système. En effet, la clé doit avoir été créée le 30 octobre 2008 !

$ ./scallion.exe --gpg 5EB7CB21$ -k 1024
Cooking up some delicions scallions...
Using kernel optimized from file kernel.cl (Optimized4)
Using work group size 32
Compiling kernel... done.
Testing SHA1 hash...
CPU SHA-1: d3486ae9136e7856bc42212385ea797094475802
GPU SHA-1: d3486ae9136e7856bc42212385ea797094475802
...
init: 129ms / 1 (129ms, 7,75/s)
generate key: 938ms / 10 (93,8ms, 10,66/s)
cpu precompute: 8ms / 10 (0,8ms, 1250/s)
total without init: 9248ms / 1 (9248ms, 0,11/s)
set buffers: 2ms / 292 (0,01ms, 146000/s)
write buffers: 12ms / 292 (0,04ms, 24333,33/s)
read results: 8875ms / 292 (30,39ms, 32,9/s)
check results: 168ms / 292 (0,58ms, 1738,1/s)

529,73 million hashes per second

On remarquera aussi dans l'ouput donné ci-dessus la ligne qui nous indique que notre date de création est bien la bonne :

<GeneratedDate>2008-10-30T01:01:28.3388079Z</GeneratedDate>

En environ 3 secondes, Scallion nous a calculé la clé privée correspondante à la clé publique !

-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: Scallion

lQHZBEkJB1wBBADXofFwUufxjUt1EGOyloKApkf8Kv4KeorvHat7fq57Ld/R1QbD/Cwd5BD+c3Eqvb
oPGcjh03Q/fKnRwq8am9xVVxkEvUOJrrz+0YJIVHnhT82q8r1E1ut94ArMv23j3UZMDG7icdEJEVzM
oQe7bns+OvV8fIzsyHgvfUhy+xm9oQAg68TMvwAD/RpUo1WbYu+Gm1DNHtntWGQN4/a8eAoNeNEXrl
Gy7SpmwT0m04sUq1iMLsJUidlZcVSBlqjfPvCBsMBJD6BXVFG+ZwPsgz+zH0YyInI4RvLo7MWM5zzD
17VukZ5PsqXV+DeKpAH9G2g5DdkRbA3LEaI7t0RQuQP9jmq/aEGa6vQFAgDx4TyGGNkBu3HnBaW3C7
lxNZCheUtcLbsGBld1njpOTeShhy5WxgyRGmN0mO2Qfq0pfpVndwSKpIq9y/h6KEavAgDkOHSzfoFv
X14MSbCJfJvYvP70UO1Ukj5n1+zms2qjvFp1mvLRlND1xXrAlDfsbtPNAZIUxxGwCJJ736B7oFSvAg
CCe6Lw5YHAj+CrkCKwarixEYnSBmj2jjoe8SYxywphPCbNmhANr75xCjFsk4jB6UM+rxWBIG338C8N
1W2qpVNCojC0GVNjYWxsaW9uIFVJRCAocmVwbGFjZSBtZSk======
-----END PGP PRIVATE KEY BLOCK-----

Bingo ! On l'enregistre dans un fichier. Maintenant, il faut importer cette clé dans notre trousseau de clé privé GPG.

Pour importer la clé privée fraîchement calculée :

$ gpg --allow-non-selfsigned-uid --import private.key
gpg: clef 2A0728DF5EB7CB21 : identité « Scallion UID (replace me) » non autosignée acceptée
gpg: clef 2A0728DF5EB7CB21 : « Scallion UID (replace me) » n'est pas modifiée
gpg: clef 2A0728DF5EB7CB21 : clef secrète importée
gpg:       Quantité totale traitée : 1
gpg:                 non modifiées : 1
gpg:           clefs secrètes lues : 1
gpg:  clefs secrètes non modifiées : 1

On peut maintenant modifier la clé pour remplacer l'UID avec la commande :

$ gpg --edit-key 5EB7CB21

Notre clé devrait être bonne pour l'envoi au serveur de clé !

$ gpg --send-keys 5EB7CB21 --keyserver pgp.mit.edu

On peut d'ailleurs la retrouver ici : https://pgp.mit.edu/pks/lookup?op=vindex&search=0x2F06AA3C5EB7CB21

Dernières étapes, il nous reste maintenant à créer un fichier et le signer avec notre clé :

$ echo "P_TE" > msg
$ gpg -u 0x5EB7CB21 --output msg.sig --sign msg

En envoyant ensuite à l'application Web notre fichier msg et sa signature msg.sig :

$ gpg --recv-keys 5EB7CB21 >/dev/null
$ gpg --verify tmp/71ad11db1a56a9d9c98c65c0a0308b69aa5bb36d.txt.asc
gpg: Signature made Fri Oct 28 00:13:46 2016 UTC using RSA key ID 5EB7CB21
gpg: Good signature from "Fake Satoshi EKOPARTY12 (P_TE) <satoshin@gmx.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 4F07 A485 7D3F D74F FDEF 200A 2A07 28DF 5EB7 CB21
gpg: WARNING: not a detached signature; file 'tmp/71ad11db1a56a9d9c98c65c0a0308b69aa5bb36d.txt' was NOT verified!
$ gpg --with-colons --list-keys 4F07A4857D3FD74FFDEF200A2A0728DF5EB7CB21
tru::1:1472699948:0:3:1:5
pub:-:1024:1:2A0728DF5EB7CB21:2008-10-30:::-:Fake Satoshi EKOPARTY12 (P_TE) <satoshin@gmx.com>::escaESCA:
$ echo Welcome master, grab your key
Welcome master, grab your key
$ echo EKO{the_dynamic_flag_didnt_work_mr_fakeoshi}
EKO{the_dynamic_flag_didnt_work_mr_fakeoshi}

Signature validée ! Comme dit plus haut, ceci n'est possible que parce que l'application ne vérifie la clé qu'avec le short ID, ici 0x5EB7CB21. Il est donc possible, sans connaître le fingerprint complet, de se faire passer pour le faux Satochi, ou même Linus Torvalds...

Flag : EKO{the_dynamic_flag_didnt_work_mr_fakeoshi}