CTF中的LFSR考点(一)

前提概要:
这是我在理解了作者:道路结冰的博客深入分析CTF中的LFSR类题目(一)下写的一次回顾和分析,只是在其中加上自己的见识和理解来加深印象。

博客地址:https://www.anquanke.com/post/id/181811#h2-0

.
.
前言:

LFSR(线性反馈移位寄存器)已经成为如今CTF中密码学方向题目的一个常见考点了,在今年上半年的一些国内赛和国际赛上,也出现了非常多的这类题目,但是其中绝大多数题目目前都没有writeups(或者writeups并没有做cryptanalysis,而是通过爆破的方法解决,这种思路只适用于部分类似去年强网杯出现的几道非常基础的LFSR类题目有效,对于绝大多数国际赛上的题目不仅是没有任何效果的,也是没有任何意义的,只有真正掌握了LFSR的密码学原理,才有可能在国际赛上解决一道高分值的LFSR类题目),网上针对这类考点的详细分析也不多,因此接下来我将通过几篇文章,对这类知识点进行一个详细的分析。
.
.
.

LFSR简介:

LFSR是属于FSR(反馈移位寄存器)的一种,除了LFSR之外,还包括NFSR(非线性反馈移位寄存器)。

附加:
反馈移位就是可以通过前面已经存在的寄存器中的值反馈出后面的的寄存器的值,通过不断移位对应不同的前寄存器值一直反馈出后面连续的后寄存器值。

FSR是流密码产生密钥流的一个重要组成部分,在GF(2)上的一个n级FSR通常由n二元存储器和一个反馈函数组成,如下图所示:

.

如果这里的反馈函数是线性的,我们则将其称为LFSR,此时该反馈函数可以表示为:

其中cn=0或1,⊕表示异或(模二加),也就是说反馈函数必然为a1……⊕……an形式中的一部分。

我们接下来通过一个例子来更直观的明确LFSR的概念,假设给定一个5级的LFSR,其初始状态(即a1到a5这5个二元存储器的值)为:

其反馈函数为:

整个过程可以表示为下图所示的形式:

接下来我们来计算该LFSR的输出序列,输出序列的前5位即为我们的初始状态10011,第6位的计算过程如下:

第7位的计算过程如下:

由此类推,可以得到前31位的计算结果如下:
1001101001000010101110110001111

对于一个n级的LFSR来讲,其最大周期为2^n-1 ,因此对于我们上面的5级LFSR来讲,其最大周期为 2^5-1=31,再后面的输出序列即为前31位的循环

注意
这里的就是能通过反馈函数生成完整连续序列最少寄存器数,因为a6=a1⊕a4,所以a5必须包含在内,所以是5级寄存器。

通过上面的例子我们可以看到,对于一个LFSR来讲,我们目前主要关心三个部分:初始状态反馈函数输出序列

那么对于CTF中考察LFSR的题目来讲也是如此,大多数情况下,我们在CTF中的考察方式都可以概括为:给出反馈函数输出序列,要求我们反推出初始状态,初始状态即为我们需要提交的flag,另外大多数情况下,初始状态的长度我们也是已知的。

显然,这个反推并不是一个容易的过程,尤其当反馈函数十分复杂的时候,接下来我们就通过一些比赛当中出现过的具体的CTF题目,来看一下在比赛当中我们应该如何解决这类问题,由于不同题目之间难度差异会很大,所以我们先从最简单的题目开始,我将尽可能的用最通俗的语言和脚本来进行演示,在后面会逐渐提升题目的难度,同时补充相应的代数知识。

.
.

CTF例题演示

2018 CISCN 线上赛 oldstreamgame
题目给出的脚本如下:

flag = "flag{xxxxxxxxxxxxxxxx}"
assert flag.startswith("flag{")
assert flag.endswith("}")
assert len(flag)==14def lfsr(R,mask):output = (R << 1) & 0xffffffffi=(R&mask)&0xfffffffflastbit=0while i!=0:lastbit^=(i&1)i=i>>1output^=lastbit return (output,lastbit)R=int(flag[5:-1],16)
mask = 0b10100100000010000000100010010100f=open("key","w")
for i in range(100):tmp=0for j in range(8):(R,out)=lfsr(R,mask)tmp=(tmp << 1)^outf.write(chr(tmp))
f.close()

.
.
分析一下我们的已知条件(1):

已知初始状态的长度为4个十六进制数,即32位,初始状态的值即我们要去求的flag,所以初步判断这里的是32,那么最大周期就是2^32-1
已知反馈函数lfsr,只不过这里的反馈函数是代码的形式,我们需要提取出它的数学表达式。 已知输出序列。

.
.
那么我们的任务很明确,就是通过分析lfsr函数,整理成数学表达式的形式求解即可,接下来我们一行一行的来分析这个函数:

.
.
通过上面的分析,我们可以看出在这道题的情境下,lfsr函数本质上就是一个输入R输出lastbit的函数,虽然我们现在已经清楚了R是如何经过一系列运算得到lastbit的,但是我们前面的反馈函数都是数学表达式的形式,我们能否将上述过程整理成一个表达式的形式呢?这就需要我们再进一步进行分析:

mask只有第3、5、8、12、20、27、30、32这几位为1,其余位均为0。
mask与R做按位与运算得到i,当且仅当R的第3、5、8、12、20、27、30、32这几位中也出现1时,i中才可能出现1,否则i中将全为0。
lastbit是由i的最低位向i的最高位依次做异或运算得到的,在这个过程中,所有为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这几位依次异或的结果。

.
.
将其写成数学表示式的形式,即为我们要求的反馈函数,反馈函数的形式也说明了初始位数要32位

.
.
.
然后我们看一下明文是怎么来的:

key=20FDEEF8A4C9F4083F331DA8238AE5ED083DF0CB0E7A83355696345DF44D7C186C1F459BCE135F1DB6C76775D5DCBAB7A783E48A203C19CA25C22F60AE62B37DE8E40578E3A7787EB429730D95C9E1944288EB3E2E747D8216A4785507A137B413CD690C

最后八行代码,对flag,它做了一百次循环,每次循环都产生一个结果,并将这个结果写到key里面去,所以key里面总共有一百个ASCII字符,共两百个16进制数。
.
补充:
题目之所以会出现 100 个ASCII字符是因为 4 循环次加内嵌的 8 位一次共 32 位循环往后产生的 4 个flag生成的加密字符共 8 个 16 进制数后,继续用这 4 个加密后的 flag 字符继续新一轮加密,就是多层加密。所以我们取 32 位即可,结果 flag 也是 4 个ASCII字符拆分出的 8 个 16 进制数。
.

.
.
.
显然,lastbitR之间满足线性关系,那么接下来我们就可以开始求解了。
而且从这里我们可以知道,这种移位的CTF题目类型要反推32位的初始值要多少位输出序列呢,答案就是32位,因为这种移位的题目是32位为一个循环,这就和我们前面说的2^32-1的循环不太同了,因为这里是移位操作。

32位Key值:00100000111111011110111011111000

解题的关键是发现在明文只剩最后一位时,可以通过最后的结果来求出排在第32位的第一位,然后就可以反推回去了。
.
我们想象这样一个场景,当即将输出第32位lastbit时,此时R已经左移了31位,根据上面的数学表达式,我们有:

.
这样我们就可以求出R的第1位,同样的方法,我们可以求出R的第2位:

以此类推,R的全部32位我们都可以依次求出了

.
.
.
最终脚本,这里注意小端顺序反序取位:

key1="00100000111111011110111011111000"   #lastbit全部值,就是反馈函数生成的值,32位的key1
key2=key1
flag=[]
for i in range(32):output='?'+key1[:31] #?0100000111111011110111011111000,因为后面有key1=str(lastbit)+key1[:31],key1不断填补,output不断取前31位,所以这里output每次把?定在第i位上,注意output和key1是独立的分开的。flag.append(str(int(key2[-1-i])^int(output[-3])^int(output[-5])^int(output[-8])^int(output[-12])^int(output[-20])^int(output[-27])^int(output[-30])))
#这里之所以取负数是因为我们截取是从左往右取,而在计算机中是小端顺序,应该从右往左取才对,这里的key2[-1-i]就是小端左到右的第i位,也就是前面分析的反馈函数生成值的第i位。flag值的原第i位,现在在第32位,可以通过⊕的可逆性来求,就是R32=lastbit ⊕ R3 ⊕ R5 ⊕ R8 ⊕ R12 ⊕ R20 ⊕ R27 ⊕ R30                                    key1=str(flag[i])+key1[:31]#不断填补key1,让key1向右推进,
print("flag{"+hex(int(''.join(flag[::-1]),2)).replace('0x','')+"}")#这里是经过一系列操作,首先把flag变成小端顺序的[::-1],然后就是转十六进制。

.
.
结果:

CTF中的LFSR考点(一)相关推荐

  1. python 字节流分段_一文掌握CTF中Python全部考点

    声明:Tide安全团队原创文章,转载请声明出处!文中所涉及的技术.思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担! 前 言 一次偶然的机会,让自己 ...

  2. CTF中php相关考点

    以前在做CTF题的时候总是会遇到一些用php的trick才能过的题,知识点还是很杂的,主要是php这种动态弱类型语言实在是太灵活,各种奇葩写法也多,把之前的知识总结下. 学长的博客有对php黑魔法进行 ...

  3. CTF中智能合约部署交互基础

    0x01 前言 Solidity在以太坊中是编写智能合约最受欢迎的语言,一般的CTF竞赛中的智能合约方向的题目都是以solidity语言编写的智能合约. 为什么写这一篇文章,主要是因为在接触智能合约类 ...

  4. Docker配置CTF中的靶机环境

    0x01 前言 之所以整理一篇Docker搭建CTF中的靶机文章,主要是因为最近断断续续遇到需要自己搭建一个服务器端镜像的事,出题或者是部署一些服务,出于安全或者是可移植性的一些考虑,都是需要用到Do ...

  5. 见微知著(一):解析ctf中的pwn--Fast bin里的UAF

    在网上关于ctf pwn的入门资料和writeup还是不少的,但是一些过渡的相关知识就比较少了,大部分赛棍都是在不断刷题中总结和进阶的.所以我觉得可以把学习过程中的遇到的一些问题和技巧总结成文,供大家 ...

  6. php字符长度函数漏洞 ctf,CTF中常见php-MD5()函数漏洞

    CTF中常见php-MD5()函数漏洞 1.数字与字符串之间的比较 var_dump( 0 == "a" ); var_dump( "0" == "a ...

  7. ctf php沙箱,详谈CTF中常出现的PHP反序列化漏洞

    0x01什么是PHP序列化与反序列化 PHP序列化是一种把变量或对象以字符串形式转化以方便储存和传输的方法 在PHP中,序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构. 比方来说, ...

  8. python判断素数的方法简书_深入浅出RSA在CTF中的攻击套路

    0x01 前言 本文对RSA中常用的模逆运算.欧几里得.拓展欧几里得.中国剩余定理等算法不展开作详细介绍,仅对遇到的CTF题的攻击方式,以及使用到的这些算法的python实现进行介绍.目的是让大家能轻 ...

  9. CTF中编码与加解密总结

    CTF中那些脑洞大开的编码和加密 转自:https://www.cnblogs.com/mq0036/p/6544055.html 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到 ...

最新文章

  1. 设计模式之状态模块加观察者模式
  2. 前端使用 Nginx 反向代理彻底解决跨域问题
  3. TCP/IP模型的各层的作用
  4. C 迭代器iterator的实现原理
  5. springboot项目中jdk版本的问题
  6. 备忘:SharePoint默认的欢迎WebPart中超链接样式
  7. 雅虎被告存在重大疏忽 导致5亿账户信息被黑
  8. python批量制作ppt_实例25_批量生成PPT版荣誉证书
  9. NOPI修改xlsx文件内容,无法正常打开,提示文件格式或文件扩展名无效
  10. 从autotool迁移到cmake
  11. led同步回显到计算机屏幕,手把手教您如何将笔记本电脑的画面投屏到LED大屏幕上显示,音视频同步传输...
  12. MATLAB提取RGB三原色及识别形状(圆、三角、方)
  13. Laravel多表连接,多个查询(Eloquent)
  14. 齐兴皓 团队项目(任务五):项目回顾
  15. 分布式任务调度系统-定时任务的解决方案
  16. geek_询问How-To Geek:如何监视带宽使用情况?
  17. tools:callgraph
  18. 外贸公司如何写开发信
  19. [Happy Coding] 加速Windows GUI debug版本的编译
  20. LTE RX调试指南(CMW500)

热门文章

  1. c语言贪吃蛇添加排行榜,c语言贪吃蛇排行榜_...12年4月编程语言排行榜 C语言荣归宝座...
  2. Android应用程序开发以及背后的设计思想深度剖析(4)
  3. 在线涂改图片 php,php网站怎么修改图片
  4. 打开VMware虚拟机报错VMware Workstation 与 Device/Credential Guard 不兼容
  5. Android移动应用开发基础知识整理
  6. 学习笔记(01):基于qt和ffmpeg视频播放器开发实战-avformat_open_input函数详解
  7. 显示倒计时的Dialog
  8. [安装系统] UlTraISO U盘系统镜像刻录
  9. Linux网络编程:用C语言实现的聊天程序(同步通信)
  10. C++中的map问题+unordered_map问题