CTF-Streamgame1-writeup

Streamgame1

题目信息:

附件:

streamgame1.py

from flag import flag
assert flag.startswith("flag{")
# 作用:判断字符串是否以指定字符或子字符串开头flag{
assert flag.endswith("}")
# 作用:判断字符串是否以指定字符或子字符串结尾},flag{},6个字节
assert len(flag)==25
# flag的长度为25字节,25-6=19个字节
#3<<2可以这么算,bin(3)=0b11向左移动2位变成1100,0b1100=12(十进制)
def lfsr(R,mask):
    output = (R << 1) & 0xffffff    #将R向左移动1位,bin(0xffffff)='0b111111111111111111111111'=0xffffff的二进制补码
    i=(R&mask)&0xffffff             #按位与运算符&:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0
    lastbit=0
    while i!=0:
        lastbit^=(i&1)    #按位异或运算符:当两对应的二进位相异时,结果为1
        i=i>>1
    output^=lastbit
    return (output,lastbit)

R=int(flag[5:-1],2)
mask    =   0b1010011000100011100

f=open("key","ab")   #以二进制追加模式打开
for i in range(12):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out   #按位异或运算符:当两对应的二进位相异时,结果为1
    f.write(chr(tmp))  #chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
f.close()

key

解题思路:

1.观察py文件,可知flag的长度为25格式为flag{xxxx}其中xxxx为19位的二进制串
2.观察py文件,可知key文件是该脚本的输出,脚本中每轮循环输出1个字节,共输出12字节的数据
3.由于xxxx只有19位,考虑直接爆破

附件:

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

with open("key","rb") as f:
    filek = f.read(12)
    res = bytes()
    for a in range(2**19):
        R=a
        mask=0b1010011000100011100
        for i in range(12):
            tmp=0
            for j in range(8):
                (R,out)=lfsr(R,mask)
                tmp=(tmp << 1)^out
            res += tmp.to_bytes(length=1,byteorder='big',signed=False)
        print(a,res,filek)
        if res == filek:
            break
        else:
            res = bytes()

FLAG

flag

作者:damedane-qiuqiu

posted @ 2021-07-16 23:19  泠雪  阅读(1767)  评论(0编辑  收藏  举报