BUUCTF Crypto [AFCTF2018]Tiny LFSR wp

这题看起来特别的麻烦,我们先来一步步分析。题目用同一个加密脚本加密了两份文件,一份是plain加密得到的cipher,另一个是flag加密得到的flagencode,再看看加密的方式,前一部分是通过lfsr的密钥key与plain前一部分按位异或得到的,后一部分是通过,lfsr生成的密钥流与plain的后一部分按位异或得到的,感觉就是特别的繁琐了。于是,我们的思路是先通过cipher与plain按位异或得到key值先,然后我们可以知道LFSR中的key与mask位数是相同的,看了一下mask的位数是二进制64位,那么key的位数就是16进制16位,也就是8位ASCII字符,于是我们设置异或的长度为8个字符,当然也可以设置更多

cipher="72472201E3C0AC877A27C18729749FDA185C1DF902500AEB425C5B6A53574B4A00508546094A90A2F1547780FD401E8C2983A70F22931F0BCC0EBE6EC83B1284BF2023AEBE59B1CBD2D9C395E9C76D42DF65C470C23C92E65F66504F3025B5F660E772096A172CDD"
c=cipher.decode('hex')
#print c
plain="sdgfjkahblskdjxbvfskljdfbguisldfbvghkljsdfbghsjkldhbgjklsdbgvlkjsdgbkljb sdkljfhwelo;sdfghioeurthgbnjl k"
a=""
for i in range(0, 8):
	a+=chr(ord(c[i])^ord(plain[i]))
print a

通过这样即可得到密钥key,也可以带入原脚本验证

cipher="72472201E3C0AC877A27C18729749FDA185C1DF902500AEB425C5B6A53574B4A00508546094A90A2F1547780FD401E8C2983A70F22931F0BCC0EBE6EC83B1284BF2023AEBE59B1CBD2D9C395E9C76D42DF65C470C23C92E65F66504F3025B5F660E772096A172CDD"
c=cipher.decode('hex')
#print c
plain="sdgfjkahblskdjxbvfskljdfbguisldfbvghkljsdfbghsjkldhbgjklsdbgvlkjsdgbkljb sdkljfhwelo;sdfghioeurthgbnjl k"
a=""
for i in range(0, 8):
	a+=chr(ord(c[i])^ord(plain[i]))
print a

可以发现与给的cipher的后一部分相同,可以认为得到的key是正确的,于是我们可以生成lfsr产生的密钥流,生成位数设置位flagencode的位数

R = bytes_to_long(a)
tmptext=""
#for i in range(len(a), len(plain)):
for i in range(len(a), 1213):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    tmptext+=chr(tmp)
print 2,tmptext

这里要注意,一定要初始话R的值
于是我们可以开始求解flag,先将前一部分与key按位异或

flagencode1="484D6504E6C6BD9A6C22DC8B613E8698025300F70F4843EB455E4A614158440C114E8B48160688B4F25B6693F04154CF09A19C3F6CD91D149F0BFC7AD63E1F9AEC3621ABBC46AFCC808AD096EADE6E0AC16ED86A8D6F94E94C2E50537531E7EE61EE7506725B6AC3BBE2C1886B8B9B6FECB4464F1778D57F0729924FBED5B7D9E581120E95BC75564B40DF37C57DFD152D7163FD61E12DD86347FD55EB3FB994818E61AF3845FB59D2A1633105606FF861F4809934AC6994B4A09EA57629C816C4F3A7C159BCCEF293534D3EFFFFF4AA9CB87E5E37D7292FE20C15F9A282859C93F0190F9DA409A125D47BCD80E39EE103DDA17498B5EF7EED50A064F2A5A78C8BDB69CDE2855F75752460AE0346E1716274BE3D2A733107927ACE7B3B3CD86AB5F4FB3AA52A3B5ADAE1A603B4C97C04067EA64785C243634382B6C66066F09A58FC4F381FB656E8C423041D338738E52CE9E816BCDFFD7BB2F02F90ACDDB76DF2E3E9861B40520DA20670A341A88CD9D1AA37B17F03672D424A8FB3BF01E2CAEE32F6A9F871AA0CA0BA999F4659FC0A4506FB64C910610F0DBEFFCBCA04AD81A96608ED9BDE070A2BF48982D82BDFE096F8FFAA2824F66B3E5DA04DAC0F985CF571EBDB14B3A99EEC5F861129D62EA28310D0F7F1FC5F09D5BAB601961E38BD9F0151175F71421BBFFCDD19FAFA4047CA27EF6C74C351CDF73F02457E682AE6370C1BC2E3DC9AD8EC0C45D2B011657ABEBDEE68BEA83453CAF5B13D999BB706A44A1D69EA1E43049D1219CBF433A4668E0750ECEC29874A904525DAA518F0247B13AF5571DB7E97F5CECD0E0B082F6EEF736A96ECC30F69B12B94289FF597E643DC5DBF54E1393E9DBF70981867845FA58351B07F1A891FDEFA69CB9CF50F803E7961B9E8F0D89C5F698269B28C32588F5E0229CB75E8135AE3E4A2F59C8F314A1041D629A4FD6CC2D1603AE7B866258FED3740EBC8305203972AF3BB89E64D34248162A36CCB1288AD7380914507C95894842B8A4780659D5A31992E6BDCCDD6D2C60D3A1B0B90A382B7BEC2F4F2E5C1A1A2B03D45E0A0F2B091C37D5869F0E7483C7575A12F551261D6B326E6FB4B59B604234D36BC35050A608D738C31AD5F18EC82364B9C41000F511274443F5A8F02DCF901CC0874C06567296598CA6BD5DAF357F4C5F01A8C555C4DE796315FB9B5C5C43DB2C0E4D4E32A5B26DA45E28EABDF5575B4F16445197C7A9E93C89B4C7DDBA31E117D8ADFE342CE6518B32F9E24F974829B8DAF0F07C1BAE2DB64D390DB5DBBC765D075270198B3F788A2DA30CCAED2D6658108C7593ACFE65B9A98FB9E156C2E6921B7E9A7555DFF69744433EBACA2C02BC8BF3C9DE7DC5BCB04C3504D25F285A70D0B0ED17A0AFFB776ACA2958B8B1009DC4ECDF74159E3C192041CB85ED364381A21881579A4DEBC4C1585C9803B117D6D8C16C984743FBC9A220D3C15014407D716068DC6520096FC4FA734E65EBACB00EFE7A737400CB815EE2BD6948C8186651EDA7D5D5397D27E0F1851CCED80E0D752F9BFF4D7DC3CA1441611BEA3297FB6FAFFEBD18B15D6456A408D5E6217E31F0D375CA6CE5F799DE9C177800EFC622BE9060982D23DC6857B79A1178FC03CD6FC2EC7CB91D8F3277ABA86F5F02AFD1428A6D4B595D0359A28C74EBD4EEEE7DD6C9C9BE9C71420E9D4277EED4F474A21D39C02734581"
flagencode2=flagencode1.decode('hex')
print len(flagencode2)
#print flagencode2
flag=""
for i in range(0, 8):
	flag+=chr(ord(a[i])^ord(flagencode2[i]))
print flag
#In compu

后半部分通过将flagencrypt与密钥流按位异或即可,整题脚本给出

import os,random,sys,string
from hashlib import sha256
import gmpy2
from Crypto.Util.number import *
import base64
mask = 0b1101100000000000000000000000000000000000000000000000000000000000
cipher="72472201E3C0AC877A27C18729749FDA185C1DF902500AEB425C5B6A53574B4A00508546094A90A2F1547780FD401E8C2983A70F22931F0BCC0EBE6EC83B1284BF2023AEBE59B1CBD2D9C395E9C76D42DF65C470C23C92E65F66504F3025B5F660E772096A172CDD"
c=cipher.decode('hex')
#print c
plain="sdgfjkahblskdjxbvfskljdfbguisldfbvghkljsdfbghsjkldhbgjklsdbgvlkjsdgbkljb sdkljfhwelo;sdfghioeurthgbnjl k"
a=""
for i in range(0, 8):
	a+=chr(ord(c[i])^ord(plain[i]))
print a

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 = bytes_to_long(a)
t=""
for i in range(len(a), len(plain)):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    t+=long_to_bytes((tmp^ord(plain[i])))
print 1,t

R = bytes_to_long(a)
tmptext=""
#for i in range(len(a), len(plain)):
for i in range(len(a), 1213):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    tmptext+=chr(tmp)
print 2,tmptext


flagencode1="484D6504E6C6BD9A6C22DC8B613E8698025300F70F4843EB455E4A614158440C114E8B48160688B4F25B6693F04154CF09A19C3F6CD91D149F0BFC7AD63E1F9AEC3621ABBC46AFCC808AD096EADE6E0AC16ED86A8D6F94E94C2E50537531E7EE61EE7506725B6AC3BBE2C1886B8B9B6FECB4464F1778D57F0729924FBED5B7D9E581120E95BC75564B40DF37C57DFD152D7163FD61E12DD86347FD55EB3FB994818E61AF3845FB59D2A1633105606FF861F4809934AC6994B4A09EA57629C816C4F3A7C159BCCEF293534D3EFFFFF4AA9CB87E5E37D7292FE20C15F9A282859C93F0190F9DA409A125D47BCD80E39EE103DDA17498B5EF7EED50A064F2A5A78C8BDB69CDE2855F75752460AE0346E1716274BE3D2A733107927ACE7B3B3CD86AB5F4FB3AA52A3B5ADAE1A603B4C97C04067EA64785C243634382B6C66066F09A58FC4F381FB656E8C423041D338738E52CE9E816BCDFFD7BB2F02F90ACDDB76DF2E3E9861B40520DA20670A341A88CD9D1AA37B17F03672D424A8FB3BF01E2CAEE32F6A9F871AA0CA0BA999F4659FC0A4506FB64C910610F0DBEFFCBCA04AD81A96608ED9BDE070A2BF48982D82BDFE096F8FFAA2824F66B3E5DA04DAC0F985CF571EBDB14B3A99EEC5F861129D62EA28310D0F7F1FC5F09D5BAB601961E38BD9F0151175F71421BBFFCDD19FAFA4047CA27EF6C74C351CDF73F02457E682AE6370C1BC2E3DC9AD8EC0C45D2B011657ABEBDEE68BEA83453CAF5B13D999BB706A44A1D69EA1E43049D1219CBF433A4668E0750ECEC29874A904525DAA518F0247B13AF5571DB7E97F5CECD0E0B082F6EEF736A96ECC30F69B12B94289FF597E643DC5DBF54E1393E9DBF70981867845FA58351B07F1A891FDEFA69CB9CF50F803E7961B9E8F0D89C5F698269B28C32588F5E0229CB75E8135AE3E4A2F59C8F314A1041D629A4FD6CC2D1603AE7B866258FED3740EBC8305203972AF3BB89E64D34248162A36CCB1288AD7380914507C95894842B8A4780659D5A31992E6BDCCDD6D2C60D3A1B0B90A382B7BEC2F4F2E5C1A1A2B03D45E0A0F2B091C37D5869F0E7483C7575A12F551261D6B326E6FB4B59B604234D36BC35050A608D738C31AD5F18EC82364B9C41000F511274443F5A8F02DCF901CC0874C06567296598CA6BD5DAF357F4C5F01A8C555C4DE796315FB9B5C5C43DB2C0E4D4E32A5B26DA45E28EABDF5575B4F16445197C7A9E93C89B4C7DDBA31E117D8ADFE342CE6518B32F9E24F974829B8DAF0F07C1BAE2DB64D390DB5DBBC765D075270198B3F788A2DA30CCAED2D6658108C7593ACFE65B9A98FB9E156C2E6921B7E9A7555DFF69744433EBACA2C02BC8BF3C9DE7DC5BCB04C3504D25F285A70D0B0ED17A0AFFB776ACA2958B8B1009DC4ECDF74159E3C192041CB85ED364381A21881579A4DEBC4C1585C9803B117D6D8C16C984743FBC9A220D3C15014407D716068DC6520096FC4FA734E65EBACB00EFE7A737400CB815EE2BD6948C8186651EDA7D5D5397D27E0F1851CCED80E0D752F9BFF4D7DC3CA1441611BEA3297FB6FAFFEBD18B15D6456A408D5E6217E31F0D375CA6CE5F799DE9C177800EFC622BE9060982D23DC6857B79A1178FC03CD6FC2EC7CB91D8F3277ABA86F5F02AFD1428A6D4B595D0359A28C74EBD4EEEE7DD6C9C9BE9C71420E9D4277EED4F474A21D39C02734581"
flagencode2=flagencode1.decode('hex')
print len(flagencode2)
#print flagencode2
flag=""
for i in range(0, 8):
	flag+=chr(ord(a[i])^ord(flagencode2[i]))
print flag
#In compu

for i in range(len(a), 1213):
    flag+=long_to_bytes(ord(tmptext[i-len(a)])^ord(flagencode2[i]))
print 3,flag
#3 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}




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值