[CISCN 2018]sm

目录

1.题目

3.解题

4.参考


1.题目

题目链接

from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long
from Crypto.Cipher import AES
import hashlib
from random import randint
def gen512num():order=[]while len(order)!=512:tmp=randint(1,512)if tmp not in order:order.append(tmp)ps=[]for i in range(512):p=getPrime(512-order[i]+10)pre=bin(p)[2:][0:(512-order[i])]+"1"ps.append(int(pre+"0"*(512-len(pre)),2))return psdef run():choose=getPrime(512)ps=gen512num()print "gen over"bchoose=bin(choose)[2:]r=0bchoose = "0"*(512-len(bchoose))+bchoosefor i in range(512):if bchoose[i]=='1':r=r^ps[i]flag=open("flag","r").read()key=long_to_bytes(int(hashlib.md5(long_to_bytes(choose)).hexdigest(),16))aes_obj = AES.new(key, AES.MODE_ECB)ef=aes_obj.encrypt(flag).encode("base64")open("r", "w").write(str(r))open("ef","w").write(ef)gg=""for p in ps:gg+=str(p)+"\n"open("ps","w").write(gg)run()

附件:ef、ps、r

2.分析

from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long
from Crypto.Cipher import AES
import hashlib
from random import randint
def gen512num():order=[]while len(order)!=512:tmp=randint(1,512)if tmp not in order:order.append(tmp)#产生1~512的序列ps=[]for i in range(512):p=getPrime(512-order[i]+10)#根据order获得一个对应的素数pre=bin(p)[2:][0:(512-order[i])]+"1"#取素数的前512-order[i]位,加1之后就能够明确保证每一位的最后一个1的位置ps.append(int(pre+"0"*(512-len(pre)),2))#剩余位置(512-)补0#加到集合中去return psdef run():choose=getPrime(512)#获取一个512位的随机素数来作为chooseps=gen512num()#得到对应的序列了print "gen over"#完成准备bchoose=bin(choose)[2:]#获取2进制版本数r=0bchoose = "0"*(512-len(bchoose))+bchoose#bchoose前面完全补充0,共512位for i in range(512):if bchoose[i]=='1':r=r^ps[i]#根据choose来确定r是否与ps[i]异或flag=open("flag","r").read()#读取flag信息key=long_to_bytes(int(hashlib.md5(long_to_bytes(choose)).hexdigest(),16))#choose,哪个随机素数被转化为bytes后又被转化为MD5,又被按照16进制转化为了整数,然后又转化为了bytesaes_obj = AES.new(key, AES.MODE_ECB)#获取aes加密对象ef=aes_obj.encrypt(flag).encode("base64")#ef里储存flagopen("r", "w").write(str(r))open("ef","w").write(ef)#输出efgg=""for p in ps:gg+=str(p)+"\n"open("ps","w").write(gg)#ps是被完全输出
run()

题目把ps全部给了,r是最终异或的结果,那么我们的问题就是根据r和ps把choose求出,然后利用内置的AES加密方式进行解密即可,解密方法有两种,一种是根据代码寻找突破口进行解密,一种是使用sage进行矩阵解密

3.解题

第一种:

我们注意gen512num函数:

order=[]while len(order)!=512:tmp=randint(1,512)if tmp not in order:order.append(tmp)#产生1~512的序列ps=[]for i in range(512):p=getPrime(512-order[i]+10)#根据order获得一个对应的素数pre=bin(p)[2:][0:(512-order[i])]+"1"#取素数的前512-order[i]位,加1之后就能够明确保证每一位的最后一个1的位置ps.append(int(pre+"0"*(512-len(pre)),2))#剩余位置(512-)补0#加到集合中去return ps

所以得到的ps必然是一个末尾0的个数分别是0~511的数组,说明ps中每一个数的最后一个1的位置都不一样

还原choose:

上面这个特性可以帮助顺利我们反推choose,举例来说,假如最后一个值1为1,则它必定是来自最后一个1的位置相同的那个数,我们将目前的数异或上对应的ps数,就能够消除这个数对前面的数的影响了,然后就能够让对choose的求解推进一位

求解代码如下:

f = open("...", 'r')
ps = f.readlines()
psn = []
pos = []
for i in ps:psn.append(int(i))t1 = int(i)t2 = 0while(t1 % 2 == 0):t1 >>= 1t2 += 1pos.append(512 - t2)
r = 6753785483255906709117615805253027649453460653974415214642466102672301763943358839905575042938258141827000621474498066533397472809407687579125519939754658
m = list('0' * 512)
for i in range(511, -1, -1):if ((r >> (511 - i)) % 2 == 1):r ^= psn[pos.index(i + 1)]#找到对应的那个进行异或的位置m[pos.index(i + 1)] = '1'#置为1
choose = int(''.join(m), 2)

然后进行AES求解:

from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long
from Crypto.Cipher import AES
import hashlib
from random import randint
import base64key=long_to_bytes(int(hashlib.md5(long_to_bytes(choose)).hexdigest(),16))f2 = open("...", 'r')
c = f2.read()
c = base64.b64decode(c)
aes = AES.new(key, AES.MODE_ECB)
flag = aes.decrypt(c)
print(flag)#b'flag{shemir_alotof_in_wctf_fun!}'

第二种,使用sage进行求解:

原问题可以看作:

A\cdot B = C

A代表choose,B代表ps中的512个数,C是代表最终给出的r,即异或结果

sage中模2意义的加能够满足异或运算的要求,自己动动笔应该能发现

故我们可以使用以下的方程来求解:

A=C\cdot B^{-1}

这个问题在sage中是十分易求的

代码如下:

#please run in sagemathfrom Crypto.Util.number import *
from Crypto.Cipher import AES
import hashlib
import base64ps = open("...",'r').readlines()
c = []
for i in ps:c.append(int(i.strip()))
A=[]
for i in c:A.append([int(x) for x in bin(i)[2:].zfill(512)])
r = 6753785483255906709117615805253027649453460653974415214642466102672301763943358839905575042938258141827000621474498066533397472809407687579125519939754658
B = [int(x) for x in bin(r)[2:].zfill(512)]
A = matrix(GF(2),A)
B = matrix(GF(2),B)
key = B*A.inverse()
li = []
for i in key[0]:li.append(bin(i)[2:])
choose = int(''.join(li), 2)
k=long_to_bytes(int(hashlib.md5(long_to_bytes(choose)).hexdigest(),16))
aes=AES.new(k,AES.MODE_ECB)
flag_enc='5eFo3ANg2fu9LRrFktWCJmVvx6RgBFzd0R8GXQ8JD78='flag_enc=base64.b64decode(flag_enc)
flag=aes.decrypt(flag_enc)
print(flag)

4.参考

文章1

文章2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/10030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【送书福利第六期】Java开发的150多个坑,你踩过几个?(文末送书)

文章目录 做Java开发别掉坑里还不知道 程序员为什么会掉到坑里却不自知?第一是意识不到坑的存在。第二是有些 bug 或问题只在特定情况下暴露。第三是变化不明显的性能问题。 《Java开发坑点解析:从根因分析到最佳实践》Java 开发完美避坑指南结语 &#…

2010-2022年ESA_ CCI-LC数据集下载

扫描文末二维码,关注微信公众号:ThsPool 后台回复 g009,领取 2010-2022年300m分辨率 ESA_ CCI-LC 数据集 哥白尼气候数据集:土地利用和土地覆盖研究的宝贵资源 🌍🔍 土地利用和土地覆盖变化是全球变化研究…

纯血鸿蒙APP实战开发——自定义安全键盘案例

介绍 金融类应用在密码输入时,一般会使用自定义安全键盘。本示例介绍如何使用TextInput组件实现自定义安全键盘场景,主要包括TextInput.customKeyboard绑定自定义键盘、自定义键盘布局和状态更新等知识点。 效果图预览 实现思路 1. 使用TextInput的cu…

docker安装nginx支持ssl 实现https访问(完整版)

全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.1 本文简介 2. docker安装nginx支持ssl2.0 准备ssl证书(例: 阿里云)2.0.1 配置域名解析2.0.2 找到数字证书管理服务并签发ssl证书2.0.3 选择默认证书 填写域名 创建2.0.4 提交审核, 签发成功2.0.5 解压并上传到宿主机ssl路径下 …

异常处理/__LINE__ 与 __FILE__ 宏在调试和异常处理中的高级使用

文章目录 概述痛点分析_LINE_ 代码所在行号_LINE_ 直接转为字符串_LINE_ 作为整型数据使用_LINE_标记宏函数的调用位置 _FILE_ 代码所在文件名简单实验不期望 _FILE_ 宏代表全路径 assert 使用了 _FILE_ 和 _LINE_借助TLS技术小结 概述 _LINE_和_FILE_是C/C中的预定义宏&#…

HarmonyOS开发案例:【生活健康app之编写通用工具类】(5)

本节将介绍日志打印、时间换算等通用工具类的编写和使用,工具类可以简化应用代码编写和业务流程处理。 日志类 日志类Logger旨在提供一个全局的日志打印、日志管理的地方,既可以规范整个应用的日志打印,也方便日后对日志工具类进行修改&…

P1434 滑雪(java)

题目描述: Michael 喜欢滑雪。这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域由一个二维数组给…

利用106短信群发平台能否提升沟通效率?

利用106短信群发平台确实能够显著提升沟通效率,具体体现在以下几个方面: 1.快速传递信息:106短信群发平台能够实现信息的快速传递。一旦设置好发送内容和接收群体,短信便能在瞬间发送至大量用户。这种即时性确保了信息的迅速传达…

医院预约挂号系统微信小程序APP

医院预约挂号小程序,前端后台(后台 java spring boot mysql) 医院预约挂号系统具体功能介绍:展示医院信息、可以注册和登录, 预约挂号(包含各个科室的预约,可以预约每个各个医生)&…

java-spring 09 下.populateBean (方法成员变量的注入@Autowird,@Resource)

01.在populateBean 方法中的:用于Autowird,Resource注入 // 后处理器已经初始化boolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();// 需要依赖检查boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinition.DEP…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-15.4讲 GPIO中断实验-IRQ中断服务函数详解

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

代码随想录算法训练营Day35 | 435. 无重叠区间、763.划分字母区间、56. 合并区间 | Python | 个人记录向

本文目录 435. 无重叠区间做题基于左边界的贪心算法基于左边界,把452.用最少数量的箭引爆气球代码稍做修改 763.划分字母区间做题看文章 56. 合并区间做题看文章 以往忽略的知识点小结个人体会 435. 无重叠区间 代码随想录:435. 无重叠区间 Leetcode&am…

三生随记——耳机里的诅咒

深夜,城市的灯火已经渐渐熄灭,只剩下一轮明月孤独地悬挂在天空中,洒下银白色的光芒。在这样一个寂静的夜晚,李浩独自一人坐在昏暗的房间里,耳机紧紧贴在耳边,他正在观看一部知名的恐怖电影。 电影里的恐怖情…

java对象互换工具类

1:将Object类型转成json字符串 /*** 将对象转为字符串* param obj* return*/public static String toString(Object obj) {if(obj null) {return null;}if ("".equals(obj.toString())) {return null;}if (obj instanceof String) {return obj.toString();}try {Ob…

Spring Cloud Gateway 11种断言工厂

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Spring Cloud Gateway路由匹配是Spring WebFlux基础功能的一部分,在Spri…

js将html网页转换成PDF并解决了图表文字被切割的问题

给页面内所有要转换成PDF的HTML元素添加一个class“toPDF” 输出的时候, 遍历所有class"toPDF"的HTML元素 将它们逐个加入到pdf文档中,添加的时候如果超出的则添加一页 一、安装 npm install --save html2canvas npm i jspdf --save二、html…

ruoyi-vue-pro 使用记录(2)

ruoyi-vue-pro 使用记录(2) 数据库商城商品模块数据表营销数据库交易数据库统计数据库 数据库 商城 参考官方文档 ruoyi-vue-pro yudao 项目商城 mall 模块启用及相关SQL脚本 商品模块(中心)以 product_ 作为前缀的表交易模块…

Acwing2024蓝桥杯并查集

并查集模板 int n,dad[N],sizee[N];//sizee数组规定只有祖宗结点是有效值 //初始化所有集合 void Init(){for(int i1;i<n;i){dad[i]i;sizee[i]1;}return ; } //查找a的祖宗节点 int Find(int a){if(dad[a]!a) dad[a]Find(dad[a]);//每个集合中只有祖宗节点的值等于自身的值…

你认识edge吗,edge是做什么的

简介 Microsoft Edge&#xff08;研发代号为Project Spartan&#xff0c;又译作微软边缘浏览器&#xff0c;Edge浏览器&#xff09;是一个由微软研发的基于Chromium开源项目及其他开源软件的网页浏览器&#xff0c;于2015年1月21日公布&#xff0c;2015年3月30日公开发布第一个…

pyqt曲线轨迹运动

pyqt曲线轨迹运动 pyqt QPropertyAnimation介绍曲线轨迹运动代码 pyqt QPropertyAnimation介绍 QPropertyAnimation 是 PyQt中的一个类&#xff0c;它用于对 Qt 对象的属性进行动画处理。通过使用 QPropertyAnimation&#xff0c;你可以平滑地改变一个对象的属性值&#xff0c…