2023 陕西省大学生网络安全技能大赛 --- 高职组 Crypto ezmath

文章目录

      • 题目
      • 解题过程

题目

from Crypto.Util.number import *
from secret import y,a,b
flag=b'flag{}'
l = len(flag)
m1, m2 = flag[: l // 2], flag[l // 2:]
 
x = bytes_to_long(m1)
c = bytes_to_long(m2)
 
 
assert (x**2+1)*(y**2+1)-2*(x+y)*(x*y+1)==gift-4*x*y
 
'''
4*b**6-2*a**3+3*a*c = 5530346600323339885232820545798418499625132786869393636420197124606005490080520377416491241780814130580634432917029242402389788321303783584093278303358433856193188224687198306898483386282930376793701825481151610363517100498626293248
b**5+6*c**3+2*a*b*c = 2954615125181706551778975245956905163867066802909029011696374372323491135608656194836008189370779030694961333309906927038863656553775849501064217981385517049591593537202663734020724898058374757
3*a**3-3*a*c-3*b**6 = -5530346600323339885232820545798418499625132786869393636420197035566805062067013375355549877479840082835466426039196029766850808080041755202912921908993556467660683726675045317331817898077228454499973287809035537190311008571468738911
gift=18150211062729351455633481905222609221074385988870569666008228964942099019268333450225373082700058568213818917267125668494844006433076192398714708653476096
'''


解题过程

已知
( x 2 + 1 ) ( y 2 + 1 ) − 2 ( x + y ) ∗ ( x ∗ y + 1 ) = g i f t − 4 x y (x^2+1)(y^2+1)-2(x+y)*(x*y+1)=gift-4xy (x2+1)(y2+1)2(x+y)(xy+1)=gift4xy
⇒ g i f t = ( x 2 + 1 ) ( y 2 + 1 ) − 2 ( x + y ) ∗ ( x ∗ y + 1 ) + 4 x y \Rightarrow gift = (x^2+1)(y^2+1)-2(x+y)*(x*y+1)+4xy gift=(x2+1)(y2+1)2(x+y)(xy+1)+4xy
⇒ g i f t = x 2 y 2 + x 2 + y 2 + 1 − 2 ( x 2 y + x y 2 + x + y ) + 4 x y \Rightarrow gift = x^2y^2+x^2+y^2+1-2(x^2y+xy^2+x+y)+4xy gift=x2y2+x2+y2+12(x2y+xy2+x+y)+4xy
⇒ g i f t = x 2 y 2 + x 2 + y 2 − 2 x 2 y − 2 x y 2 − 2 x − 2 y + 4 x y + 1 \Rightarrow gift = x^2y^2+x^2+y^2-2x^2y-2xy^2-2x-2y+4xy+1 gift=x2y2+x2+y22x2y2xy22x2y+4xy+1
⇒ g i f t = x 2 ( y 2 − 2 y + 1 ) − 2 x ( y 2 − 2 y + 1 ) + ( y 2 − 2 y + 1 ) \Rightarrow gift = x^2(y^2-2y+1)-2x(y^2-2y+1)+(y^2-2y+1) gift=x2(y22y+1)2x(y22y+1)+(y22y+1)
⇒ g i f t = x 2 ( y − 1 ) 2 − 2 x ( y − 1 ) 2 + ( y − 1 ) 2 \Rightarrow gift = x^2(y-1)^2-2x(y-1)^2+(y-1)^2 gift=x2(y1)22x(y1)2+(y1)2
⇒ g i f t = ( x 2 − 2 x + 1 ) ( y − 1 ) 2 \Rightarrow gift = (x^2-2x+1)(y-1)^2 gift=(x22x+1)(y1)2
⇒ g i f t = ( x − 1 ) 2 ( y − 1 ) 2 \Rightarrow gift = (x-1)^2(y-1)^2 gift=(x1)2(y1)2

开根号得到 g i f t = ( x − 1 ) ( y − 1 ) \sqrt{gift} = (x-1)(y-1) gift =(x1)(y1)
对于fac = x*y这类情况,我们可以先分解fac,再求它的所有因子,然后遍历符合条件的因子即可

gift=18150211062729351455633481905222609221074385988870569666008228964942099019268333450225373082700058568213818917267125668494844006433076192398714708653476096
x_y = gmpy2.iroot(gift,2)[0]
fac = factor(x_y)
ff = sum([[i] * t for i, t in fac], [])
l = len(ff)
for i in range(1, 1 << l):
    aim = bin(i)[2:].rjust(l, '0')
    tmp = 1
    for k, j in enumerate(aim):
        if int(j) != 0:
            tmp *= ff[k] * int(j)
    x = tmp+1
    flag1 = long_to_bytes(x)
    if b'flag' in flag1:
        print(flag1)
        break

后来发现sage有现成的函数divisors可以直接求所有的因子,真是太方便辣
在这里插入图片描述
在这里插入图片描述

gift=18150211062729351455633481905222609221074385988870569666008228964942099019268333450225373082700058568213818917267125668494844006433076192398714708653476096
x_y = gmpy2.iroot(gift,2)[0]
div = divisors(x_y)
for i in div:
    flag1 = long_to_bytes(int(i+1))
    if b'flag' in flag1:
        print(flag1)
        break

得到第一部分flag

flag{e837f64d-a556-41

接下来给了三个等式,每一个等式也包含了a,b,c 3个变量,其中c是flag2,为我们所求
这里给两种思路
1.利用sympy库构造方程组去解出a、b、c

from sympy import *

a,b,c = symbols("a b c")
eq = [4*b**6-2*a**3+3*a*c-5530346600323339885232820545798418499625132786869393636420197124606005490080520377416491241780814130580634432917029242402389788321303783584093278303358433856193188224687198306898483386282930376793701825481151610363517100498626293248,b**5+6*c**3+2*a*b*c-2954615125181706551778975245956905163867066802909029011696374372323491135608656194836008189370779030694961333309906927038863656553775849501064217981385517049591593537202663734020724898058374757,3*a**3-3*a*c-3*b**6+5530346600323339885232820545798418499625132786869393636420197035566805062067013375355549877479840082835466426039196029766850808080041755202912921908993556467660683726675045317331817898077228454499973287809035537190311008571468738911]
result = list(nonlinsolve(eq, [a,b,c]))
print(result)

这种方式的话,方程解是能解,但是计算过程相当的慢,大概要40分钟左右。
2023 陕西省大学生网络安全技能大赛 --- 高职组 Crypto ezmath_第1张图片

result = [(-97319611529501810510904538298668204056042623868316550440771307534558768612892, 311960913464334198969500852124413736815, 78042915855360415267901257437397052556186367517053)]

计算出 c = 78042915855360415267901257437397052556186367517053

2.使用resultant消元法,通过消元把多项式方程组转化为一个变量只有c的形式,然后再构造一个新的一元多项式,最后解方程即可得到c。
PS:la佬tql辣,orz!!!

#sage
R.<a,b,c> = PolynomialRing(ZZ)
f1 = 4*b**6-2*a**3+3*a*c-5530346600323339885232820545798418499625132786869393636420197124606005490080520377416491241780814130580634432917029242402389788321303783584093278303358433856193188224687198306898483386282930376793701825481151610363517100498626293248
f2 = b**5+6*c**3+2*a*b*c-2954615125181706551778975245956905163867066802909029011696374372323491135608656194836008189370779030694961333309906927038863656553775849501064217981385517049591593537202663734020724898058374757
f3 = 3*a**3-3*a*c-3*b**6+5530346600323339885232820545798418499625132786869393636420197035566805062067013375355549877479840082835466426039196029766850808080041755202912921908993556467660683726675045317331817898077228454499973287809035537190311008571468738911

def resultant(f1, f2, var):
    return Matrix.determinant(f1.sylvester_matrix(f2, var))
 
 
h1 = resultant(f1, f2, a) #b,c
h2 = resultant(f1, f3, a) #b,c
h3 = resultant(h1, h2, b) #c
m2 = h3.univariate_polynomial().roots()[0][0]
flag2 = long_to_bytes(int(m2))
print(flag2)

得到flag2

5f-af01-c883e3c8d9ca}

完整解题代码:

#sage
from Crypto.Util.number import *
import gmpy2
from sage.matrix.matrix2 import Matrix 

gift=18150211062729351455633481905222609221074385988870569666008228964942099019268333450225373082700058568213818917267125668494844006433076192398714708653476096
x_y = gmpy2.iroot(gift,2)[0]
div = divisors(x_y)
for i in div:
    flag1 = long_to_bytes(int(i+1))
    if b'flag' in flag1:
        break

R.<a,b,c> = PolynomialRing(ZZ)
f1 = 4*b**6-2*a**3+3*a*c-5530346600323339885232820545798418499625132786869393636420197124606005490080520377416491241780814130580634432917029242402389788321303783584093278303358433856193188224687198306898483386282930376793701825481151610363517100498626293248
f2 = b**5+6*c**3+2*a*b*c-2954615125181706551778975245956905163867066802909029011696374372323491135608656194836008189370779030694961333309906927038863656553775849501064217981385517049591593537202663734020724898058374757
f3 = 3*a**3-3*a*c-3*b**6+5530346600323339885232820545798418499625132786869393636420197035566805062067013375355549877479840082835466426039196029766850808080041755202912921908993556467660683726675045317331817898077228454499973287809035537190311008571468738911

def resultant(f1, f2, var):
    return Matrix.determinant(f1.sylvester_matrix(f2, var))
 
h1 = resultant(f1, f2, a) #b,c
h2 = resultant(f1, f3, a) #b,c
h3 = resultant(h1, h2, b) #c
m2 = h3.univariate_polynomial().roots()[0][0]
flag2 = long_to_bytes(int(m2))
print(flag1+flag2)

flag:

flag{e837f64d-a556-415f-af01-c883e3c8d9ca}

【天底下单相思的痴情,好像都是那么一文不值,可若是值钱,又何必单相思呢。】

你可能感兴趣的:(CTF,python,开发语言)