[AFCTF2018]Tiny LFSR

本文介绍了如何使用Python脚本Encrypt.py实现基于线性反馈移位寄存器(LFSR)的加密,以及如何通过分析加密后的密文(cipher.txt)和明文(Plain.txt)来恢复关键信息,最终提取出flag。解码过程涉及密钥的提取和异或运算。
摘要由CSDN通过智能技术生成

1.题目

#Encrypt.py:
import sys
from binascii import unhexlify

if(len(sys.argv)<4):
	print("Usage: python Encrypt.py keyfile plaintext ciphername")
	exit(1)

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

R = 0
key = ""
with open(sys.argv[1],"r") as f:
	key = f.read()
	R = int(key,16)
	f.close
	
mask = 0b1101100000000000000000000000000000000000000000000000000000000000

a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])

f=open(sys.argv[2],"r")
ff = open(sys.argv[3],"wb")
s = f.read()
f.close()
lent = len(s)

for i in range(0, len(a)):
	ff.write((ord(s[i])^ord(a[i])).to_bytes(1, byteorder='big'))

for i in range(len(a), lent):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    ff.write((tmp^ord(s[i])).to_bytes(1, byteorder='big'))
ff.close()


#cipher.txt:not visible

#flag_encode.txt: not visible

#plain.txt: sdgfjkahblskdjxbvfskljdfbguisldfbvghkljsdfbghsjkldhbgjklsdbgvlkjsdgbkljb sdkljfhwelo;sdfghioeurthgbnjl k

#.bash_history.txt:
'''
python Encrypt.py key.txt Plain.txt cipher.txt
python Encrypt.py key.txt flag.txt flag_encode.txt
rm flag.txt
rm key.txt
'''

2.分析

.bash_history.txt文件中的信息是说,使用了同一份key.txt对Plain.txt和flag_encode.txt进行加密,得到了cipher.txt和flag_encode.txt。

mask的长度:

0b1101100000000000000000000000000000000000000000000000000000000000
length = 64

留意题目中的这部分代码:

for i in range(0, len(a)):
	ff.write((ord(s[i])^ord(a[i])).to_bytes(1, byteorder='big'))

for i in range(len(a), lent):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    ff.write((tmp^ord(s[i])).to_bytes(1, byteorder='big'))

密文的前面较少的一部分使用可以来进行异或加密,所以我们只需要让密文和明文异或就能够得到key,然而我们不能知道密文的长度,我们先看一下直接异或后所有的输出

import codecs
import binascii
from Crypto.Util.strxor import strxor

cip = open('cipher.txt', 'rb').read()
msg = open('Plain.txt', 'rb').read()

bytes_data= strxor(cip, msg)[:len(cip)]
print(binascii.b2a_hex(bytes_data))

输出:

b'0123456789abcdef184bb2ec4d1ee7b86e3a6e926e3a6e8d203b2e03203b2f2c6226e22e6226fad1953215e7953374e745e7cf6d45f97467bf6adc09be5779eecc4444ccd535dba9f2aaa7fe85ad0b2aa800a81ff94ff680380e39205550c78208801067007b0cb6'

我们注意到其前16个恰好是连续的字符串,我们猜测这是key,前16个字符:

b'0123456789abcdef'

在得到了key之后,解题就只需要再一次进行异或运算即可

解题代码:

import sys
from binascii import unhexlify
from Crypto.Util.strxor import strxor
import codecs


key = '0123456789abcdef'
R = int(key, 16)
def lfsr(R, mask):
	output = (R << 1) & 0xffffffffffffffff
	i=(R&mask)&0xffffffffffffffff
	lastbit=0
	while i!=0:
		lastbit^=(i&1)
		i=i>>1
	output^=lastbit
	return (output,lastbit)

mask = 0b1101100000000000000000000000000000000000000000000000000000000000

cip = open('flag_encode.txt', 'rb').read()
a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])
#上面这步是将a中的16进制范围内的字符每2个一组,构成0~255范围内的8个字符,然后与密文进行异或运算,密文读入时是'\xaa'的形式
lent = len(cip)
ans = []

for i in range(len(a)):
    ans.append(chr((cip[i] ^ ord(a[i]))))

for i in range(len(a), lent):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
        #位移8次得到一个8位的序列,这个序列用于后续的异或运算
    ans.append(chr(tmp ^ cip[i]))
    #原本的加密没有改变信息原文的长度,于是可以对其进行简单异或还原信息
    #cip[i]算作是int类型数据,故可以进行异或运算

print(''.join(ans))

输出:

In computing, a linear-feedback shift register (LFSR) is a shift register whose input bit is a linear function of its previous state.

The most commonly used linear function of single bits is exclusive-or (XOR). Thus, an LFSR is most often a shift register whose input bit is driven by the XOR of some bits of the overall shift register value.

The initial value of the LFSR is called the seed, and because the operation of the register is deterministic, the stream of values produced by the register is completely determined by its current (or previous) state. Likewise, because the register has a finite number of possible states, it must eventually enter a repeating cycle. However, an LFSR with a well-chosen feedback function can produce a sequence of bits that appears random and has a very long cycle.

Applications of LFSRs include generating pseudo-random numbers, pseudo-noise sequences, fast digital counters, and whitening sequences. Both hardware and software implementations of LFSRs are common.

The mathematics of a cyclic redundancy check, used to provide a quick check against transmission errors, are closely related to those of an LFSR.

Congratulations! flag is afctf{read_is_hard_but_worthy}

flag在最后一行:

afctf{read_is_hard_but_worthy}

4.参考

文章1

文章2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值