攻防世界streamgame1

题目下下来的附件有两个,1个.py文件,1个二进制文件,.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()

差不多就是根据flag计算出12个字符,依次写入key文件,这种题目一般就爆破和逆运算2种思路,这里我们先读取key文件,看看是什么内容

f = open('key','rb')
content = f.read()
s_list = []
for c in content:
    s_list.append(c)

结果如下:

[85, 56, 247, 66, 193, 13, 178, 199, 237, 224, 36, 58]

然后可以知道的是flag是19位二进制数,范围是0-2^20 - 1,所以写脚本来爆破,完整代码如下:

def check(list1, list2):
    for i in range(12):
        if list1[i] != list2[i]:
            return False
    return True


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)


if __name__ == '__main__':
    f = open('key','rb')
    content = f.read()
    s_list = []
    for c in content:
        s_list.append(c)

    print(s_list)

    mask = 0b1010011000100011100

    for i in range(1 << 19):
        print(i)
        tmp_list = []
        R = i
        for j in range(12):
            tmp = 0
            for k in range(8):
                (R, out) = lfsr(R, mask)
                tmp = (tmp << 1) ^ out  # 按位异或运算符:当两对应的二进位相异时,结果为1
            tmp_list.append(tmp)

        if (check(s_list, tmp_list)):
            print(bin(i))
            break

即可得到flag

1110101100001101011

 注意加上flag{}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值