BerAESnang-senang
Diberikan file s34cret.py
dan servis ke min4tozaki.me 31000
.
Challenge
Kami memodifikasi kode program s34cret.py
agar mempermudah memahami implementasi enkripsi AES. Berikut hasil modifikasinya.
from Crypto.Cipher import AES
import sys
import os
key = os.urandom(16)
iv = os.urandom(16)
msg = "-isi pesan member TWICE-deomkicer"
msg = "A"*32
i = 0
class Unbuffered(object):
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def writelines(self, datas):
self.stream.writelines(datas)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
sys.stdout = Unbuffered(sys.stdout)
def pad(msg, v):
if len(msg) % 16 != 0:
msg = msg + str(v + 5) * ((16 - len(msg) % 16) - 1)
else:
msg = pad(msg + str(v + 5), v)
return msg
def cpadding():
padding = os.urandom(16)
return padding
def encryptSenang_senang(iv, key, plain, v):
cipher = AES.new(key, AES.MODE_CBC, iv)
print plain + str(v)
return (iv + cipher.encrypt(plain + str(v))).encode('hex')
print """
Selamat datang di Gemastik 12
Selamat bersenang-senang!
(https://min4tozaki.me)
Jangan aneh-aneh ya
"""
print "Senang-senang v" + str(i), ":"
print encryptSenang_senang(iv, key, pad(msg, i), i)
i += 1
while 1:
print """
Menu:
1. Tebak Senang-senang v0
2. Senang-senang v""" + str(i) + """
3. Keluar
"""
p = raw_input('Pilih : ')
if p == '1':
flag_f = raw_input("Input Senang-senang v0 : ")
try:
if flag_f == msg:
print '\nSelamat!!!'
print 'flag : gemastik12{' + msg +'}'
exit(1)
else:
print 'S4d :('
except:
exit(1)
elif p == '2':
new_msg = raw_input("Enkrip Senang-senang v"+ str(i) +" : ")
try:
print "\nSenang-senang v" + str(i), ":"
print encryptSenang_senang(iv, key, pad(new_msg, i), i)
i += 1
except:
exit(1)
elif p == '3':
exit(1)
else:
exit(1)
Solution
Setelah dianalisis, pilihan kedua yang disediakan oleh servis memungkinkan kita untuk mengenkripsi string bebas dengan key dan IV yang sama, sehingga kita bisa mengimplementasikan known-plaintext attack pada kriptosistem ini.
Langkah pertama, recover intermediate blocks dengan cara gunakan operasi XOR antara ciphertext dan plaintext (kami gunakan huruf A sebanyak 44 karakter sebagai plaintext dummy), berikut kode programnya.
blocks = []
while c:
blocks.append(c[:32])
c = c[32:]
print blocks
inter = []
for i in blocks:
inter.append(xors('A'*16, i.decode('hex')))
print inter
Langkah kedua, recover plaintext asli pada servis. Hal ini dapat dilakukan bila intermediate blocks sudah didapat secara menyeluruh. Kita dapat melakukan recover dengan menggunakan operasi XOR antara ciphertext asli dan intermediate blocks.
Implementation
def xors(a, b):
res = ''
for i in range(len(a)):
res += chr(ord(a[i]) ^ ord(b[i % len(b)]))
return res
def getiv(enc):
iv = enc[32:64]
enc = enc[96:]
pesan = enc[:-32]
return iv, pesan
enc = '8c6cde6fec14f9672d1d7bfa19be5055dbdbe6291d392102c7ef4ff595963e61345de9a61128cdbc4d6af5cfb707e4ea175d8985cc0eaa7ba6580182d8fd016bed45c0842c36f947b657239b1c4028ee323f4e87754f0eb077f2677afa46951f815c07f9857c89ee7d093a8ff58c00b5'
iv, pesan = getiv(enc)
c = iv+pesan
blocks = []
while c:
blocks.append(c[:32])
c = c[32:]
print blocks
inter = []
for i in blocks:
inter.append(xors('A'*16, i.decode('hex')))
print inter
enc = '1d70da1eadb566202f9e6cc4cc30cab4dbdbe6291d392102c7ef4ff595963e6116e40aad380ed4ad62ac2cdad15fd3fc6259fd9bbd298965d37517f7e0891f47986fc49a0032e760b2252e8568715acc424a43f3013b7ac40386130ef945961ee07c825a525ffb06259bfd3dca768ba5'
iv, pesan = getiv(enc)
c = iv+pesan
blocks = []
while c:
blocks.append(c[:32])
c = c[32:]
print blocks
flag = []
for i in range(len(inter)):
flag.append(xors(blocks[i].decode('hex'), inter[i]))
print flag
$ python rsa-sad.py
['dbdbe6291d392102c7ef4ff595963e61', '175d8985cc0eaa7ba6580182d8fd016b', 'ed45c0842c36f947b657239b1c4028ee', '323f4e87754f0eb077f2677afa46951f']
['\x9a\x9a\xa7h\\x`C\x86\xae\x0e\xb4\xd4\xd7\x7f ', 'V\x1c\xc8\xc4\x8dO\xeb:\xe7\x19@\xc3\x99\xbc@*', '\xac\x04\x81\xc5mw\xb8\x06\xf7\x16b\xda]\x01i\xaf', 's~\x0f\xc64\x0eO\xf16\xb3&;\xbb\x07\xd4^']
['dbdbe6291d392102c7ef4ff595963e61', '6259fd9bbd298965d37517f7e0891f47', '986fc49a0032e760b2252e8568715acc', '424a43f3013b7ac40386130ef945961e']
['AAAAAAAAAAAAAAAA', '4E5_0fb_4lW4y5_m', '4kE_mE_fE3L_5p3c', '14L555555555BBB@']
Flag berada pada block ke-2 dan seterusnya.
Flag
gemastik12{4E5_0fb_4lW4y5_m4kE_mE_fE3L_5p3c14L}