羊城杯 2023 Wp(复现)
NSS刷题复现笔记,过程写的可能比较简单,有问题欢迎指出交流(・∀・)つ⑩
esyRSA
题目:
1 | from gmpy2 import invert |
分析:
维纳攻击,把d当作原本的e就行,进行连分数展开便能求解。
值得注意的是,本题附件存在问题,n的真实数字在附件中重复了两遍,要手动删去(/‵Д′)/~ ╧╧
题解:
1 | #sage |
Danger_RSA
题目:
1 | from Crypto.Util.number import * |
分析:
已知X = getRandomInteger(nbit // a),则有$2\leq a \leq 1024$
已知s = getRandomRange(pow(2, a ** 2 - a + 4), pow(2, a ** 2 - a + 5)),则有$2^{a^2-a+4}\leq s \leq 2^{a^2-a+5}$
同时e分解可以得到$e = 3\cdot 7 \cdot 7 \cdot 19 \cdot 691 \cdot 5741,且2^{33}\leq e \leq 2^{34}$
尝试不同的a的值:
- a=2时,$2^4\leq s \leq 2^5$
- a=3时,$2^{10} \leq s \leq 2^{11}$
- a=4时,$2^{16}\leq s \leq 2^{17}$
结合e的取值范围,可以得到$a=4$
之后对e的因子进行排列组合拆成两组,可以发现有两种组合 - $s = 5741\cdot 19,t=691\cdot 3 \cdot 7 \cdot 7$
- $s=5741\cdot 3 \cdot 7,t=691\cdot 7 \cdot 19$
$\therefore N=(X_1^4+s)(X_2^4+t)$
$\because X_1^4X_2^4 >> tX_1^4+sX_2^4+st$
$\therefore gmpy2.iroot(N,4)[0] = X_1X_2$
$\therefore$两个未知数两个方程,列方程组求解即可得到$p,q$
但是后续求解出$p,q$后会发现$e$和$phi$不互素,后来尝试后发现$3|(p-1),7|(q-1)$,由于明文的比特一般不会大于$p$的1024比特,因此尝试在模$p$下求解,将$m^3$当作整体,求$d=invert(e//3,p-1)$,最后求出$m^3$再在模$p$下求根即可。
解答:
1 | #sage |
Easy_3L
题目:
1 | from gmpy2 import * |
Part1:NTRU求S3
已知(1)$c\equiv sh + s_3 \mod p$
还有(2)$h \equiv f^{-1}*q \mod p$
(1)两边同时乘以$f$,有$cf\equiv sq + s_3f\mod p$
再对$q$取模得,$cf\equiv s_3f \mod q$,令$a=cf$,则有$a\equiv s_3f \mod q$
因此我们要求$(f,q)$
根据$hf\equiv q\mod p$构造格:
$$
(f,k)
\begin{pmatrix}
1 & h\
0 & p
\end{pmatrix}
=(f,q)
$$
求得$s_3$
Part2:LCG求seed
利用已知连续5个序列值先求模$n$,方法如下:
$m=gcd(t_{n+1}t_{n-1} - t_n^2,t_{n+2}t_{n} - t_{n+1}^2 )$
具体推导可以看我另一篇博客:Crypto基础篇-LCG Ramoor
再求$a,b,seed$即可
解答:
1 | from Crypto.Util.number import * |
XOR贯穿始终
massage.txt:
1 | 自由和谐和谐富强公正友善爱国公正法治法治文明和谐自由法治自由法治平等公正友善公正公正民主法治自由公正敬业和谐富强公正友善爱国和谐平等平等友善敬业法治敬业和谐富强法治平等平等友善敬业公正公正公正友善敬业法治平等平等诚信自由公正自由平等友善敬业公正友善法治和谐和谐 |
社会主义核心价值观编码解码得到
1 | C0ngr4tulati0n5_y0u_fou^d_m3 |
将其作为压缩包密码进行解压缩
pri.pem
1 | -----BEGIN PRIVATE KEY----- |
task.py
1 | from gmpy2 import gcd |
提示私钥文件被损坏,因此我们首先对私钥文件进行base64解码并转换为十六进制数据
1 | 30 82 02 77 02 01 00 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 04 82 02 61 30 82 02 5d 02 01 00 02 81 81 00 b9 ad 33 2f b6 b8 7d 59 b5 b2 0b 4a e8 80 ba 41 6d 87 24 11 1f 99 a9 ed 49 8b cb 36 50 91 d8 3d cc 43 fd ff 9b 60 7d f8 a4 43 bc ad c7 99 07 c9 21 e7 6b 38 00 3b 5b 0e ce 66 04 37 80 31 95 eb fa b9 a7 e2 3f c0 75 12 28 fd ee fe 55 91 82 75 23 d7 b7 9a d0 4d 85 e4 db 5c aa 13 f2 8a 7e 01 24 35 7d 06 85 e0 0f 14 cc bb 96 79 97 99 23 c2 53 1f f4 87 f9 ba 25 00 ad e4 89 95 c3 15 d9 13 02 03 01 00 01 02 81 81 00 97 4e bb 2d a0 bb 0a fb 36 03 97 0c 3e 17 d8 b0 44 af 22 07 0a 37 50 b0 5b 84 9d de ef 1d 4a 98 61 82 ee d3 83 2c c8 ba fc 31 6e ea 36 83 50 42 e9 6c 0a 85 a2 3a bc 63 7e 72 c7 f0 ea 78 7d f0 61 27 fe 9d c3 d2 1b 8d ae 80 18 bd ff c3 45 10 7d 52 71 dd b6 d5 fb c0 1f 8c bf 73 f4 44 10 d6 1e 00 62 08 35 6f 1c 5b 85 51 5e fc 70 8b 34 b6 76 e7 8f 18 d4 d3 b6 8f 57 65 d1 0b 70 1f 03 61 02 41 00 ea 59 43 4f 56 0d e2 ea f4 f2 1c 22 fb 10 69 1b 79 48 5e 62 90 00 7d c2 82 42 bc 63 73 9f b9 5f a0 3e 5e d8 07 00 0d 49 1f 0c a4 3e 50 a9 1d 43 a6 94 0f 39 0c 91 75 7a 3b a8 22 6c e5 81 12 c9 02 41 00 ca d4 c2 9d 01 7e 30 dd ab d6 06 80 50 44 d9 ca 3e 6a 31 84 fb 4e 1f 33 28 45 55 54 98 c3 6b 02 e7 b9 7e 2e b0 9d 85 c9 19 e3 0a 49 3c e9 4e f9 41 22 61 c3 99 8c 73 44 27 1b 6e 6e 1b 3d fe fb |
按照顺序各个部分得特点进行拆分:
02 81 81表示0x81即129字节的模数n:00 b9 ad 33 2f b6 b8 7d 59 b5 b2 0b 4a e8 80 ba 41 6d 87 24 11 1f 99 a9 ed 49 8b cb 36 50 91 d8 3d cc 43 fd ff 9b 60 7d f8 a4 43 bc ad c7 99 07 c9 21 e7 6b 38 00 3b 5b 0e ce 66 04 37 80 31 95 eb fa b9 a7 e2 3f c0 75 12 28 fd ee fe 55 91 82 75 23 d7 b7 9a d0 4d 85 e4 db 5c aa 13 f2 8a 7e 01 24 35 7d 06 85 e0 0f 14 cc bb 96 79 97 99 23 c2 53 1f f4 87 f9 ba 25 00 ad e4 89 95 c3 15 d9 1302 03表示e:01 00 01即e=6553702 81 81表示0x81即129字节的私钥指数d:00 97 4e bb 2d a0 bb 0a fb 36 03 97 0c 3e 17 d8 b0 44 af 22 07 0a 37 50 b0 5b 84 9d de ef 1d 4a 98 61 82 ee d3 83 2c c8 ba fc 31 6e ea 36 83 50 42 e9 6c 0a 85 a2 3a bc 63 7e 72 c7 f0 ea 78 7d f0 61 27 fe 9d c3 d2 1b 8d ae 80 18 bd ff c3 45 10 7d 52 71 dd b6 d5 fb c0 1f 8c bf 73 f4 44 10 d6 1e 00 62 08 35 6f 1c 5b 85 51 5e fc 70 8b 34 b6 76 e7 8f 18 d4 d3 b6 8f 57 65 d1 0b 70 1f 03 61
使用脚本获取m:
1 | d = 0x00974ebb2da0bb0afb3603970c3e17d8b044af22070a3750b05b849ddeef1d4a986182eed3832cc8bafc316eea36835042e96c0a85a23abc637e72c7f0ea787df06127fe9dc3d21b8dae8018bdffc345107d5271ddb6d5fbc01f8cbf73f44410d61e006208356f1c5b85515efc708b34b676e78f18d4d3b68f5765d10b701f0361 |
获取明文m:
1 | DASCTF{0e287wQ\x08R\x17\x00FGXYFZ\x07V\x03kIUCn\x02VDg\x01f\x0cN |
发现后半段没正常显示,根据题目猜测需要将第一步得到的字符串和该串进行异或
1 | b = b'C0ngr4tulati0n5_y0u_fou^d_m3' |
得到:
1 | DASCTF{0e2874af5e422482378640e61d919e9a} |
SigninCrypto
题目:
1 | from random import * |
分析:
根据题目分析,我们的主要目的是根据存在的漏洞恢复$key$和$IV$
Part1:恢复key
(1)恢复K1
使用long_to_bytes(xor)可以发现,前8个字节是四组重复的,符合$hint1$的特点,猜测$K1$应该只有8个字节,因此使用前八个字节异或上后8个字节便可以恢复$K1$
(2)恢复K2
对于MT19937提交624个32bit数,便能够预测后边的随机数,但题目中并没有直接给出624个32bit数。
1 | for rand16 in List1: |
已知List1和List2都是从头开始生成的,且输出到文件中的list2序列是不完整的,只输出了每个$rand64$的[:16]和[32:48]。因此我们需要想想办法恢复出624个32bit数getrandbits(16)的生成规则是每次生成一个32bit数,再从这个32bit数中截取16位作为生成的随机数。
因此List1就是List2的缺失部分,我们可以通过拆分拼接List1和List2得到624个32bit数。
(3)恢复K3
K3为flag[:8],已知前7个字节为DASCTF{,因此爆破一个字节便可以
Part2:恢复IV
(1)恢复IV1
$IV$共8个字节,而$hint2$为$IV$向左移动了4个字节之后和8个字节的随机字节进行异或,说明高4个字节,即$IV1$未参与运算,$hint2$的高4个字节便是$IV1$
(2)恢复IV2
根据(1)算出的$IV1$可以计算出$digest1$,同时题目给出了$digest$,在$digest$中去除$digest2$之后便剩下了$digest2$
。虽然我们这里只获得了$IV2$的哈希值,可能需要爆破,但是求出来之后我们发现$digest2=digest1$,我们默认不存在碰撞,即$IV2=IV1$
解答:
1 | from Crypto.Util.number import * |
MCeorpkpleer
题目:
1 | from Crypto.Util.number import * |
分析:
根据题目,可以发现,我们需要求$p_{low}$和$e$,其中$p_{low}$可以利用coppersmith定理来求解。
而对于$e$来说,观察$e_cry$发现它是将$e$的二进制的每一位用于背包加密了。
解答:
1 | from Crypto.Util.number import * |








