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

posted @ 2023-10-12 12:08  N0zoM1z0  阅读(25)  评论(0编辑  收藏  举报