====== RSA ======
===== Principe du chall =====
While sniffing HZV network, you just caught an encrypted message for John. Might contain interesting stuff.
Après détarrage du .tar, on se retrouve avec 4 fichiers et un dossier :
% tar xvf rsa.tar
librsa/
librsa/__init__.pyc
librsa/__init__.py
decrypt.py
flag.asc
john.pub
README
% cat flag.asc
----- BEGIN MESSAGE -----
eJw1krt1HUEMQ3NVosiHIMFfD68J5wrcf2TM7Crce0gQwOz3zz98fRCgkT5DEjWfr7+fjU6rxWA2
3A+CO6NsTN9cuygYHWRsrTHzMG/mTld1Gwd3DB5M93SaC98DgslEc3zuIrgENlZkgwd12HDHNPkr
JaMdbr0zI3xYdSZg1dDdfkzMSjyHxZ6IZ1POfGxNGQIP89J1erlVbV+2x49ceBjsHcPRC3SHwj3W
FN3G4TgpM2+myqytE7QLbyhjWA3YYDheVqMOvWRNk/U4Wa5i9God9cx5+8LpUtUTzVNSri6G9xr6
dac4Mh8qWW9xV1Mtekjw+O23uUrEdkVQD33Vasow0yrEG++BU5oKVgIp4j2qh1HfEaN/oMX+/AcX
TXp2
----- END MESSAGE -----
% cat john.pub
----- BEGIN PUBLIC KEY -----
KG4gPSAxNTQ5Mzg4MzAyOTk5NTE5LCBlID0gMTAxKQ==
----- END PUBLIC KEY -----
% echo "KG4gPSAxNTQ5Mzg4MzAyOTk5NTE5LCBlID0gMTAxKQ==" | base64 -d
(n = 1549388302999519, e = 101)
Comme le nom du chall l'indique, nous avons donc affaire à du RSA.
''decrypt.py'' sert à déchiffrer le flag en fonction de la clé privée que l'on doit trouver.
Pour plus d'informations sur le système RSA, voir wikipedia : https://fr.wikipedia.org/wiki/Rivest_Shamir_Adleman
===== Détermination de la clé privée =====
La clé publique étant donnée (''john.pub''), et ayant donc **n** et **e**, il nous faut, tout d'abord, déterminer les deux facteurs premiers de **n** : **p** et **q**. Ici, **n** étant petit ( **n** < 2⁵¹) il est possible de déterminer **p** et **q** par un simple bruteforce.
Le programme suivant effectue un simple test de division de **n** par un nombre premier **p** et test si le résultat de cette division est un autre nombre premier **q** :
% ./refactor
Found ! p = 31834349 ; q = 48670331
PubKey : 1549388302999519:101
PrivKey : 1549388302999519:d
Phi(1549388302999519) : 1549388222494840
On trouve donc **p** = 31834349 et **q** = 48670331.
Connaissant **p**, **q**, **n** et **e**, nous pouvons alors déterminer **d** via l'inverse modulaire de e mod φ(n). Pour garder un peu de lisibilité dans ce write up, nous utiliserons ici un module perl pré-existant pour déterminer **d** :
#!/usr/bin/perl
use strict;
use warnings;
use Crypt::OpenSSL::RSA;
use Crypt::OpenSSL::Bignum;
use Crypt::OpenSSL::Bignum::CTX;
my $n = Crypt::OpenSSL::Bignum->new_from_decimal("1549388302999519");
my $e = Crypt::OpenSSL::Bignum->new_from_decimal("101");
my $p = Crypt::OpenSSL::Bignum->new_from_decimal("31834349");
my $q = Crypt::OpenSSL::Bignum->new_from_decimal("48670331");
my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
my $one = Crypt::OpenSSL::Bignum->one();
my $d = $e->mod_inverse($p->sub($one)->mul($q->sub($one), $ctx), $ctx);
print $d->to_decimal;
% perl decrypt.pl
1165876286233741
On peut alors lancer ''decrypt.py'' avec la clé privée trouvée :
_________
_| ___|_
| ___ | | | HZV
| |___| |___| |
|_ _| challenge by benjamin
| _ _ |
|_| |_| |_| c9132f892055ea81fd91a9ed0e54a859