BUUCTF [CISCN2018]oldstreamgame

lfsr题目

flag = "flag{xxxxxxxxxxxxxxxx}"
assert flag.startswith("flag{")
assert flag.endswith("}")
assert len(flag)==14

def lfsr(R,mask):
    output = (R << 1) & 0xffffffff
    i=(R&mask)&0xffffffff
    lastbit=0
    while i!=0:
        lastbit^=(i&1)
        i=i>>1
    output^=lastbit
    return (output,lastbit)

R=int(flag[5:-1],16)
mask = 0b10100100000010000000100010010100

f=open("key","w")
for i in range(100):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    f.write(chr(tmp))
f.close()

当然这里可以选择直接爆破 但是既然是lfsr就应该练习一下逆向
题目虽然做了100轮 每轮8个lfsr 但我们只需要32个就可以逆向求解flag了
取文件前32位:00100000111111011110111011111000
题目fwrite的是每次lfsr产生的lastbit值 而经过32次刚好就是原来的plaintext完整加密一次
我们根据lfsr线性反馈性质直接写出逆向decode:(最开始没 &mask ...)


mask = 0b10100100000010000000100010010100
s =     "00100000111111011110111011111000"
"""
已知32次lfsr每次的lastbit
其实32次做完lastbit组合成了最终的加密结果
要还原初始R
"""
# 0x926201d7
flag = 0b00100000111111011110111011111000
ori = ""
def decode():
        global mask,flag,ori
        i = (flag>>1)&(0xffffffff)
        i &= mask
        lowbit = flag&1
        lastbit = 0
        flag >>= 1
        # lastbit:在假设先前最高位为0条件下的反馈值
        while i!=0:
                lastbit ^= (i&1)
                i = i>>1
        if lastbit == lowbit:
                ori += '0'
                pass
        else:
                ori += '1'
                flag |= 1<<31

for i in range(32):
        decode()
print(flag)
print(bin(flag))
print(hex(flag))
print(ori)
print(hex(int(ori,2)))

然后就能得到flag的hex结果image

补:
用更清晰点的思路:
写一写式子发现就是从flag32 lastbit1 ... lastbit31 开始往回推
每次处理就是取当前前31位作为后31位 首位是未知的flag 初始填"0" lfsr算算看lastbit对不对的上来判断要不要改成"1"

s = "20FDEEF8A4C9F4083F331DA8238AE5ED083DF0CB0E7A83355696345DF44D7C186C1F459BCE135F1DB6C76775D5DCBAB7A783E48A203C19CA25C22F60AE62B37DE8E40578E3A7787EB429730D95C9E1944288EB3E2E747D8216A4785507A137B413CD690C"
tmp = []
for i in range(len(s)//2):
    tmp.append(int(s[i*2 : i*2+2],16))
mask = 0b10100100000010000000100010010100
s =     "00100000111111011110111011111000"


def lfsr(R,mask):
    R = int(R,2)
    i=(R&mask)&0xffffffff
    lastbit=0
    while i!=0:
        lastbit^=(i&1)
        i=i>>1
    return lastbit
m = ""
flag = s
for i in range(31,-1,-1):
    lastbit = int(s[i])
    flag = "0"+flag[:-1]
    pd = lfsr(flag,mask)
    if(pd==lastbit):
        m+="0"
    else:
        flag = "1"+flag[1:]
        m+="1"

print(hex(int(flag,2)))
print(m)
print(hex(int(m[::-1],2)))
posted @ 2023-10-06 15:47  N0zoM1z0  阅读(74)  评论(0编辑  收藏  举报