0xGameDiv3
0xGame Div 3 题解
About
第三周,密码学难度还可以,前2题难度不大,第3题难度有点大,不过还是能够用一天的时间切出来了。不过第三周结束还没有到达到7000分,第一周就有很多全栈大佬7000了,我还没他们1/3的效率高。看来奖励拿不到了。。
Crypto
1. signinRSA
这道题看到时签到题,读了一下代码,这跟上一周的parityOracle竟然有$99$%的相似。
不多说,直接复制上周写好的脚本 ,改一下nc地址,把上周脚本的倒数第$8$行的recnum=int(recnum[-1])
改为recnum=int(recnum[-1],16)
,然后把倒数第$7$行和倒数第$5$行的对recnum的判断加上%$4$操作(如下),直接运行,几分钟就出结果了。
1 |
|
2.easyRSA
先看一下题目的代码
1 |
|
题目给出了$n,c,x$的值(当然也有$e=65537$),其中$x=11d+7\phi$ ,所以这道题不同寻常之处就是给出了$x$,故突破口在x处。
通过之前RSA中相关知识可知:$d$ 是$e$在模$\phi$意义下的乘法逆元,也就是$ed \equiv 1 \mod \phi$ 。而由于$p,q$均为质数,所以$\phi=(p-1)(q-1)$
既然题目给出$x=11d+7phi$ ,而$d,phi$均为未知量。所以根据方程校园思想,我们可以两边同乘$d$,得到$ex=11de+7e \phi$ 。这个式子对$\phi$取模之后,我们可以得到$ex \equiv 11 \mod \phi$,这时候这个式子仅剩下一个未知数,所以我们可以提出$\phi$ ,得到$k\phi=ex-11$
在$\phi=(p-1)(q-1)=pq-p-q+1=n-p-q+1$,由于$p,q$均为$1024$位,$n$为$2047$位,远远大于$p+q$。故$\phi$的二进制位数跟$n$应该基本是一样的,计算可知,$phi$是$2068$位,所以$k$应当是$21$位或者$22$位,也就是$k∈[2^{21},2^{22})$。
我们用以下脚本枚举$k$,然后直接进行long_to_bytes
的操作,虽然有大概$50$多组解,然而最像flag的只有一组,故我们就得到了flag。
1 |
|
3. paddingOracle
又是一道Oracle,想到上一条Oracle我搞了好久= =。果然,上题12小时,还没人做出来。上题18小时后,才有人拿一血。我就比较逊了。上题35小时才把2血拿到。感觉后面密码学题目会越来越难的样子,awsl
简单地看了一下相关资料,然而本人太菜,连书都看不懂,最后摸索了12小时才搞懂题目意思,就让我用简洁的语言讲一下这道题的意思吧
首先,服务器会给你一个长度为$32$位的$16$进制数为初始向量,然后再给你$32k$个$16$进制数为密文(本题中$k=3$,也就是一共$96$位)。有些题目它直接给你一个$32(k+1)$位的$16$进制数,这个时候就默认最前面$32$位为初始向量,后面的$32k$位作为密文。
得到初始向量后,将密文分为$k$组,每组$32$位。记初始向量为$I_0$,后面的密文组为$I_1,I_2,I_3,…,I_k$
这个时候,我们还需要$3$个$16$位数组:$Clc$、$Tlc$和$Alc$,分别用于存储每一次解密的枚举值、中间值和破解出来的明文
第一轮枚举,我们枚举$Clc$最后一个数字也就是$Clc_{15}$,当服务器返回success时,计算$Tlc_{15}=Clc_{15}$xor$1$的值,然后轮数进入第二轮,用$Tlc_{15}$更新$Clc_{15}$,也就是$Clc_{15}=Tlc_{15}$ xor $2$。
需要注意的是:第$p$轮枚举,我们枚举的值是$Clc_{16-p}$,用$Clc_{16-p}$更新$Tlc_{16-p}$为$Clc_{16-p}$ xor $p$,然后轮数进入$p+1$,这时我们需要用$Tlc_{16-p}$及其以后所有解出来的$Tlc$去改变所有已知的$Clc$值,也就是把后面所有的$Clc$改为 $Tlc$ xor $p+1$**。换句话讲就是说$Tlc$解出来之后永远不能变,$Clc$每一次解出来以后会被不断更新。$Clc$更新$Tlc$,只更新最新解出来的一位,$Tlc$更新$Clc$,需要更新解出来的所有$Clc$内容**
上面的解释可能比较抽象,那我就用下面的例子来解释一下吧(数字下标$h$表示$16$进制,也就是$14_h$的真实值为十进制的$20$:
Round 0
初始状态:
$Clc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00]_h$
$Tlc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00]_h$
Round 1(枚举 $Clc_{15}$ )
第$1$轮,我们枚举$Clc_{15}$的值,假设我们枚举到$Clc_{15}=78_h$的时候服务器发回Success
那么此时:$Clc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,$$78$]$_h$
用$Clc_{15}$更新$Tlc_{15}$,$Tlc_{15}=Clc_{15}$ xor $1$(轮数)$=79_h$
$Tlc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,$$79$]$_h$
Round 2(枚举$Clc_{14}$ )
然后进入第$2$轮,我们首先得更新一下$Clc_{15}$的值为$Tlc_{15}$ xor $2=7B_h$
此时$Clc$发生了变化:$Clc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,$$7B$]$_h$
然后我们枚举$Clc_{14}$的值,假如我们枚举到$Clc_{14}=52_h$时服务器返回Success
那么此时:$Clc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,$$52$$,7B]_h$
用$Clc_{14}$更新$Tlc_{14}$,$Tlc_{14}=Clc_{14}$ xor $2$(轮数)$=50_h$
此时的$Tlc$:$Tlc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,$$50$$,79]_h$
Round 3(枚举$Clc_{13}$)
进入第$3$轮,此时一个易错点(敲黑板)出现了:由于此时已经出来了$Clc_{14}$和$Clc_{15}$,第$3$轮异或值为$3$,所以我们要对$Clc_{14}$和$Clc_{15}$都进行异或$3$的操作
此时:$Clc=[00,00,00,00,00,00,00,00,00,00,00,00,00,00,$$53,78$$]_h$,两位都进行了更新
所以以上操作就是我们所讲的:$Clc$更新$Tlc$ 只更新这次解出来的一位,而$Tlc$更新$Clc$,需要更新$Clc$中已经解出来的所有$Clc$值
$16$个$Tlc$解出来后,本轮$Alc$就等于$Tlc$ xor $I_{m-1}$($m$为第$m$解密)。然后重新初始化,进行下一大轮的解密。$k$轮解密结束,我们就得到了所有的明文了(注意过滤掉里面的无关字符)
这个该死的脚本写了我98行,7个子函数。还是比较烦人的。因为一开始没规划好导致一会用$16$位数组(每个正数不超过$255$),一会用$32$位数组(每个正数不超过$15$)。虽然写起来简单,但还是减少了代码的可读性,究其原因,只有一个:作为密码学废物的我太菜了
1 |
|