Misay's blog

Back

1.reed#

输一个seed进去,然后影响prng的状态,再生成系数a,b,用ci≡ami+b  mod  pc_i\equiv am_i+b\;mod\;p这里的ci,p都知道,实际上没什么必要管prng的生成逻辑,可知mi的取值只有所有数字和大小写字母,也就是62个取值可能,我们找两组不一样的ci,cj有

ci≡ami+b  mod  pc_i\equiv am_i+b\;mod\;p\\ cj≡amj+b  modpc_j\equiv am_j+b\;modp\\ 做差有(ci−cj)≡a(mi−mj)  mod  p做差有(c_i-c_j)\equiv a(m_i-m_j)\;mod\;p

穷举所有可能的mi,mj的取值,也就3600多种,可以解出

a≡(ci−cj)(mi−mj)−1  mod  pa\equiv (c_i-c_j)(m_i-m_j)^{-1}\;mod\;p\\

再代入可得

b≡ci−mi(ci−cj)(mi−mj)−1  mod  pb\equiv c_i-m_i(c_i-c_j)(m_i-m_j)^{-1}\;mod\;p\\

这下我们就得到了a,b再对后面的所有已知的c,可得

mk≡(ck−b)a−1  mod  pm_k\equiv(c_k-b)a^{-1}\;mod\;p\\

解出所有可能的m_k,看看是不是在0~61内,脚本如下

不过这貌似是出题人的非预期解,等有师傅分享了关于PRNG不动点的解法的话再补充吧

2.Complex-signin#

基于二元复数的RSA运算,题目给出了m实、虚部的高位,同时e的数值为3,可以考虑设低位,展开成多项式,去打二元coppersmith,推导如下

Rem=mh[0]+x  ;Imm=mh[1]+yRe_{m}=mh[0]+x\;;Im_m=mh[1]+y\\ C≡(mh[0]+x+(mh[1]+y)i)3  mod  nC\equiv(mh[0]+x+(mh[1]+y)i)^3\;mod\;n\\ ReC≡(mh[0]+x)3−3(mh[0]+x)(mh[1]+y)2  mod  nRe_C\equiv (mh[0]+x)^3-3(mh[0]+x)(mh[1]+y)^2\;mod\;n\\ ImC≡−(mh[1]+y)3+3(mh[0]+x)2(mh[1]+y)  mod  nIm_C\equiv-(mh[1]+y)^3+3(mh[0]+x)^2(mh[1]+y)\;mod\;n\\

只有x,y未知,这里给一个二元copper的脚本,感谢(defund/coppersmith: Coppersmith’s method for multivariate polynomials (github.com) ↗)和使用轮子的exp

exp

3.division#

题目给了容器的server

考点主要是python的PRFrandom 其中使用的是MT19937算法,在输出比特超过624*32位时就能被预测,参考blogs([CTF/randcrack]python随机数预测模块分析及改进方案_random.getrandbits(32)-CSDN博客 ↗)

博客师傅给了个很好用的轮子,思路也很清楚,选择1,输入1,就能获得这次生成的随机数,那么输624次,再选择2,输入预测的值就Ok了,直接上exp

4.choice#

这道也是考察的MT19937的内容,题干

from Crypto.Util.number import bytes_to_long
from random import Random
from secret import flag

assert flag.startswith(b'XYCTF{') and flag.endswith(b'}')
flag = flag[6:-1]

msg = bytes_to_long(flag)
rand = Random()
test = bytes([i for i in range(255, -1, -1)]) #256个字符 ascii
print(test)
open('output.py', 'w').write(f'enc = {msg ^ rand.getrandbits(msg.bit_length())}\nr = {[rand.choice(test) for _ in range(2496)]}')
    
# 先getrandbits的用了一次
# 再存在choice test 即选择的部分
python

不过这里是生成了2496个8bit的数字,可知2496*8 = 624 *32 bit数是够用的,沿用上面博客师傅的轮子,就可以破解伪随机生成器,但是这里flag的长度未知,爆破就行了,exp如下

5.*复复复复数#

首先,定义了一个四元数的运算,首先这里的p,q,r都是可以求的,解线性方程和四元数求模逆都是可行的方法,

q−1=q∗∣q∣2q^{-1}=\frac{q^*}{|q|^2}

part1 求pqr

F=GF(P)
hint = [F(x) for x in [375413371936, 452903063925, 418564633198, 452841062207]]
H = matrix(F,[
    [hint[0],-hint[1],-hint[2],-hint[3]],
    [hint[1],hint[0],-hint[3],hint[2]],
    [hint[2],hint[3],hint[0],-hint[1]],
    [hint[3],-hint[2],hint[1],hint[0]]
])

g = vector(GF(P),[gift[0],gift[1],gift[2],gift[3]])
v = H.solve_right(g)
p=int(v[1])
q=int(v[2])
r=int(v[3])
#解方程
python
  • part2 分析RSA

这里e=65547=9*7283 且算一下就能发现e phi不互素,gcd(e,ϕ)=9gcd(e,\phi)=9,然后这里模指不互素的原理还没有搞太明白,先贴一下exp,晚一些再补充一下

XYCTF2025
https://www.zt2misay2.cn/blog/xyctf2025
Author Misay
Published at 2025年4月19日