原理大佬讲的够清楚了,直接上题
flag = "flag{xxxxxxxxxxxxxxxx}"
assert flag.startswith("flag{")
assert flag.endswith("}")
assert len(flag)==14
def lfsr(R,mask):
output = (R << 1) & 0xffffffff#左移1位后取低32位
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()
i=(R&mask)&0xffffffff
mask只有第3、5、8、12、20、27、30、32这几位为1,与R进行与运算,结果只有这几位可能为1(当且仅当R对应位也为1时成立)。再取低32位。
while i!=0:
lastbit^=(i&1)
i=i>>1
依次取低位进行异或,为0的位可以忽略,因为0异或任何数等于任何数本身,不影响最后运算结果,因此lastbit的值仅取决于i中有多少个1:当i中有奇数个1时,lastbit等于1;当i中有偶数个1时,lastbit等于0。
当R的第3、5、8、12、20、27、30、32这几位依次异或结果为1时,即R中有奇数个1,因此将导致i中有奇数个1;当R的第3、5、8、12、20、27、30、32这几位依次异或结果为0时,即R中有偶数个1,因此将导致i中有偶数个1。 因此我们可以建立出联系:lastbit等于R的第3、5、8、12、20、27、30、32这几位依次异或的结果。
故$lastbit = R_3 ⊕ R_5 ⊕R_8 ⊕R_{12} ⊕R_{20} ⊕R_{27} ⊕ R_{30} ⊕R_{32}$
mask = '10100100000010000000100010010100'
key = '00100000111111011110111011111000'
tmp=key
R = ''
for i in range(32):
output = '?' + key[:31]
ans = int(tmp[-1-i])^int(output[-3])^int(output[-5])^int(output[-8])^int(output[-12])^int(output[-20])^int(output[-27])^int(output[-30])
R += str(ans)
key = str(ans) + key[:31]
R = format(int(R[::-1],2),'x')
flag = "flag{" + R + "}"
print(flag)
另一种题型,mask未知,R已知:
import random
from secret import mask
from Crypto.Util.number import *
#
def lfsr(R, mask):
output = (R << 1) & 0xffffffffffffffffffffffffffffffff
i = (R & mask) & 0xffffffffffffffffffffffffffffffff
lastbit=0
while i != 0:
lastbit ^= (i & 1)
i = i >> 1
output ^= lastbit
return (output,lastbit)
flag = b'flag{' + mask + b'}'
num_mask = bytes_to_long(mask)
R = random.getrandbits(128)
print(R)
for _ in range(128):
R,out = lfsr(R,num_mask)
print(R)
'''
176011035589551066670092363165068881602
157117237038314150714243518116791116977
'''
深入分析CTF中的LFSR类题目(一)-安全客 - 安全资讯平台 (anquanke.com)
深入分析CTF中的LFSR类题目(二)-安全客 - 安全资讯平台 (anquanke.com)
R = 176011035589551066670092363165068881602
output = 157117237038314150714243518116791116977
R_list = [R]
for i in range(1,128):
R =((R<<1)^^ (output >>127))&0xffffffffffffffffffffffffffffffff
output = (output < 1)&0xffffffffffffffffffffffffffffffff
R_list.append(R)
# print(R_list)
R_binary_list = [list(format(R, '0>128b'))for R in R_list]
R_int_list = [[int(bit) for bit in binary] for binary in R_binary_list]
Rt = matrix(Zmod(2),R_int_list).transpose()
c = [0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1]
print(len(c))
c = matrix(Zmod(2), c)
m = Rt.solve_left(c)
print(m)
m = 87985526350865221468704373212448903457
print(long_to_bytes(m))
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1666739907@qq.com