Update encrypt.py

This commit is contained in:
Omar Santos 2020-05-11 01:59:25 -04:00 committed by GitHub
parent edf148cb95
commit c4f6f98836
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,9 +1,3 @@
Heavy computation(400)
Question:
A friend of mine handed me this script and challenged me to recover the flag. However, I started running it on my school cluster and everything is burning now... Help me please!
Given files:
encrypt.py
from Crypto.Util.number import bytes_to_long, long_to_bytes from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import pad from Crypto.Util.Padding import pad
@ -49,76 +43,3 @@ enc = cipher.encrypt(pad(flag,16))
with open("flag.enc","wb") as output_file: with open("flag.enc","wb") as output_file:
output_file.write(enc) output_file.write(enc)
flag.enc(dump)
0000 f4 d8 e5 a2 ac 80 6c e9 dc c1 ef 1e d5 c4 51 7c ......l.......Q|
0010 e3 d8 84 1a d7 c0 77 c9 9c b0 f6 f0 ab 13 63 b0 ......w.......c.
0020 f9 5e 8d cd 87 ce c7 d3 88 7a 4a 68 de a9 6f 96 .^.......zJh..o.
0030 77 cf 1e a7 95 a0 f8 1c be 3a 66 f0 aa 73 2c 3e w........:f..s,>
Solution:
Outline:
(1) For preparartion, we calcurate Euler's totient of N by FactorDb( http://www.factordb.com/ ):
N=5*23*61*701*3043975283150884175290138965903193067634156680289693153778518185326633105971710936004483047892546798724665417739250476586249010832824560305913279982496088828053414799963361876618585076997170323631281630177651847
(2) First part of the functuon "derive_key":
for i in range(NB_ITERATIONS):
start = start ** e
start %= N
It is easily simplificated by Euler's theorem.
start = pow(bytes_to_long(password),pow(e,NB_ITERATIONS,phi_N), N)
where phi_N is the totient of N,
phi_N=(5-1)* (23-1)* (61-1)* (701-1)* (3043975283150884175290138965903193067634156680289693153778518185326633105971710936004483047892546798724665417739250476586249010832824560305913279982496088828053414799963361876618585076997170323631281630177651847-1)
(3) Second Part of the functuon "derive_key":
key = 1
for i in range(NB_ITERATIONS):
key = key ** e
key %= N
key *= start
key %= N
We can replace it with the following (using "invert" function of gmpy2).
inv_e = gmpy2.invert(e-1,phi_N)
key = pow(start, (pow(e,NB_ITERATIONS,phi_N)-1) * inv_e, N)
(4) Finally, We brute force the password and get the flag!
Solver:
solve.py
from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from hashlib import sha256
import gmpy2
NB_ITERATIONS = 10871177237854734092489348927
e = 65538
N = 14968794114523720195251887716913440457986979987674770429103169854116498198112478103466085455257317270930523061714030307370028304505577267672733143013124254253285088080041831478700041394909740024011681885623055622400205
#Using FactorDB, we have N=5*23*61*701*3043975283150884175290138965903193067634156680289693153778518185326633105971710936004483047892546798724665417739250476586249010832824560305913279982496088828053414799963361876618585076997170323631281630177651847
phi_N = (5-1)*(23-1)*(61-1)*(701-1)*(3043975283150884175290138965903193067634156680289693153778518185326633105971710936004483047892546798724665417739250476586249010832824560305913279982496088828053414799963361876618585076997170323631281630177651847-1)
def derive_key(password):
start = bytes_to_long(password)
start = pow(start,pow(e,NB_ITERATIONS,phi_N), N)
inv_e = gmpy2.invert(e-1,phi_N)
key = pow(start, (pow(e,NB_ITERATIONS,phi_N)-1) * inv_e, N)
return sha256(long_to_bytes(key)).digest()
with open('flag.enc','rb') as f:
flag_enc = f.read()
for i in range(0x20, 0x100):
for j in range(0x20, 0x100):
password = long_to_bytes(i) + long_to_bytes(j)
key = derive_key(password)
IV = b"random_and_safe!"
cipher = AES.new(key, AES.MODE_CBC,IV)
flag = cipher.decrypt(flag_enc)
if(flag[0:6] == b'shkCTF'):
print(flag.decode('utf-8')[0:flag.decode('utf-8').find('}')+1])
break
Flag:
shkCTF{M4ths_0v3r_p4t13Nce_b4453d1f9f5386a1846e57a3ec95678f}