攻防世界——streamgame1
攻防世界——streamgame1
原理:爆破flag
题目:

题解:拿到两个文件,先看一下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的二进制补码 24i=(R&mask)&0xffffff #按位与运算符&:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 24lastbit=0while i!=0:lastbit^=(i&1) #按位异或运算符:当两对应的二进位相异时,结果为1i=i>>1output^=lastbitreturn (output,lastbit)R=int(flag[5:-1],2)
mask = 0b1010011000100011100f=open("key","ab") #以二进制追加模式打开
for i in range(12):tmp=0for j in range(8):(R,out)=lfsr(R,mask)tmp=(tmp << 1)^out #按位异或运算符:当两对应的二进位相异时,结果为1f.write(chr(tmp)) #chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
f.close()
分析代码:flag总共19位,且从21行能看出flag应该是2进制,lfsr应该是加密函数。从下面看出有8次循环,每次返回一个比特,8个比特组成一个字节,总共有十二个,都存到key文件中。
key文件

分析加密的方法比较困难,但因为flag只有19位,即2**19种可能,可以直接爆破。
代码:
def lfsr(R,mask):output = (R << 1) & 0xffffff #将R向左移动1位,bin(0xffffff)='0b111111111111111111111111'=0xffffff的二进制补码i=(R&mask)&0xffffff #按位与运算符&:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 24lastbit=0while i!=0:lastbit^=(i&1) #按位异或运算符:当两对应的二进位相异时,结果为1i=i>>1output^=lastbitreturn (output,lastbit)
key = [0x55,0x38,0xf7,0x42,0xc1,0x0d,0xb2,0xc7,0xed,0xe0,0x24,0x3a]
mask = 0b1010011000100011100
tmp = 0
tip = 0
for k in range(2**19):R = ktip = 1for i in range(12):tmp = 0for j in range(8):(R,out)=lfsr(R,mask)tmp=(tmp << 1)^outif tmp != key[i]:tip = 0breakif tip == 1:print("flag{"+bin(k)[2:]+"}")break
flag{1110101100001101011}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
