XCTF分站赛ACTF——Crypto
impossible RSA:
没啥好说的,跟我之前文章有道题类似,虽然如此还是花费了很长时间,原因令人落泪,把q = inverse(e,p)的数学式写成了eq mod p导致数学式推导及其困难(能推但无用)
解题脚本:
#coding:utf-8
from Crypto.Util.number import *
import math
n = 15987576139341888788648863000534417640300610310400667285095951525208145689364599119023071414036901060746667790322978452082156680245315967027826237720608915093109552001033660867808508307569531484090109429319369422352192782126107818889717133951923616077943884651989622345435505428708807799081267551724239052569147921746342232280621533501263115148844736900422712305937266228809533549134349607212400851092005281865296850991469375578815615235030857047620950536534729591359236290249610371406300791107442098796128895918697534590865459421439398361818591924211607651747970679849262467894774012617335352887745475509155575074809
e = 65537
c = 8273086882440893360458062957389163084656045191542493618199369528956277216626884353986044368396198156428766254991928690583227149075264217246716715502497271453823598984519037301602775476502736840821942623288225980044817912940317041496675271105285924648202112216540495276381694590948153181922044287087121526235593090625653756288948499134042427779455887781328892794911088854654421379942237290840799205667104402295294924690771201447934282318850564703279100891083617354084345663030868007048086929831020873706613566948846194280096109248694845560054847526215721665897469865078997234299897107511688667705001432037926136840958 import gmpy2
for k in range(1, 100000000):
L = gmpy2.iroot(1 + 4 * k * n * e, 2)
if L[1]:
p = (-1 + L[0]) // (2 * k)
q = (p * k + 1) // e
print(p)
print(q)
print(k)
break k = 46280
p = 150465840847587996081934790667651610347742504431401795762471467800785876172317705268993152743689967775266712089661128372295606682852482012493939368044600366794969553828079064622047080051569090177885299781981209120854290564064662058027679075401901717932024549311396484660557278975525859127898004619405319768113
q = 106253858346069738600667441477316882476975191191010804704017265511396163224664897689076447029585908855140507431062102645373463498213419404889139172575859514095414665779078979976323891310048026205540865067215318951327289428947198682355325809994354509756230772573224732747769822710641878029801786071777441733193
phi = (p - 1) * (q - 1)
# print(phi)
print(gmpy2.gcd(e, phi))
#ed mod phi 余 1
d = gmpy2.invert(e, phi)
print(d)
m = pow(c, d, n)
# m = m
print(long_to_bytes(m))
flag:ACTF{F1nD1nG_5pEcia1_n_i5_nOt_eA5y}
RSA leak:
题目如下:
from sage.all import *
from secret import flag
from Crypto.Util.number import bytes_to_long def leak(a, b):
p = random_prime(pow(2, 64))
q = random_prime(pow(2, 64))
n = p*q
e = 65537
print(n)
print((pow(a, e) + pow(b, e) + 0xdeadbeef) % n) def gen_key():
a = randrange(0, pow(2,256))
b = randrange(0, pow(2,256))
p = pow(a, 4)
q = pow(b, 4)
rp = randrange(0, pow(2,24))
rq = randrange(0, pow(2,24))
pp = next_prime(p+rp)
qq = next_prime(q+rq)
if pp % pow(2, 4) == (pp-p) % pow(2, 4) and qq % pow(2, 4) == (qq-q) % pow(2, 4):
n = pp*qq
rp = pp-p
rq = qq-q
return n, rp, rq n, rp, rq = gen_key()
e = 65537
c = pow(bytes_to_long(flag), e, n)
print("n =", n)
print("e =", e)
print("c =", c)
print("=======leak=======")
leak(rp, rq) '''
n = 3183573836769699313763043722513486503160533089470716348487649113450828830224151824106050562868640291712433283679799855890306945562430572137128269318944453041825476154913676849658599642113896525291798525533722805116041675462675732995881671359593602584751304602244415149859346875340361740775463623467503186824385780851920136368593725535779854726168687179051303851797111239451264183276544616736820298054063232641359775128753071340474714720534858295660426278356630743758247422916519687362426114443660989774519751234591819547129288719863041972824405872212208118093577184659446552017086531002340663509215501866212294702743
e = 65537
c = 48433948078708266558408900822131846839473472350405274958254566291017137879542806238459456400958349315245447486509633749276746053786868315163583443030289607980449076267295483248068122553237802668045588106193692102901936355277693449867608379899254200590252441986645643511838233803828204450622023993363140246583650322952060860867801081687288233255776380790653361695125971596448862744165007007840033270102756536056501059098523990991260352123691349393725158028931174218091973919457078350257978338294099849690514328273829474324145569140386584429042884336459789499705672633475010234403132893629856284982320249119974872840
=======leak=======
122146249659110799196678177080657779971
90846368443479079691227824315092288065
'''
解题思路:
这题我在比赛时也没算出来,在公式的推导过程中就走了弯路导致在有限的时间,有限的算力里面是无法解出答案的。废话不多说,来复盘整理一下思路。
审计代码可以得到如下:
(ae + be + A) mod n1 ≡ B (A,B都是已知的常数,k为未知数,n1为函数里的n,为了与外面n区分写为n1)
p = a4 同理可以得q
pp = rp + p 同理可以得qq
pp mod 16 = pp - p mod 16 同理可以得qq-q
根据同余性质可以得到如下:
(ae + be ) ≡ (B-A) mod n1
ae ≡ (B-A-be ) mod n1
因为leak函数里面又是一个rsa,所以可以求rq和rp,脚本如下:
def get_rq_or_rp():
#对leak_x分解得到p1,q1
p = 8949458376079230661
q = 13648451618657980711
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
for rp in range(10000, pow(2, 24)):
rq_e = leak_c - 0xdeadbeef #(a^e + b^e)
rq_e = (rq_e - pow(rp, e, leak_n)) % leak_n
rq = pow(rq_e, d, leak_n)
if len(bin(rq)[2:]) <= 24:
print(rp)
print(rq)
return rp, rq
因为 pp mod 16 = pp-p mod 16,可以推出p+k = pp,因为k远小于p,所以可以近似看成p=pp
则n = pp * qq = p * q
可以推出 pq = (ab)4 从而得到ab,然后得出pq
把 pp = rp + p 以及 qq = rq + q 代入n可以得到如下:
n = (ab)4 + a4 * rq + b4 * rp + rp * rq
可以推出 n - rp * rq - (ab)4 = p * rq + q * rp = M
算出M后,两边同乘q,得到如下式子:
rp * q2 - M * q + pq * rq = 0
解得q,然后q + rq = qq 同理得 pp
完整脚本如下:
#coding:utf-8
from Crypto.Util.number import *
import gmpy2
leak_n = 122146249659110799196678177080657779971
leak_c = 90846368443479079691227824315092288065
n = 3183573836769699313763043722513486503160533089470716348487649113450828830224151824106050562868640291712433283679799855890306945562430572137128269318944453041825476154913676849658599642113896525291798525533722805116041675462675732995881671359593602584751304602244415149859346875340361740775463623467503186824385780851920136368593725535779854726168687179051303851797111239451264183276544616736820298054063232641359775128753071340474714720534858295660426278356630743758247422916519687362426114443660989774519751234591819547129288719863041972824405872212208118093577184659446552017086531002340663509215501866212294702743
e = 65537
c = 48433948078708266558408900822131846839473472350405274958254566291017137879542806238459456400958349315245447486509633749276746053786868315163583443030289607980449076267295483248068122553237802668045588106193692102901936355277693449867608379899254200590252441986645643511838233803828204450622023993363140246583650322952060860867801081687288233255776380790653361695125971596448862744165007007840033270102756536056501059098523990991260352123691349393725158028931174218091973919457078350257978338294099849690514328273829474324145569140386584429042884336459789499705672633475010234403132893629856284982320249119974872840 def get_rq_or_rp():
#对leak_x分解得到p1,q1
p = 8949458376079230661
q = 13648451618657980711
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
for rp in range(10000, pow(2, 24)):
rq_e = leak_c - 0xdeadbeef #(a^e + b^e)
rq_e = (rq_e - pow(rp, e, leak_n)) % leak_n
rq = pow(rq_e, d, leak_n)
if len(bin(rq)[2:]) <= 24:
return rp, rq def get_flag(rp, rq):
#n = pp * qq 因为pp = p + k 又因为k<16所以pp约等于p,同理得q
pq_ab4 = (gmpy2.iroot(n, 4)[0])**4
L = n - rp * rq - pq_ab4 #判别式
M = gmpy2.iroot(L ** 2 - 4 * rp * rq * pq_ab4, 2)
if M[1]:
q1 = (L + M[0]) // (2 * rp)
q2 = (L - M[0]) // (2 * rp)
qq1 = q1 + rq
qq2 = q2 + rq
pp1 = n // qq1
pp2 = n // qq2
if pp1 * qq1 == n:
phi = (pp1 - 1) * (qq1 - 1)
d = gmpy2.invert(e, phi)
m = gmpy2.powmod(c, d, n)
print(long_to_bytes(m))
else:
phi = (pp2 - 1) * (qq2 - 1)
d = gmpy2.invert(e, phi)
m = gmpy2.powmod(c, d, n)
print(long_to_bytes(m)) if __name__ == '__main__':
rp, rq = get_rq_or_rp()
if rp and rq:
get_flag(rp, rq)
flag:ACTF{lsb_attack_in_RSA|a32d7f}
推导过程用到的性质:
同余式相加:若a≡b(mod m),c≡d(mod m),则a ± c≡b ± d(mod m);
不好理解可以如下例子:
17 mod 13 ≡ 4 即 (15 + 2) mod 13 ≡ 4 推出 15 mod 13 ≡ 2
同余其它性质:
传递性:若a≡b(mod m),b≡c(mod m),则a≡c(mod m);
对称性:若a≡b(mod m),则b≡a (mod m);
反身性:a≡a (mod m);
同余式相乘:若a≡b(mod m),c≡d(mod m),则ac≡bd(mod m)。
总结:
rsa求解主要通过推导出它们之间的关系,所以想每一题都能做出来,要有一个好的数论基础 ,没有基础的话就只能像本人一样边做边学,做不做的出来就要靠临场发挥,好的运气(有时候,你推了半天的公式结果根本无法跑出flag,需要的时间太久了)
XCTF分站赛ACTF——Crypto的更多相关文章
- Xctf攻防世界—crypto—Normal_RSA
下载压缩包后打开,看到两个文件flag.enc和pubkey.pem,根据文件名我们知道应该是密文及公钥 这里我们使用一款工具进行解密 工具链接:https://github.com/3summer/ ...
- XCTF crypto 不仅仅是Mors
一. 题目暗示摩斯码,打开文件发现里面有反斜杠的.不管它直接拿来解密 二. 发现一句话是句英文,还有其他的加密方式,后面那串只有两种字符A和B,手抓饼A套餐,b套餐 培根加密,拿来解密后,得到flag
- 【CTF】XCTF Misc 心仪的公司 & 就在其中 writeup
前言 这两题都是Misc中数据包的题目,一直觉得对数据包比较陌生,不知道怎么处理. 这里放两道题的wp,第一题strings命令秒杀觉得非常优秀,另外一题有涉及RSA加密与解密(本文不具体讨论RSA非 ...
- javax.crypto.BadPaddingException: Given final block not properly padded 解决方法
下面的 Des 加密解密代码,在加密时正常,但是在解密是抛出错误: javax.crypto.BadPaddingException: Given final block not properly p ...
- 使用crypto模块实现md5加密功能(解决中文加密前后端不一致的问题)
正常情况下使用md5加密 var crypto = require('crypto'); var md5Sign = function (data) { var md5 = crypto.create ...
- javax.crypto.BadPaddingException: Given final block not properly padded
一.报错 写了一个加密方法,在Windows上运行没有问题,在Linux上运行时提示如下错误: javax.crypto.BadPaddingException: Given final block ...
- Liunx-https-java.lang.NoClassDefFoundError: javax/crypto/SunJCE_b
错误信息: java.lang.NoClassDefFoundError: javax/crypto/SunJCE_b at javax.crypto.KeyGenerator.a(DashoA13* ...
- node crypto md5加密,并解决中文不相同的问题
在用crypto模块时碰到了加密中文不相同的问题,多谢群里面@蚂蚁指定 1:解决中文不同的问题 function md5Pay(str) { str = (new Buffer(str)).toStr ...
- Crypto++ 动态链接编译与实例测试
测试用例的来源<Crypto++入门学习笔记(DES.AES.RSA.SHA-256)> 解决在初始化加密器对象时触发异常的问题: CryptoPP::AESEncryption aesE ...
随机推荐
- spring cron表达式源码分析
spring cron表达式源码分析 在springboot中,我们一般是通过如下的做法添加一个定时任务 上面的new CronTrigger("0 * * * * *")中的参数 ...
- 220722 T2 序列(ST表+分治)
题目描述 小 B 喜欢玩游戏. 有一天,小 B 在玩一个序列上的游戏,他得到了正整数序列{ai}以及一个常数c . 游戏规则是,玩家可以对于每一个ai 分别加上一个非负整数x ,代价为 x2,完成所有 ...
- BinaryBombs(二进制炸弹实验)
实验介绍 使用所学知识拆除Binary Bombs来增强对程序的机器级表示.汇编语言.调试器和逆向工程等理解. Binary Bombs(二进制炸弹)是一个可执行程序,是C语言编译链接成的,包含pha ...
- VM运行centos网络配置(出现错误)详解
一般按照正常安装流程到这一步的时候可以直接点击网络和主机名,但是我这里并没有连接成功,因此我跳过了这里想着后面再配置 后面通过ping www.baidu.com以及ping 百度的ip地址(如何获得 ...
- 华为路由器DHCP配置基本命令
配置基于接口地址池DHCP (动态主机配置协议) [R1]dhcp enable 路由器上开启DHCP [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]dhcp sel ...
- Vue学习之--------组件在Vue脚手架中的使用(代码实现)(2022/7/24)
文章目录 1.第一步编写组件 1.1 编写一个 展示学校的组件 1.2 定义一个展示学生的信息组件 2.第二步引入组件 3.制作一个容器 4.使用Vue接管 容器 5.实际效果 6.友情提示: 7.项 ...
- Vue中组件化编码 完成任务的添加、删除、统计、勾选需求(实战练习三完结)
上一个章节实现数据在组件之间的传递 .这一章主要是完成添加任务到任务栏.删除任务栏.统计任务完成情况.主要还是参数在各个组件之间的传递. 上一章节的链接地址:https://blog.csdn.net ...
- 【FAQ】关于华为地图服务定位存在偏差的原因及解决办法
一. 问题描述: 华为地图服务"我的位置"能力,在中国大陆地区,向用户展示他们在地图上的当前位置与用户的实际位置存在较大的偏差. 具体差别可以查看下方的图片: 二. 偏差较大的原因 ...
- java中类的关系的总结
类和类之间存在多种关系,而这种关系在我们的代码中司空见惯,有时多种类关系很难区分 (由于水平有限,没有画出类的关系图,关系图可以参考参考链接) 继承关系 继承是指一个子类(子接口)继承父类(父接口)然 ...
- Java多线程-ThreadPool线程池-2(四)
线程池是个神器,用得好会非常地方便.本来觉得线程池的构造器有些复杂,即使讲清楚了对今后的用处可能也不太大,因为有一些Java定义好的线程池可以直接使用.但是(凡事总有个但是),还是觉得讲一讲可能跟有助 ...