CryptoCTF 2023 easy分类 团队解题writeup
这次 easy 分类偏简单,
不过由于配合得不是很好,所以在实战中会有部分题目卡壳的情况
不过还好能有其他人也帮忙看一看,所以马上就能够解围
Did it!
题目描述
记 $n = 127$,$N=\{0, 1, 2, \ldots, n-1\}$,有随机的未知 $K \subseteq N$,且 $|K| \le 20$。
有至多 12 次的机会,输入一个集合 $A \subseteq N$,且 $|A| \le 20$,返回结果
对于所有 ${x_i \in A - K}$
其中 $r_i \in \{0, 1\}$ 为一个关于 $x_i$ 的随机数。
如果输入的 $A = K$,则得到 flag。
我的解答
也就是说,有至多 11 次的机会去得到结果,然后就要猜出 $K$ 来。
因为 $n$ 是素数,所以对于结果中的每一组 $x_i^2 \bmod n + r_i$,都可以枚举 $r_i$,通过开平方求得可能的 $x_i$。然后再用 $A$ 减去这些 $x_i$ 构成的集合,就得到 $K$ 中可能包含的元素。
另外,我们把输入的 $A$ 元素个数弄小一点,以减小下面的情况出现的概率:
如果不幸地,上式成立的话,我们就会错误地把 $A \cap K$ 中的元素 $k_j$ 也当作 $A-K$ 中的元素给移除掉,其中 $r_i’$ 为我们上面枚举的 $r_i$。因为至多 12 次机会去得到结果,所以每次猜测的集合大小至多为 $\lceil127/12\rceil = 11$。即使是这样,也有很大概率弄不出所有的 20 个数,也要通过诸如赌 $K$ 在生成的过程中生成一样的数,从而导致 $|K|<20$ 来增大能求出的概率。(当然不排除能有将 $\{0, 1, \ldots, 127\}$ 进行科学地划分以避免上述情形出现的手法,但是能通过碰概率猜出 $K$ 就咸鱼了)
代码如下:
1 | from pwn import * |
得到 flag 为:
1 | CCTF{W4rM_Up_CrYpt0_Ch4Ll3n9e!!} |
再次尝试:将 $N$ 进行划分为两两不交的子集 $N_0, N_1, N_2, \ldots, N_{11}$,使得
- $|N_i| \le 20$ 对于 $i = 0, 1, \dots, 11$
- 不存在 $x_i, x_i’ \in N_i, r_i, r_i’ \in \{0, 1\}$,使
因此可以做一个很简单的贪心:对于 $x = 0, 1, \dots, n-1$:
- 尝试放到第 $i$ 个集合 $N_i$ 里面
- 如果 $|N_i| = 20$,那么就不能放到这个集合里面
- 计算 $x^2 \bmod n$ 和 $x^2 \bmod n + 1$,如果这两个值都不和 $N_i$ 所有值的平方和平方加一冲突,那么就能把 $x$ 加到这个集合里面
- 否则就不能放到这个集合里面
- 如果不能放到第 $i$ 个集合 $N_i$ 里面,那么就尝试放到第 $i+1$ 个集合 $N_{i+1}$ 里面。
贪心构造划分的代码如下:
1 | t = 12 |
将得到的划分结果应用在猜测中:
1 | from pwn import * |
就能不用多次尝试就能猜出集合 $K$ 来。
Suction
题目描述
RSA 中,$N=pq$,但是 $p, q$ 仅有 128 位。
题目给出的 $(N, e, c)$ 的后 8 位均未知,且 $e$ 为 16 位素数。
求明文 $m$。
我的解答
所以就是嗯枚举就行了。
- 枚举 $N$ 的后 8 位,并尝试分解。如果能分解成 2 个 128 位素数之积,那么可能就是 $N$。注意 $N$ 为两个奇素数之积,必为奇数
- 枚举 $e$ 的后 8 位,如果是素数,并且 $e$ 与 $\phi(N)$ 互素,那么可能就是 $e$。注意 $e$ 为奇素数
- 枚举 $c$ 的后 8 位,如果解密的 $m$ 满足可见字符的条件,那么可能就是 $m$
不过对 256 位的 $N$ 进行分解这个时间是一个玄学的东西,需要挂着跑一阵子。
枚举 $N$ 的代码:
1 | from tqdm import trange |
得到 $N$ 以及分解:
1 | N_ = 55208723145458976481271800608918815438075571763947979755496510859604544396613 |
继续枚举可能的加密指数 $e$ 和密文 $c$,并对解出来的明文 $m$ 作检验:
1 | from tqdm import trange |
并补上 flag 的格式,得到 flag 为:
1 | CCTF{6oRYGy&Dc$G2ZS} |
Blue Office
题目描述
题目基于流密钥。
题目先将流密钥 d
作 reseed
变换,再将明文 msg
的第 c
个字节和密钥 d
作异或生成密文:
1 | while c < l: |
reseed
变换实现如下:
1 | def reseed(s): |
给密文 enc
,试恢复明文 msg
。
我的解答
因为这里 d
实际被拿去作异或的部分只有第 16-23 位,而且 reseed
函数是线性的,所以整个系统关于 d
模 $2^{24}$ 是等价的。
所以只需枚举初始随机数 d
在 $[0, 2^{24})$ 范围内,然后判断明文 msg
是否均为可见字符即可。
代码如下:
1 | enc = b'b0cb631639f8a5ab20ff7385926383f89a71bbc4ed2d57142e05f39d434fce' |
解得 flag 为:
1 | CCTF{__B4ck_0r!F1c3__C1pHeR_!!} |