Boston Key Party 2017 - RSA-Buffet - Crypto Challenge

Reading time ~7 minutes

Quick write-up because this first part of the RSA challenges at BKP this year was trivial. Writing up mostly as a way to show how automation can help you a lot when solving CTF challenges. Even on the level of Boston Key Party which, as I re-remembered this week, is a pretty damn hard CTF.

The clue states that we will have 5 ciphertexts and 10 potential public keys for which they have been encrypted. Our job is to decrypt just 3 of these ciphertexts to recover our plaintext! Here’s the file in question.

So a file containing key’s sounds like a suspect for some nice attacks. Let’s extract it and see what we’re working with.

root@kali:~/bkp/rsabuffet# tar xf rsa-buffet.tar.bz2 
root@kali:~/bkp/rsabuffet# ls -la
total 92
drwxr-xr-x  2 root root     4096 Feb 27 23:17 .
drwxr-xr-x 11 root root     4096 Feb 27 23:17 ..
-rw-r--r--  1 1000 inetsim  1139 Feb 25 09:19 ciphertext-1.bin
-rw-r--r--  1 1000 inetsim  1139 Feb 25 09:19 ciphertext-2.bin
-rw-r--r--  1 1000 inetsim  1139 Feb 25 09:19 ciphertext-3.bin
-rw-r--r--  1 1000 inetsim  1140 Feb 25 09:19 ciphertext-4.bin
-rw-r--r--  1 1000 inetsim  1139 Feb 25 09:19 ciphertext-5.bin
-rw-r--r--  1 1000 inetsim  1993 Feb 25 09:13 encrypt.py
-rw-r--r--  1 1000 inetsim   498 Feb 25 09:13 generate-plaintexts.py
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-0.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-1.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-2.pem
-rw-r--r--  1 1000 inetsim  1491 Feb 25 09:19 key-3.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-4.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-5.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-6.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-7.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-8.pem
-rw-r--r--  1 1000 inetsim   800 Feb 25 09:19 key-9.pem
-rwxr--r--  1 root root    14842 Feb 27 23:17 rsa-buffet.tar.bz2
root@kali:~/bkp/rsabuffet# openssl rsa -in key-3.pem -text -noout -pubin
Public-Key: (4096 bit)
Modulus:
    00:99:4a:5e:2c:23:03:b4:09:43:d9:b7:44:b5:70:
    9e:e6:01:fb:5c:4a:c3:00:cf:a4:4a:76:08:10:7a:
    74:d0:6a:c0:49:63:a3:f8:20:1f:a7:80:13:35:ed:
    d3:f3:23:09:04:25:92:4b:74:f6:ac:39:ee:af:f7:
    b4:a6:bc:aa:24:15:33:fd:5f:57:50:5b:38:86:68:
    f2:4d:8d:65:33:07:45:cc:51:5e:e1:b3:c9:60:16:
    b3:99:c3:5e:ef:ef:06:12:ba:ff:82:76:10:88:11:
    7b:07:e2:5f:92:63:f9:14:98:10:23:31:91:65:d2:
    09:c4:78:4b:c3:7a:92:ed:7f:ec:b4:70:31:7b:3f:
    de:53:43:cd:d9:aa:13:79:4b:74:83:18:92:cf:6e:
    a1:00:2d:7a:3f:76:0f:1b:b3:ed:fb:f6:27:3b:15:
    36:11:27:42:4f:17:12:89:2e:0c:6c:c7:59:b3:c6:
    90:da:8c:61:84:a9:0b:e6:48:6b:8f:25:c7:45:55:
    4c:0a:aa:44:57:64:58:9a:51:77:03:8a:67:cd:73:
    e6:6f:e1:b0:d5:59:e0:bb:be:3e:5b:8d:4a:ee:f7:
    2f:fa:87:4c:c1:61:10:bb:c1:35:c3:e9:92:8c:5f:
    ca:e7:37:81:5f:49:fb:02:3c:64:ed:a6:2a:d2:ed:
    7d:0d:32:24:96:17:dc:51:2d:c5:40:00:6c:0f:05:
    9b:2f:da:eb:3b:0a:e1:c2:b9:61:5d:b7:c8:3b:90:
    9e:22:27:19:45:17:36:e1:f0:7c:39:19:c3:96:5f:
    d9:d0:03:bd:88:13:ec:1e:9c:d5:40:fa:f7:f7:0f:
    72:fe:8f:0f:54:4b:2c:ab:51:a8:a0:62:86:5a:e4:
    f4:6a:05:30:b7:e1:1a:26:4d:71:7f:3c:f1:3b:60:
    18:d0:9d:e1:a0:c2:8e:a2:0c:ee:2a:67:11:da:5d:
    11:5f:d7:1c:09:6d:11:5c:13:f0:b5:e4:0d:94:69:
    6c:67:10:5c:2f:70:9a:e5:d2:fe:0a:c8:58:47:b3:
    c9:01:7a:ce:7d:b2:eb:00:d4:10:d9:d2:da:76:85:
    77:6a:80:99:47:2d:01:79:1c:57:81:0d:16:0a:bd:
    6c:9e:42:02:76:32:0e:b1:1b:80:a0:b2:f5:72:2e:
    20:e9:d8:82:2a:1d:14:3c:97:a6:3e:f8:17:33:e5:
    2f:26:3e:3a:7f:77:b6:90:0b:f9:5d:a2:15:54:4d:
    f5:1e:61:ec:c4:68:f0:37:a2:b3:9c:cf:15:3d:98:
    4b:32:a9:a4:ce:75:7b:bb:38:79:8c:e0:b0:80:f5:
    03:ce:1a:39:6d:47:e1:4c:c4:1b:f1:8e:34:ed:bd:
    91:37:eb
Exponent:
    38:0d:01:ed:b6:ec:c7:5e:51:05:6e:f6:0d:ec:80:
    7a:8c:17:35:6e:a6:64:4e:cf:62:c2:b8:57:63:f7:
    9f:a6:5f:1b:54:d4:ff:28:3f:bb:0b:0b:3e:6f:a5:
    71:86:c5:2b:ea:20:e0:96:36:8c:19:41:41:cd:ed:
    75:97:8b:be:14:d2:70:9d:20:14:56:01:d0:dd:6b:
    7e:2d:f0:dd:ed:42:a5:14:d2:98:c6:81:82:28:9b:
    82:41:aa:09:af:eb:e7:f3:d0:a1:87:a6:54:5b:89:
    a0:6c:ee:52:87:e8:25:72:64:e0:4b:d0:96:83:d9:
    b4:b3:b0:4f:2e:a8:67:82:d3:e3:79:e5:01:4f:f6:
    16:20:2c:78:ad:9b:08:01:b6:7e:ee:ea:af:3b:43:
    05:5a:6f:09:6c:9b:fb:11:9f:1b:57:c7:8c:6e:40:
    50:ac:f3:c9:67:7f:93:25:7a:2b:aa:b9:ff:bc:0f:
    56:2f:c6:4d:46:8d:63:9d:b0:90:cd:b6:26:10:12:
    68:fb:c2:86:c5:c9:84:5a:ba:fb:6c:06:fc:06:25:
    90:4c:cf:32:83:7f:b2:fd:5d:16:0d:f8:36:0b:33:
    fe:2f:a5:5f:b4:3f:d4:ba:0b:a6:9d:de:44:f7:2f:
    9e:06:50:9a:63:6e:c8:45:68:57:59:7b:9a:55:30:
    b4:3b:6c:2f:11:03:8c:9f:ce:71:d5:de:bd:7b:63:
    c7:fb:1d:af:7c:84:37:90:93:b1:f9:d8:f5:e1:d4:
    ab:5e:96:e4:87:c4:ac:4c:d1:62:97:67:a5:59:e0:
    fe:95:69:99:75:d3:b2:96:9f:bc:48:e6:c0:52:9b:
    42:e4:50:51:ac:5c:e9:98:b8:a7:77:25:12:dc:32:
    c4:89:02:a9:96:c3:fb:d3:15:96:7b:e6:a4:03:55:
    63:08:8f:3b:be:e7:9d:c3:24:fd:08:3b:2e:52:9f:
    2d:11:4b:ae:5e:6d:ea:53:dd:e3:e5:18:08:1a:4a:
    13:e6:96:b5:0e:d8:a5:1b:ac:56:53:53:a9:8a:6b:
    84:1f:ad:79:8e:97:01:50:62:99:56:a4:81:6b:1d:
    79:68:f6:5c:ef:e7:1b:19:20:73:41:2c:dd:69:c0:
    c2:22:19:a4:9c:58:91:e6:36:66:2a:e3:42:9c:a9:
    c2:a3:a2:9a:89:25:16:74:b3:7c:07:6f:66:24:4b:
    41:fb:22:8c:82:56:89:67:c0:94:0e:45:4f:49:74:
    f6:8d:18:63:f7:39:8d:dd:62:31:fa:e8:c7:ff:6f:
    83:fa:f3:1b:47:2e:75:ae:26:ce:d5:98:19:1b:0f:
    62:7d:c2:75:9e:2a:9a:86:0a:3e:3b:03:ca:f6:8a:
    ac:bf

Oh my! That’s a large exponent! What do we know about large RSA exponents ? If the public exponent is large, the private exponent must be small. We can attack this with attacks such as Wiener. But stop… BKP know this is a trivial CTF problem these days. It’s featured many times. Even in last year’s BKP. So how much is it going to help us and is there a better way?

Finally a live CTF I can try an experimental mode of my RsaCtfTool fork. I forked this tool some time back and added several attacks. Most recently I added an dodgy “multikey” mode. Today we’re in luck because I can try it out. All I need to do is install it and point it at this challenge!

root@kali:~/bkp/rsabuffet# git clone https://github.com/sourcekris/RsaCtfTool
Cloning into 'RsaCtfTool'...
remote: Counting objects: 157, done.
remote: Total 157 (delta 0), reused 0 (delta 0), pack-reused 157
Receiving objects: 100% (157/157), 1.67 MiB | 113.00 KiB/s, done.
Resolving deltas: 100% (67/67), done.
root@kali:~/bkp/rsabuffet/RsaCtfTool# ./RsaCtfTool.py --publickey ../"*.pem" --verbose --private
[*] Multikey mode is EXPERIMENTAL.
[*] Keys: ['../key-9.pem', '../key-1.pem', '../key-6.pem', '../key-2.pem', '../key-7.pem', '../key-0.pem', '../key-8.pem', '../key-4.pem', '../key-5.pem', '../key-3.pem']
[*] Attacking key: ../key-9.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-1.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAxP9IaxTNnDe5VvCP8Zyi+D26hlCcuEDNalqV8TUgCbGNHVa0
oP7A6VopypbK76pd7/cdausK2J7qrZCM7pNYK9cbLNfa9wmlS5jRY7UI0/0fCpcJ
+2nkmdG4q8UK86TLrnfAcERJM2E6RSlU+RrNr0YdajZANZIFYfeIXTDr3IK+NWDm
QohkuXFeFzTQE+I9+4wdpmL1zm2jcSQC+NpEXQykm5ux5Hq+7vWKY4XKP5650kAI
...
ekJF9bpxy6wEqHqvoiV/PywEt9aYCVPVSxeUTSjrDeVmYM1RWcFTH2ogEzEAannA
1tOhN3nnio+NIZX1ii1iO9ZR/d5CmuAJAoIBAQCXB2VjFC6AYnxy5IiWy/kcmSXj
hTV3nAy190vk0YSk9s0SiTnWrkCVubF9CGMc43M9fLMUhpmqBnT/EpJLITTrtoxd
FN+ZEWXxLIQ2nJNrKkLDUlukV3Z/bk3+mKIJa1DH8ct56YOvD/7sKH7CQTRFkRh7
abGLrHyLw3VQuNHxEKQ8ljABn6DUMQO2fg8xC4xj1McnadM6I6A8ivZy4opgaS4r
TMPEdtafKx+y3vV2lWeLXMg4pP2vBVuTxU2IAmA7WWnua/6NH3dDkxxk+15i6Hkb
NjdCEEA/W8TlZUEj1ZKasazEiEUc5ynfDe1HlSc5ItduTbMQKwsVZiRdCSuC
-----END RSA PRIVATE KEY-----
[*] Attacking key: ../key-6.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-2.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
-----BEGIN RSA PRIVATE KEY-----
MIIIJQIBAAKCAgEAhphlSMArLWsEYadKCaXuTvoHiC1cYQvbFNG6METv/VVw5MUJ
0RasqZKjQs9S7QRj221GSKMBO6ghnDpysZmHliU90R7MU2CH5uW9IHwTh6+d9r+H
WrMZVW3MC61qkPAXRZdg7n0nT+YEbnWZOF92B9Ke0jVHdpXjNl/GufUnAYPpxMLB
GKpnbB2cvgaGRQfkMQ2FuMrP+fWj7tSHtx0tdbAJQ9ftqar1srtpJxYl3iRp1qfE
9QxO6sVLFgV5PMD3/pFnRS/1/vNkfJ7siGZzBzLAXcpMVvOTyi5h59dkQoIrnaVt
...
ZSe6nLUlopbSWZ+DWFX/mQtcK7LBVmdWCmnTym0dSUggy4KF8vTKswXgRXQiqnlU
xW4mqgIgT7OBLk/W6C11WPMR59de1vMg/jiQURvPc42W6WTDbFtONIbvm0Hyrp4O
26NIP4U+R8SHGWtNjZe6fl9aT9K60qm6aiPyz4HjdNm23n41wwb8ctXt3Khy+7zD
8gWlF7C7IPORwD28uuLBMI+ydElJe2mH7697oUmw2S+r2Fa4ofbasZC+P4GAohck
gtqdKy4kla8DlMoCCdgOwXIwtQIEdyhnBQ==
-----END RSA PRIVATE KEY-----
[*] Attacking key: ../key-7.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-0.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-8.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-4.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-5.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
[*] Performing commonfactors attack.
[*] Performing fermat attack.
[*] Performing siqs attack.
[*] Warning: Modulus too large for SIQS attack module
[*] Attacking key: ../key-3.pem
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 60 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
-----BEGIN RSA PRIVATE KEY-----
MIIH4wIBAAKCAgEAmUpeLCMDtAlD2bdEtXCe5gH7XErDAM+kSnYIEHp00GrASWOj
+CAfp4ATNe3T8yMJBCWSS3T2rDnur/e0pryqJBUz/V9XUFs4hmjyTY1lMwdFzFFe
4bPJYBazmcNe7+8GErr/gnYQiBF7B+JfkmP5FJgQIzGRZdIJxHhLw3qS7X/stHAx
ez/eU0PN2aoTeUt0gxiSz26hAC16P3YPG7Pt+/YnOxU2ESdCTxcSiS4MbMdZs8aQ
2oxhhKkL5khrjyXHRVVMCqpEV2RYmlF3A4pnzXPmb+Gw1Vngu74+W41K7vcv+odM
wWEQu8E1w+mSjF/K5zeBX0n7Ajxk7aYq0u19DTIklhfcUS3FQABsDwWbL9rrOwrh
...
0gqHns/TpRQoYzMrGjnGkXmXD/CFXOqUGbfF6vJJvQKTjoX7iR5GrT74MFklh8VE
JtJm7zje0ilzUIieHGImq2P393bAqRGRU9ssvwnwFVuF0kquNEJ33JZk6Yimpoci
RlhXx3JoHdPBdUXDhB5xfzzZodo6s6JAggGR1hXa7LzFEEDGI/JHbMAiyFqLMgRR
/5OvnxwxxRBTY5FwTnaREvF+1T6wp6U+EU7in9tN6Cmx01ThJTojur25ZUCQmuFG
XIf01nQakFrOA5xh3KfZ+jDx0PHlAJnoMF1IdANccnwP1f0/uBFoMasNi67uedTe
kDk2ESJfSQ==
-----END RSA PRIVATE KEY-----
[*] Performing multi key attacks.
[*] Found common factor in modulus for ../key-6.pem and ../key-0.pem
28796899277235049975421947378568428888005019408631005870725337759187744546493409470582705210790627097597656481534493716225301660663533212040068163723937803169735485217437722947354732420098585958967033073629288721874028940705969141716032409906092583043329293532612601200186754187377338924379443611709918885185638934712580040042904995838353611699081350712817357237035507539201368300463060034856220488010509411264244138417348439340955309300128758040513940379009974696105387107481999359705587790254117489020540714253505694682552102843028243384677060490696214834957049391213864664165843655260698241682369402177091178720927
[*] Found common factor in modulus for ../key-0.pem and ../key-6.pem

Note I truncated some of the verbose output a little for brevity.

So out of that first pass we effectively:

  • Fully recovered key-1.pem’s private key using fermat factorization
  • Fully recovered key-2.pem’s private key from factordb
  • Fully recovered key-3.pem’s private key using the Wiener attack
  • Recovered a shared large prime of both key-0.pem and key-6.pem. My tool hasn’t fully fleshed out this functionality yet. It’s a rough draft :)

To recover both key-0 and key-6 private keys, we could save the new prime we got from the first pass into the pastctfprimes.txt file and re-run the script for those two keys like so:

root@kali:~/bkp/rsabuffet/RsaCtfTool# ./RsaCtfTool.py --publickey ../key-0.pem --private
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEA168ysJPW4iS7ljqae8hzsud8as52Pn1sbdfR0RGChS9oS1A9
1y52lP3sRmivv2+QxK9GYqvuHDozxQ7FxSqMCpqvTQ8xYeu07nYioi/x+2e5MCPU
lDEwb/wBQBkbEHexFMyohNtMzdjR97sTHvMhtJBwA1SBYZIdKTpCYxiXCLoHVUUq
...
aQNO4a6g0as2bcQK3AE0QrY9PY6+ujcopKTDmGaZQHx2ryU9c0yy8cfPs+4prpVU
JmSd7oCEcGnjQXMyM0kibZ0Ow6uFJUm0Lzvs04EbpW2aPn+HEiAV65pLupbrVG6A
/U0ehyAdriJlxQPOe+aLWcli9kEnk2MZBIa2E9Ty0xQ+jWyJzI2Xg5/RiS7NKNPO
lUU3Zwr58kgYZp3R4KkGXe8VvlY5UbkgkkZvmJJS/kJwe4o+jMJz8wa4Zqm6
-----END RSA PRIVATE KEY-----
root@kali:~/bkp/rsabuffet/RsaCtfTool# ./RsaCtfTool.py --publickey ../key-6.pem --private
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAvA1N2e1ExEwhc6vTsCVAGzZoFtkT97QnG3Grze0hqw0EwvxX
ejE7eUJ1hF27iegVHPS9OCXpJAyI65OoJMqosLVjlg/8sS+8r82dOPvfh7E0OV0O
oxYYa+ryRwpTWh2jUpwAXLkGLw1D64579M15Qlpsq2WhXJBXE6vO2/SnFcRkZb7L
...
aQ3uIAXSUp/pUP62spE2ZyBACRDYhqaLnhOUP+vnD61DzvE1L1GFzXdpLitkE1D8
MpYS/nfBmZMeAwmwjUDDQBaozl78qQL2RoXqcb86X3TWEwTw22gs/ZhaUr9HlEjO
UNbZPbHnTki3uaU3KyUogHB9/OubnLu9NKdisSGusn4zAYkr3dw6EHnL8GxjGkHk
cI/lY0TZFhR/6EmXxtzgAMxwnb5H0TMRgfdCjmcnuxnHB5wCchX9wi8S5Roe
-----END RSA PRIVATE KEY-----

That’s 5/10 private keys fully recovered. The next stage of this challenge is to decrypt at least 3 ciphertext-N.bin files and recover the flag. Fortunately BKP team have documented how they built these ciphertexts very well. The provided encrypt.py has a handy decrypt() function:

 def decrypt(private_key, ciphertext):
  if len(ciphertext) < 512 + 16: 
    return None
  msg_header = ciphertext[:512]
  msg_iv = ciphertext[512:512+16]
  msg_body = ciphertext[512+16:]
  try:
    symmetric_key = PKCS1_OAEP.new(private_key).decrypt(msg_header)
  except ValueError:
    return None
  if len(symmetric_key) != 32: 
    return None
  return AES.new(symmetric_key,
      mode=AES.MODE_CFB,
      IV=msg_iv).decrypt(msg_body)

Following that we need to use the Shamir secret sharing python module to convert the distributed secret into plaintext. Again the BKP team documented that in generate-plaintexts.py:

# pip install secretsharing
# https://github.com/blockstack/secret-sharing
from secretsharing import PlaintextToHexSecretSharer as SS

Pulling it all together I wrote this quick solver after saving all the recovered private keys into key-N.priv filename format:

 from Crypto.Cipher import AES,PKCS1_OAEP
from Crypto.PublicKey import RSA
from secretsharing import PlaintextToHexSecretSharer as rs
import glob
def decrypt(private_key, ciphertext):
  if len(ciphertext) < 512 + 16:
    return None
  msg_header = ciphertext[:512]
  msg_iv = ciphertext[512:512+16]
  msg_body = ciphertext[512+16:]
  try:
    symmetric_key = PKCS1_OAEP.new(private_key).decrypt(msg_header)
  except ValueError:
    return None
  if len(symmetric_key) != 32:
    return None
  return AES.new(symmetric_key,
      mode=AES.MODE_CFB,
      IV=msg_iv).decrypt(msg_body)
if __name__=="__main__":
  cts = glob.glob('ciphertext-?.bin')
  keys = glob.glob('key-?.priv')
  secrets = []
  for k in keys:
     for c in cts:
        private_key = RSA.importKey(open(k).read())
        ciphertext = open(c,'rb').read()
        plaintext  = decrypt(private_key,ciphertext)
        
        if plaintext is not None:
           if 'Congrat' in plaintext:
              secrets = secrets + plaintext.splitlines()[1:]
  for sec1 in [x for x in secrets if '1-' in x]:
     for sec2 in [x for x in secrets if '4-' in x]:
        for sec3 in [x for x in secrets if '5-' in x]:
           rec = rs.recover_secret([sec1,sec2,sec3])
           if 'FLAG' in rec:
              print rec

Which gives us a nice result:

root@kali:~/bkp/rsa-buffet.orig# python dec.py
Three's the magic number!  FLAG{ndQzjRpnSP60NgWET6jX}

Interviewing in Tech: Security Engineer & Security Analyst

Landing a job as a security engineer or analyst at a tech company is a significant feat. It requires not only technical acumen but also s...… Continue reading

BSides Sydney 2023 Writeups

Published on November 24, 2023

DUCTF 2023 Writeups

Published on August 31, 2023