近期比赛复现Vol.1
SCTF
Barter(赛后)
两个文件:
sage:
1 | from Crypto.Util.number import * |
homework.py:
1 | from Crypto.Util.number import * |
这个题需要先破解homework得到PQ和r才能去解椭圆曲线。
homework破解非常简单,对方随机生成RSA参数进行加密,需要我们用I can not agree more!!!
这串作为m并发送我们的e和n再进行一次加密,如果两次加密值相同就返回椭圆曲线参数。
直接生成一个小e即可,有$sign=m^e\bmod n$可直接假设:
传值,得到返回参数:
1 | P=(24181776889473219401017476947331354458592459788552219617833554538756564211844, 33783050059316681746742286692492975385672807657476634456871855157562656976035) |
在这题的椭圆曲线里生成了一个随机数序列:
1 | def gen_random(seed, P, Q, r_list, times): |
而且PQ的关系也是已知的:
1 | def getP_Q(): |
我们已知了$PQ$和$r_0$,不知道seed,用公式观察一下试试:
可以发现$s_1$和$r_0$在椭圆曲线上差了$114514$倍,我们知道$r_0$了,代入曲线可以求$s_1$,紧接着可以反复把$r$数组全部还原,剩下的直接照搬异或就出了:
1 | from tqdm import tqdm |
GoogleCTF
LCG(赛后)
1 | from secret import config |
看完代码,题目给了LCG的前六组,可以根据这六组逐个还原LCG的参数,根据题目RSA生成代码直接解就行,生成质数部分直接复制粘贴即可:
1 | from Crypto.Util.number import * |
第一次做没做出来,发现flag文件的二进制字节被反转了,再
[::-1]
反转回来才能解出来。
巅峰极客2023
数学但高中
1 | x=4{0<y<6} |
给了一堆函数曲线之类的东西,猜测是画图的flag,用几何画板geogebra应该就可以,不过暂时没研究明白几何画板怎么玩,就直接手操了:
Simple_encryption
1 | from Crypto.Util.number import * |
flag分了两部分加密。
前部分先利用费马小定理计算得到$g_2$和$p$:
然后变换一下同余方程组还是利用费马小定理使其能使用中国剩余定理求解$m_1$:
后部分$e$过小直接开根后分别求解三个一元二次方程,ABC参数都给了所以直接解就行:
1 | from Crypto.Util.number import * |
DASCTF 2023七月
ezDHKE
1 | from Crypto.Util.number import * |
一道DH,传一个符合要求的$p$,首先想到了用$p-1$光滑数:
1 | from Crypto.Util.number import * |
发送,得到了$AB$和$enc$,sage的discrete_log
的算法包含了Pohlig–Hellman的光滑数算法,分解得到$a$,即可求出key,解密得到flag:
1 | from Crypto.Util.number import * |
ezRSA(赛后)
1 | from Crypto.Util.number import * |
注意到这里的$gift=P\oplus (Q<<16)$,提供了$gift$,相当于知道了$P$的前16位,可以根据二进制的乘法还原出$Q$的最开始的几位(由于需要考虑进位,所以可以少取几位),知道$Q$的前$x$位之后根据异或可以得到$P$的$16+x$位,然后按照这种方法不断循环就可以大致求出$P$,由于$Q$的最后16位不知道,所以$P$求到最后会差几位,直接爆破即可:
1 | N = 75000029602085996700582008490482326525611947919932949726582734167668021800854674616074297109962078048435714672088452939300776268788888016125632084529419230038436738761550906906671010312930801751000022200360857089338231002088730471277277319253053479367509575754258003761447489654232217266317081318035524086377 |
在这里恢复n
的时候有一个坑的地方:print(N, gift, pow(n, e, N))
这里的n
如果本来比N
还大的话,我们求逆得到的n
就不对了,需要再加上一个N
。
这题还考了一种相关信息攻击:
1 | assert flag == b"dasctf{" + secret + b"}" |
我们得到的两个密文的明文不同,而且这两个明文有些联系(bytes是256一位):
1 | flag = bytes_to_long(b'dasctf{' + b'\x00' * i + b'}') + 256 * secret |
这里就可以使用Franklin-Reiter相关消息攻击:如果两个信息之间存在已知的固定差异($f(x)=ax+b$),并且在相同的模数$n$下进行RSA加密,那么就有可能恢复出这两个消息。
有:
可以知道$M_2$是$f(x)^e-C_1\equiv 0(\bmod N)$的一个解,也是$x^e-C_2\equiv 0(\bmod N)$的解,对两个多项式分别进行辗转相除法求得多项式的最大公因子,如果最大公因子是线性的(次数为1),即最大公因子可以表示为一个一次多项式($x-M_2$),那么在模数下仍满足$x-M_2=0$,就求得了$M_2$:
这个题中没告诉flag的长度,所以需要进行爆破,找到符合长度的secret。
1 | from Crypto.Util.number import * |
NepCTF 2023
打比赛两天比较忙,就做了几个misc,过了一遍密码的几个题,感觉比较复杂也没做出来,赛后复现一下吧。
random_RSA(赛后)
这题学长仿着校赛的那道题出的:
1 | from gmpy2 import next_prime, invert as inverse_mod |
还记得之前那个是解一个二元的同余方程,这里最大的变化就是e = inverse_mod(d, (p * p - 1) * (q * q - 1))
,问题就是如何分解模数,当时想到了用连分数攻击,但是具体怎么个攻击法不是很清楚。
依照论文《Cryptanalysis of RSA Variants with Primes Sharing Most Significant Bits》,如果出现上述这种情况,可以寻找$\frac e{N^2-\frac 94N+1}$的连分数来恢复,但是不确定谁才是真正的$p,q$,所以后续还需要排列组合一下,用到itertools:
1 | import gmpy2, itertools |
WMCTF
signin
1 | from Crypto.Util.number import * |
这题分为两个部分,上半是一个类似于上面ezRSA的求解因子的操作,不过这里没有提供高位,可以直接爆破一下:
1 | N = 56926121230070860522021858222376835199152768535695893312307107271470069724930276796319823573131233195237160028777740480344562965515093909280322054086785487388103390618832318336984744202378593597183981582538471590847113343740046218768605691018126706982690057576771999872413555389254225943044818790534983211867 |
得到$pq$之后发送,会得到发来的两个数组:
1 | secret = randrange(0,P) |
这里需要求解一个secret,搜索发现属于格密码的HNP问题:
题目比较常规,找了道差不多的题目改了改:
1 | p = 11097356886714303582042893881171986567091401868447229878503047789761897485022302260317124893493702691228364525570373590910056115747877840029999866380610223 |
SICTF Round2
大部分都是随手出的题就不往上放了。
签到题来咯!(赛后)
1 | from secret import flag |
没看出来是Franklin Reiter攻击,这次做题又把这个攻击方式回顾了一遍:
1 | from Crypto.Util.number import * |
SHCTF
题目整体比较简单,该省的省了。
XOR
1 | n = 20810298530643139779725379335557687960281905096107101411585220918672653323875234344540342801651123667553812866458790076971583539529404583369246005781146655852295475940942005806084842620601383912513102861245275690036363402134681262533947475193408594967684453091957401932685922178406769578067946779033282889429596341714417295489842047781388337010440309434639274398589029236213499110100040841426995862849012466514170374143655264739023758914247116354182164550612494432327931655944868705959874670536031052370968354394583880324756639698871918124498442308334232127034553164826483441746719644515097123067550594588348951855987 |
给了$p\oplus q$,网上随便找了个分解脚本梭哈了:
1 | import math |
easymath
LCG板子题,太简单了不看了。
ez_rsa
flag分了两半,一半yafu一半共模。
e?
不互素。
factorizing_n
yafu。