Misay's blog

Back

Above#

Team : Dawn-DAMN

Score : 4733

Rank : 13

Crypto Solved 2 of 3

lost LFSR key#

task.py

LFSR的题 关键洞在

key = generator.get_myRNG_randbits(64*8) 
c = key ^ bytes_to_long(flag)            
py

flag是给定的64字节 与key的8*64bits重合 而且flag的内部全是可视ASCII 意味着每8个bits中的最高位都一定是0 那我们就得到了64个已知的信息Bit

也就是说C8(k−1)C_{8(k-1)}就是我们的key 也就是LFSR的输出 而LFSR的运算可以转化为GF(2)GF(2)上的线性运算 所以说64个已知位结合我们已知的64位mask ,可以构造64组方程 足矣解出我们初始的64位State 也就是Seed 获得Seed之后直接解出key 然后求flag即可

exp

Two_Examples#

task.py

很经典的LWE问题了 choice的选取也非常小 在WMCTF的Lwe出过比这个更近一步的 我们直接参考鸡块师傅的板子 LWE | 糖醋小鸡块的blog (tangcuxiaojikuai.xyz) ↗

exp

Serration#

main.py

题目构造了一个基于蒙哥马利额外约简的RSA靶机 在生成1024位的p q后要求你进行选择明文攻击 以RSA-CRT的形式对传入的m进行加密 随后告知你有关加密过程中某一个模数因子p的侧信道

d[j]=(lp.code_map[i][j]['total_time'],lp.code_map[i][j]['nhits'])
py

参考Paper https://link.springer.com/chapter/10.1007/3-540-44499-8_8 ↗

关键漏洞在我们的

def mon_pro(self, a_n, b_n):
    t = a_n * b_n
    u = (t + (t * self.n_inv % self.r) * self.n) >> self.k
    if u > self.n:
        u -= self.n
    return u
py

我们梳理一下

T=an×bnT=a_n \times b_n m≡T×n−1mod  Rm\equiv T\times n^{-1}\mod R u=T+m×nRu=\frac{T+m\times n}{R}

随后再考虑对uu进行约简 ,我们可以控制的是输入的mm ,后续的ana_n bnb_n都是由第一次的计算结果递推而来,同时由于

P=Montgomery(p,bits)
Q=Montgomery(q,bits)
py

我们实际上用的是模数p    qp\;\;q 所以说我们很难做到通过控制的mm来直接简单的估计最终进行约简比较的uu的范围 这计算很复杂 但是我们侧信道主要的时间开销差异也就是在

if u > self.n:
	u -= self.n
py

而我们获得的total_time统计是混在一起的 所以说第一步我们需要把这里的Reduction_Line找出来 也就是剥离其他无关操作的影响

我们传入一个很小的数 0就不错 然后再一个很大的数 建议和nn的数量级接近 这样我们就能找到对uu大小最敏感的这一行的取值

剥离了噪音的影响 接下来我们的每次选择明文攻击都能直接揭示输入明文和其中模数之间的大小关系

也就是

papprox=pguessed+2k×guessbitp_{approx}=p_{guessed}+2^k\times guessbit

guessbit为0或者1会对我们的papproxp_{approx}产生巨大的影响 从而在我们的约简行中产生巨大的开销变化 但是这里不能精确观察到每一位Bit对我们的数据的影响 但是可以通过反复的假设来确定某一位的比特 600次轮询足够我们获取到超过550位的比特信息 剩下的地位交给CopperSmith

exp

All Done

DASCTF2025-Fall
https://www.zt2misay2.cn/blog/dasctf2025-fall
Author Misay
Published at 2025年12月9日