XCTF 2018 - Easy Fs
Masalah
==============================
Welcome to Nu1L Easy FS
==============================
1. File list
2. Read encrypted file
3. Custom encryption
4. Quit
==============================
Input your choice:
==============================
Penyelesaian
Alur program berjalan dengan membangkitkan nilai N
secara acak, kemudian meminta input untuk nilai E
. Kelemahan ada pada fungsi Custom Encryption
. Jika dimasukkan nilai 0x3
terus menerus sampai benar pada nilai E
maka opsi Read encrypted file
akan menggunakan nilai E=0x3
sehingga dapat menyebabkan Broadcast Message yang bisa diselesaikan dengan Hastad Broadcast Message Attack
.
$ apt install python-openssl &&
apt install python-gmpy &&
apt install python-gmpy2
# solver.py
from pwn import *
import re
import gmpy2
import binascii
r = lambda x: log.info(s.recv(2**x))
exactly = 0
while exactly != True:
n = []
c = []
while len(n) != 3 and len(c) != 3:
s = remote('47.52.195.203', 2333)
r(12)
s.sendline('3')
z = s.recv(2**12)
z += s.recv(2**12)
log.info(z)
o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
log.info(o)
if not o:
z += s.recv(2**12)
log.info(z)
o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
log.info(o)
check1 = False
while check1 != True:
s.sendline('3')
z = s.recv(2**12)
log.info(z)
s.sendline('X')
z = s.recv(2**12)
log.info(z)
x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
log.info(x)
if x:
if '10001' not in z:
pass
else:
z += s.recv(2**12)
log.info(z)
x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
log.info(x)
if '10001' not in z:
pass
log.info('Struktur Kondisi 1')
if len(x[0]) < 16:
s.sendline('n')
check1 = True
else:
s.sendline('y')
z = s.recv(2**12)
log.info(z)
z = s.recv(2**12)
log.info(z)
s.sendline('2')
z = s.recv(2**12)
log.info(z)
s.sendline('flag')
z = s.recv(2**12)
log.info(z)
o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
log.info(o)
if not o:
z += s.recv(2**12)
log.info(z)
o = re.findall(r'N = 0x([0-9a-fA-F]+)', z)
log.info(o)
s.sendline('3')
z = s.recv(2**12)
log.info(z)
x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
log.info(x)
if x:
if '10001' not in z:
n.append(o[0])
c.append(x[0])
else:
z += s.recv(2**12)
log.info(z)
x = re.findall(r'C = 0x([0-9a-fA-F]+)', z)
log.info(x)
if '10001' not in z:
n.append(o[0])
c.append(x[0])
print len(n), len(c)
s.close()
print n, c
N = [gmpy2.mpz(str(int(x,16))) for x in n]
C = [gmpy2.mpz(str(int(x,16))) for x in c]
e = 3
m = [0, 0, 0]
M = N[0]*N[1]*N[2]
m[0] = M/N[0]
m[1] = M/N[1]
m[2] = M/N[2]
t = [ccc*mmm*gmpy2.invert(mmm,nnn) for ccc, mmm, nnn in zip(C, m, N)]
xxx = (t[0] + t[1]+ t[2]) % M # Chinese reminder theorem
p, exactly = gmpy2.iroot(xxx,e) # recover m
print exactly
raw_input('debug?')
print hex(p).lstrip('0x')
try:
print hex(p).lstrip('0x').decode('hex')
except:
pass
raw_input('debug?')
if exactly:
print hex(p).lstrip('0x')
print hex(p).lstrip('0x').decode('hex')