[CISCN2018]oldstreamgame

一道lfsr类型的题目(一开始纠结于flag的长度问题,32位怎么求出flag,但是flag不是字符而是用16进制来表示的,那就刚好了)
题目代码如下:

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()

因为以及给出了mask我们直接求逆就可以得出flag了,sage代码如下(将求出的二进制转为16进制就可以了,提交flag的时候前面加上0x)

MS=MatrixSpace(GF(2),32,32)
MSS=MatrixSpace(GF(2),1,32)
mask='10100100000010000000100010010100'
cm=[]
for i in range(31):
        cm.append(0)
cm.append(mask[0])
index=0
for i in range(31):
        for j in range(32):
                if j==index:
                        cm.append(1)
                else:
                        if j==31:
                                cm.append(mask[i+1])
                        else:
                                cm.append(0)
        index+=1
c=MS(cm)
try:
        c_inv=c.inverse()
except ZeroDivisionError as e:
        print 'no'
        exit
res=''
a=[0,0,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,0,0]
for i in range(32):
        t=a[:32]
        t=MSS(t)
        r=(t*c_inv)[0][0]
        a.insert(0,r)
        res=str(r)+res
print res
posted @ 2020-12-12 17:31  Mr_small  阅读(409)  评论(0编辑  收藏  举报