Misay's blog

Back

  • LSFR_Signin#

原题代码如下

from Crypto.Util.number import *
flag = b"whuctf{}"

flag = list(bin(bytes_to_long(flag))[2:])
assert(len(flag) == 255)

for i in range(len(flag)):
    flag[i] = int(flag[i])

for i in range(2025):
    flag.append(flag[i] ^ flag[i+20] ^ flag[i+25] ^ flag[i+250] ^ flag[-1])
    print(flag[-1], end="")
python

已知flag为255位,对于线性寄存器,根据i i+20 i+25 i+250 以及最后一位就能解出下一位,于是我们从第256位开始往后,有

flagi=flagi+20xorflagi+25xorflagi+250xorflagi+254xorflagi+256flag_i = flag_{i+20} xor flag_{i+25}xorflag_{i+250}xorflag_{i+254}xorflag_{i+256}

i取0到254,而我们已知2552280位,取255510位来解密就可以,脚本如下

  • RSAASR#

题干:

p和q二进制颠倒,采用爆破的思路,同时估计p q的范围,并且每次取p q的低k位(k为已经爆破出来的位)相乘,对结果取低k位,如果和n的低k位相同就继续,不同就剪去,代码如下,板子参照博客:Crypto趣题-剪枝 | 糖醋小鸡块的blog (tangcuxiaojikuai.xyz) ↗

  • *ez_lattice#

格密码相关,题干

简单分析可知分为两个部分,前半段是

b=kp+aiXib = kp+a_iX_i

本质是两个方程,这里有两种方法可以解决,都写一下

  • 1.根据两个方程造3 * 3的格子

    将上式展开,有

b=kp+a1X1b = kp + a_1 X_1 b=kp+a2X2b = kp + a_2 X_2

观察式子,不难得到矩阵运算式

(a1,a2,k)(10X101X200p)=(a1,a2,2b)(a_1,a_2,k)\begin{pmatrix} 1&0&X_1\\ 0&1&X_2\\ 0&0&p \end{pmatrix}=(a_1,a_2,2b)

接下来运用Hermite 上界为3p13\sqrt{3} p^{\frac13} ,大概是170位,右边的目标向量长度取决于a1,a2,b但肯定不会超过上界,我们可以先解一下看看

  • *pollard&williams#

基于pollard p-1和willams p+1两个大数分解算法

  • 1

    可知(p1−1)∣2n2(p_1-1) | 2n_2 由欧拉定理不难得到

22n2=2p1−1≡1  (modp1)2^{2n_2} = 2^{p_1-1} \equiv 1 \;(modp_1) p1  ∣  22n2−1 p_1\;|\;2^{2n_2}-1 p1=gcd(n1,22n2−1)p_1 = gcd(n_1,2^{2n_2-1})

直接算就行,代码如下

p1 = gmpy2.gcd(gmpy2.powmod(3, 2 * n2, n1) - 1, n1)
p2 = (p1 - 1) // 2
q1 = n1 // p1
q2 = n2 // p2
python
  • 2

    证明比较繁琐,先给出结论

    对于如下Lucas序列

V0=2    ;V1=A    ;Vn=AVn−1−Vn−2V_0 = 2\;\;;V_1 = A\;\;;V_n = AV_{n-1}-V_{n-2}

令D=A2−4D = A^2-4,若 p∤Dp\nmid D 有

p  ∣gcd(Vm−2,n)    ;p∣n    ;p−(Dp)  ∣  m    p\;| gcd(V_m-2,n)\;\;;p|n\;\;;p-(\frac D p )\;|\;m\;\;

思路就是,枚举A,1到15往往就够了,找到一个D不是p的二次剩余,也就是有p+1∣mp+1 | m

这里我们容易发现p1+1∣2n2p_1+1 | 2n_2,那么2n22n_2就是我们代入的m,接下来用我们枚举的A,找到的m来迭代运算lucas序列,求出来之后做两次gcd即可,最终

p1=gcd(gcd(V2n2  −  2,n1)  ,  n1)p_1 = gcd(gcd(V_{2n_2}\;-\;2,n_1)\;,\;n_1)

脚本在这里

def lucas_v(a,n):
    v0 = 2
    v1 = a
    R = ZZ 
    M = matrix(R,[[a,-1],[1,0]]) 
    v = M**(n-1) * vector(R,[v1,v0])
    return v[0]

for a in range(2,10):
    p3 = ZZ(gcd(lucas_v(a,2 * n4) - 2, n3))
    if 1< p3 < n3:
        break
p4 = (p3+1) // 2
q3 = n3 // p3
q4 = n4 // p4     
python
  • *seista’s revenge#

ez_lattice的part2稍微改了一下上来的,求a0,a1就可以了 这里有

aiXi≡1    modpa_iX_i \equiv 1\;\;mod p

其实不论b怎么样,我们都是用类似的方法求解

  • onlyAES#

交互题,代码如下

可见就是选择一种加密方式,再输入data数据,进行加密,注意这里的异或方法

对于第一种加密方式,输入全0的data块,那么实际上就是对flag进行了一次加密,不妨设flag是两个块+3个字符,那么容易有填充后得到flag0 flag1 Pad(flag2)这三个块,加密后得到encflag0 encflag1 encPad(flag2)三个块,截取前面两个

对于第二种加密方式是先将flag拼接在输入的data后方,再16字节分块,加密之后用一个C存储各个块异或的结果,如果我们输入了Pad(flag2),那么Pad之后会得到 Pad(flag2) flag0 flag1 Pad(flag2) 加密得到encPad(flag2) encflag0 encflag1 encPad(flag2),异或的结果就会是encflag0 XOR encflag1,然而这个我们是知道的,由第一次加密的结果,也就是说,我们穷举flag3所有的可能,一共也就27^3种,pad之后传入,只要输出的值为encflag1 XOR encflag0 那么我们就构造对了

接下来,我们应用这里的异或性质,构造比flag长1位的0串,那么flag0的第一位会复制到flag3的末尾,这时候如法炮制爆破现在的flag3就可以了,能在27次以内搞出来,以此循环即可,稍微注意下当爆破位数超过16时候的块构造

贴一下出题人keaton师傅的题解


碎碎念#

第一次正式接触比赛中的密码题,和校内23 24级的其他师傅有着不小的差距,也是逐渐意识到了各类板子,思路的重要性,写复盘的初衷也是希望以后或许用得到其中的思路&脚本,不过python代码能力确实还得好好练习呢,加油

WHUCTF2025
https://www.zt2misay2.cn/blog/whuctf2025
Author Misay
Published at 2025年4月14日