MoeCTF2023 ez_chain
这题我求出flag后代回去反复验证没有任何问题然而为什么这个flag long_to_bytes乱码啊!!!
先记录一下解题过程
题目代码:
from Crypto.Util.number import *
with open("key.txt", "r") as fs:
key = int(fs.read().strip())
with open("flag.txt", "rb") as fs:
flag = fs.read().strip()
assert len(flag) == 72
m = bytes_to_long(flag)
base = bytes_to_long(b"koito") # 461430682735
iv = 3735927943
def blockize(long):
out = []
while long > 0:
out.append(long % base)
long //= base
return list(reversed(out))
blocks = blockize(m)
def encrypt_block_cbc(blocks, iv, key):
encrypted = [iv]
for i in range(len(blocks)):
encrypted.append(blocks[i] ^ encrypted[i] ^ key)
return encrypted[1:]
print(encrypt_block_cbc(blocks, iv, key))
# [8490961288, 122685644196, 349851982069, 319462619019, 74697733110, 43107579733, 465430019828, 178715374673, 425695308534, 164022852989, 435966065649, 222907886694, 420391941825, 173833246025, 329708930734]
我们可以将enc[1]= enc[2]= enc[3]= 这三个式子两两xor消掉key得到三元方程组 利用z3约束求解
x = BitVec('x',72)
y = BitVec('y',72)
z = BitVec('z',72)
s = Solver()
s.add(x^y==enc[2]^iv)
s.add(x^z==enc[1]^enc[3]^enc[2]^iv)
s.add(y^z==enc[1]^enc[3])
print(s.check())
print(s.model())
得到x,y,z 后就可以得到key了
然后就是再逆向得到block[]
# [y = 277039157340, x = 398607643007, z = 68954767649]
key = 8490961288 ^ 398607643007 ^ 3735927943
block = []
for i in range(1,len(enc)):
dec = enc[i]^enc[i-1]^key
block.append(dec)
flag = 0
print(block)
最后就是base进制还原m
di = 1
for c in block:
# print(c)
flag += c*di
di*=base
得到了flag 我用题目代码跑完全正确 但这个flag没意义...
有师傅知道哪儿出问题了的话可以私我(求教thx