21Jan1
huangx607087寒假的切题1
0x00 简介
一个密码学废物的寒假切题记录的exp,别看,贼菜
近期BUUCTF的分数上到了500分,不过目前的形式依然很严峻,与我同级的一个人比我强很多,而我却在这里补基础,感觉校队里同一级除web方向的人不可同时存在2个及以上,压力还是非常大的
#define huangx607087 yongyuandefeiwu
0x01 ECC & RSA
这是一道结合了离散对数和椭圆曲线的密码体系,我们可以先看一下加密代码和题目所给出的的各种数据。
1 |
|
我们通过上面的加密过程可以发现:$(p,q)$实际上是椭圆曲线$y^2=x^3+ax+b$上面的点,所以我们可以有一个等式为$q^2=p^3+ap+b$,加上RSA中的等式$n=pq$,两边平方后带入$q^2$表达式为$n^2=p^5+ap^3+bp^2$,然后用以下的sagemath代码即可,注意求解多项式的根应该是$f=0$的根,所以最后要减去一个$n^2$,把方程化成$p^5+ap^3+bp^2-n^2=0$
最后求出来$3$个解,很显然,由于RSA中$p$是素数,那么只有第二个解符合题意。此时$n$就被分解成功,进而我们就很快地能够解密了。
下面附上一些Sagemath中对密码学有关的函数供以后查阅
1 |
|
2.[*ctf]little case&[NCTF2019]easyRSA
这两道题都是涉及到了RSA中$\gcd(p-1,q-1,e)=e$的情况,直接查阅RSA Notes 3中的相关内容即可,此处不再赘述。
3.[NPUCTF2020]Mersenne twister
一道梅森旋转题,还是先看一下题目
1 |
|
这道题目与之前我博客里的**PRNG MT Notes[2020.10.26]**所涉及到的题目基本一致,只不过是将密文中的每一位的md5值与生成的随机值进行异或。我们还是只需要求出Next函数的逆即可(那篇博客也提供了对应方法,简单调参即可使用)。
不过问题是我们无法知道完全的$233$个状态,只能得知我们仅有的$104$个状态。其中一个办法就是枚举seed,枚举规模约为$43$亿,实际上跑了$16$亿多一些。(不过好像可以不用枚举seed,具体方法待更新)
Update 2021.7.20
如果我们重新观察一下代码,我们可以发现如下内容:
由于寄存器规模是$233$,而实际上只产生了$104$个随机数,因此内部的state所有内容是不变的。并且根据题目产生随机数的方式可知:在产生新的state的时候,与旧的state有如下关系:
1 |
|
因此新的state[i]
与旧的state[i],state[i+1],state[i+130]
有关系。而题目中已经告诉了我们flag的第一位和最后一位。因此state[0],state[103]
都可以求出来。有Newstate[103]=Oldstate[103]^Newstate[0]
,这样我们就可以获得Oldstate[103]
的最高$31$位了。
这部分结果我就略去了,算出来的Oldstate[103]
可能的$32$位结果: $\text{D7FC4AA6H or D7FC4AA7H}$
然后我们分别用以下代码验证一下就行了:注:由于newstate[103]>>31==0
,因此不需要考虑
1 |
|
4.[ACTF新生赛2020]crypto-aes
1 |
|
一道AES题目,我们可以看出key是$8$组$4$位$16$进制数,我们只需要把他给出来的第一个异或结果拿出来并输出$16$进制,发现前面是$4$组$\text{C981}_h$,而后面是不规则内容。我们只需要把不规则内容用$4$组$\text{C981}_h$进行异或即可。这样我们的key和iv就都拿到了
最后我们只需要模仿他的模式,即可解出flag了
1 |
|
5.[*ctf]GuessFlag(1)(2)
1 |
|
题目的意思很简单,服务器会保留一个随机的$64$位整数,并记录下所有的$0$位。你每次向服务器发送一个数字,然后服务器会任意选取已有密钥中$2$个$0$比特位,并将这$2$个$0$比特位之间的所有比特位依次循环异或你所发送数字的各个比特位。连续$3$次猜中密钥即可获得答案
一开始print(flag)
是给出的,这次只需要发送三次$0$,这样密钥就保持不变,然后每次猜就猜他给出来的那个数,然后就可以获取flag
不过后面升级了,print(flag)
这句话被删除了,这个时候就要想办法了我这个fw还问了学长,所以我自己果然是个fw。这个时候,我们只需要每次发送$1$,这样任意两个$0$之间的所有比特位都有可能被异或。不过我们多次本地实验后会发现:随着发送$1$的次数不断增多,密钥末尾的固定$1$比特位的长度越来越长,所以只需要不到$200$次的发送$1$,最后$64$个比特位就会全是$1$。所以我们每次猜密钥都猜$18446744073709551615$,也就是$2^{64}-1$,到最后就会连续$3$次猜中,最终我们就肯伊拿到flag
(这两道脑洞题个人认为质量还是挺高的,谁叫自己是个fw呢)