LFSR记录

原理大佬讲的够清楚了,直接上题

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
github