from secrets import randbelow
g = 2
y = pow(g, k, p)
def gogogo():
print("Another chance:")
t = int(input('t = '))
c = randbelow(p)
print("Here is my real challenge:")
print(f'c = {c}')
print("Give me your answer.")
s = int(input('s = '))
return pow(g, s, p) == t * pow(y, c, p) % p
def dododo():
print("Here is my gift for National's Day!")
t = pow(g, r, p)
print(f't = {t}')
print("What do you want?")
c = int(input('c = '))
s = (r + c*k) % (p - 1)
print("This is another gift:")
print(f's = {s}')
print("Happy National's Day!")
print("Don't play CTF these days.")
print("Just go out and play~")
print("Don't finish this chall,")
print("although I should tell you that")
print(f"p = {p}")
dododo()
if gogogo():
print(f"FUIYOH! You can get flag: {flag}")
print("and then go out and play!")
else:
print("HAIYAA! You are wrong. Just go out and play!")
首先看到已知的就有g,p和t了
其次是输入一个c输出一个s但输出s的等式中有未知量r,k
先令c=0得到
s = r mod (p-1)
p和s已知可求出r=214。再者求k
我们发现不同的c输出的s不同,两次输入不同的c(最简便就是c=1,2)输出不同s得到两条方程
s1=(r+k) mod (p-1)
s2=(r+2*k) mod (p-1)
下来就是解方程的问题
对用同一个k其他量都已知,可以利用
富兰克林-赖特 相关消息攻击
n = 7426377248993167316584923743580751815847513886893496504970559106442393387122038966319447136976391605077588023129643053040905007917383268935927643195922652
s1 = 5054994445577641800727381711603362275848730863034576085807905759367072227717066372846972765594223115536930251313835178715503900402305679456937779756304265
s2 = 2683611642162116284869839679625972735849947839175655666645252412291751068312093779374498394212054625996272479498027304390102792887228089977947916316685664
e = 1
R.<x> = PolynomialRing(Zmod(n))
g1 = (x+214)^e - s1
g2 = (2*x+214)^e - s2
def myGcd(x, y):
if y == 0:
return x.monic()
return myGcd(y, x%y)
v = myGcd(g2, g1)
M = n - v.coefficients()[0]
assert g1(M) == 0
print(hex(M))
改编于这位大佬的代码,具体可参考:
脚本在sage中运行,在线sage网站:
转10进制得k=5054994445577641800727381711603362275848730863034576085807905759367072227717066372846972765594223115536930251313835178715503900402305679456937779756304051
另外,我们知道k和p在靶机中是不会改变的
到此我们就求出了y的值
再看到gogogo子函数中,先是输入一个t然后生成一个int型的随机数c
最后输入s然后返回判断等式是否成立,成立则返回flag
return pow(g, s, p) == t * pow(y, c, p) % p
等式中有t和s要我们输入
t影响着s的值,所以令t=1使得运算更简便
这样就有pow(g,s,p)==pow(y,c,p)
而y=pow(g,k,p)
我们利用同余的性质
这样就有:s=c*k
c和k已知
将s在靶机中输入得出flag
ctfshow{41d15e13-2f1a-460e-821c-75327dfc3cde}