owo
做出了两道题,学到很多干货
sign in the ca7s 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 from Crypto.Util.number import bytes_to_longfrom hashlib import md5import osFLAG = os.environ.get("FLAG" , "flag{**redacted**}" ) E = EllipticCurve(GF(0x1337_ca7_eae368ff5d702e6067aaaa77ca_ca7_1337 ), [0 , 3 ]) G, n = E(1 , 2 ), E.order() def sign (priv, ctx, msg ): k = bytes_to_long(ctx + md5(str (priv).encode() + msg).digest()) z = bytes_to_long(md5(ctx + msg).digest()) r = int ((k * G).x()) % n s = (pow (k, -1 , n) * (z + r * priv)) % n return r, s def verify (pub, ctx, msg, sig ): z = bytes_to_long(md5(ctx + msg).digest()) r, s = sig if 0 < r < n and 0 < s < n: return r == int ((pow (s, -1 , n) * (z * G + r * pub)).x()) % n def chall (level, flag ): priv = randint(1 , n - 1 ) pub = priv * G msg = os.urandom(64 ) print (f"=== level {level} ===" ) for _ in range (catalan_number(level)): ctx = bytes .fromhex(input ('context: ' )) r, s = sign(priv, ctx, msg) assert verify(pub, ctx, msg, (r, s)) if level <= 1 : print ('message:' , msg.hex ()) if level <= 2 : print ('sign:' , r) if level <= 3 : print ('ature:' , s) r, s = map (int , input ('signature: ' ).split()) assert verify(pub, b'n1junior_2025' , f'cat /flag{level} ' .encode(), (r, s)) print (f'flag{level} :' , flag) if __name__ == "__main__" : chall(0 , "💧" ) chall(1 , "🐱" ) chall(2 , FLAG)
分析题目代码不难发现大概流程是有三个level,逐步通过来获取最后的flag,这里的level0和1是一样的所以我们一起来分析。
对于level0和1,会输出
1 2 3 if level <= 1 : print ('message:' , msg.hex ())if level <= 2 : print ('sign:' , r)if level <= 3 : print ('ature:' , s)
三个数据。
我们已经知道了r = (k*G).x() mod n
,是曲线上点的横坐标,而在而在椭圆曲线上,每个 x
对应最多 2 个点(kG).x()=r⟹kG=(r,y)或者(r,−y),又因为此时G很小为E(1, 2),
那么我们就可以直接E.lift_x(Integer(r))返回在椭圆曲线上的点然后.log(G)求椭圆曲线离散对数。那么ctx就无所谓了,直接空都行。
接下来分析level2,这里我们有两次交互机会,能拿到两对r,s。
服务端的签名函数是
1 2 3 4 5 k = bytes_to_long(ctx + md5(str (priv).encode() + msg).digest()) z = bytes_to_long(md5(ctx + msg).digest()) r = int ((k * G).x()) % n s = (k^{-1 } * (z + r * priv)) % n
此时我们有等式为$$s≡k^{−1}(z+r⋅priv)(modn)$$,同乘k再移一下项即可得到
$r_1⋅priv≡s_1k_1−z_1(modn)$,同理也就有
$r_2⋅priv≡s_2k_2−z_2(modn)$
两式相减
$(r_1−r_2)⋅priv≡(s_1k_1−s_2k_2)−(z_1−z_2)(modn)$
移项得到 $priv≡(s_1k_1−s_2k_2−(z_1−z_2))⋅(r_1−r_2)^{−1}(modn)$
对于z1和z2,我们需要利用哈希碰撞(工具为fastcoll)来找到两个md5值相同的ctx,并对其进行填充。我们知道
1 z = bytes_to_long(md5(ctx + msg).digest())
并且md5的处理是从前往后读取消息并不断更新内部值的,我们先对找到的ctx进行填充。因此 md5(t1_pad)
的输出就是“处理完 t1 并完成填充后的最终内部状态”。也就是说,当进行 md5(t1_pad + msg)
时,t1_pad
被当作“普通数据块”处理后,MD5 的内部状态在 t1_pad
处理完时等于 md5(t1_pad)
的状态,随后 MD5 继续把 msg
当作额外数据处理。所以我们这样就能使得z1=z2,就能消去一个未知数,从而求解priv,然后正常签名流程即可。
(由于这俩题本质是一样的,所以解题脚本一起贴到下一道题处)
sign the ca7s 就加了一个level3,这里直接来分析。level3的交互次数提高到了5次,并且只给了s,也就是说我们能拿到5个s的值,我们先来推导一下对应的方程组。这里同样是构造5个md5值相同的ctx使得z相同。具体如何生成只需要用fastcoll先生成一对,用其中之一作前缀继续生成,这么递推下去即可。
这里同样是有五个方程
$$s_1·k_1≡(z+r_1⋅priv)(modn)$$
$$s_2·k_2≡(z+r_2⋅priv)(modn)$$
$$s_3·k_3≡(z+r_3⋅priv)(modn)$$
$$s_4·k_4≡(z+r_4⋅priv)(modn)$$
$$s_5·k_5≡(z+r_5⋅priv)(modn)$$
显然未知数个数是远大于方程个数的,这里我们就要利用bytes_to_long操作的特点
bytes_to_long(ctx + md5(str(priv).encode() + msg))
等于 bytes_to_long(ctx) << (8*len(md5(str(priv).encode() + msg))) + bytes_to_long(md5(str(priv).encode() + msg))
。也就是说我们可以将k写为如下形式
$k_1=ctx_1·256^{16}+md5(priv+msg)$
$k_2=ctx_2·256^{16}+md5(priv+msg)$
$k_3=ctx_3·256^{16}+md5(priv+msg)$
$k_4=ctx_4·256^{16}+md5(priv+msg)$
$k_5=ctx_5·256^{16}+md5(priv+msg)$
那么显然k2,k3,k4,k5都可以用k1表示,也就是减少了四个未知数。那么我们想想还能不能继续减少呢。显然是可以的
就要用到我们在level0和1里用到的$r=(k·G)_x$,那么我们同时也可以定义(k·G)的纵坐标。用点加法代进去就可以把r2,r3,r4,r5用r1表示,有消去了四个未知数,但同时我们又引入了纵坐标,所以此时一共有5个未知数,和加上曲线方程的6个方程,是可以求解的。
我们直接用grobner基即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 from pwn import *from sage.all import *from gmpy2 import invertfrom Crypto.Util.number import *from hashlib import md5def Sign (priv, ctx, msg ): k = bytes_to_long(ctx + md5(str (priv).encode() + msg).digest()) z = bytes_to_long(md5(ctx + msg).digest()) r = int ((k * G).x()) % n s = (pow (k, -1 , n) * (z + r * priv)) % n return r, s def SmartAttack (P,Q,p ): E = P.curve() Eqp = EllipticCurve(Qp(p, 2 ), [ ZZ(t) + randint(0 ,p)*p for t in E.a_invariants() ]) P_Qps = Eqp.lift_x(ZZ(P.xy()[0 ]), all =True ) for P_Qp in P_Qps: if GF(p)(P_Qp.xy()[1 ]) == P.xy()[1 ]: break Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0 ]), all =True ) for Q_Qp in Q_Qps: if GF(p)(Q_Qp.xy()[1 ]) == Q.xy()[1 ]: break p_times_P = p*P_Qp p_times_Q = p*Q_Qp x_P,y_P = p_times_P.xy() x_Q,y_Q = p_times_Q.xy() phi_P = -(x_P/y_P) phi_Q = -(x_Q/y_Q) k = phi_Q/phi_P return ZZ(k) E = EllipticCurve(GF(0x1337_ca7_eae368ff5d702e6067aaaa77ca_ca7_1337 ), [0 , 3 ]) G, n = E(1 , 2 ), E.order() ch = 0 while True : try : ch += 1 io=process(['sage' , 'servercat.sage' ]) level = 1 time.sleep(1 ) io.recv() io.sendline(b"" ) msg = bytes .fromhex(io.recvline().split()[-1 ].decode()) r = eval (io.recvline().split()[-1 ].decode()) s = eval (io.recvline().split()[-1 ].decode()) z = bytes_to_long(md5(msg).digest()) """ k1 = (E.lift_x(Integer(r))).log(G) k2 = (-E.lift_x(Integer(r))).log(G) priv1 = ((s*k1-z)*invert(r, n))%n priv2 = ((s*k2-z)*invert(r, n))%n if bytes_to_long(md5(str(priv1).encode() + msg).digest()) != k1: priv = priv2 else: priv = priv1 """ k = (E.lift_x(Integer(r))).log(G) priv = ((s*k-z)*invert(r, n))%n r, s = Sign(priv, b'n1junior_2025' , f'cat /flag{level} ' .encode()) io.recv() io.sendline(b" " .join([str (r).encode(), str (s).encode()])) print (io.recvline().decode()) level += 1 def md5_pad (msg: bytes ) -> bytes : bit_len = len (msg) * 8 msg += b'\x80' while (len (msg) * 8 ) % 512 != 448 : msg += b'\x00' msg += bit_len.to_bytes(8 , 'little' ) return msg t1 = b'test\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\xf7\x8f\xebX\xbfx\xaf\xa5\x16\x11vy\x84"\x1e\xb2d7g\xde\x88\xc8\xa2 \xaay\xaa\x10\xac\xae&9\xf3\xf8\xe8\xc2k\xff\x90\xeb%\xbca\xf8\xa7\xa8\xbd\xd4X\x1f\x04\xad\xc2\x8dW8]sg_J\x10\xca=\xdd\xa6zr\xe0`\x0c\xc3;\x83\xa5P._,c%\xf3l+O\x17~v\xfd\xd3\xdfO!K\xc1nx\xc0\n\x84\xac\xa27\xad\x92\xef\xf8\r\xb3\x01G\x8a\xab\xd3Y\x8b)F_\x83\x03E\xfe\x93\xfe\xfa#' t2 = b'test\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\xf7\x8f\xebX\xbfx\xaf\xa5\x16\x11vy\x84"\x1e\xb2d7\xe7\xde\x88\xc8\xa2 \xaay\xaa\x10\xac\xae&9\xf3\xf8\xe8\xc2k\xff\x90\xeb%\xbca\xf8\'\xa9\xbd\xd4X\x1f\x04\xad\xc2\x8dW8]s\xe7_J\x10\xca=\xdd\xa6zr\xe0`\x0c\xc3;\x83\xa5P._,c%\xf3\xec+O\x17~v\xfd\xd3\xdfO!K\xc1nx\xc0\n\x84\xac\xa27\xad\x92\xef\xf8\r3\x01G\x8a\xab\xd3Y\x8b)F_\x83\x03E~\x93\xfe\xfa#' t1_pad = md5_pad(t1) t2_pad = md5_pad(t2) time.sleep(1 ) io.recv() io.sendline(t1_pad.hex ().encode()) r1 = eval (io.recvline().split()[-1 ].decode()) s1 = eval (io.recvline().split()[-1 ].decode()) io.sendline(t2_pad.hex ().encode()) r2 = eval (io.recvline().split()[-1 ].decode()) s2 = eval (io.recvline().split()[-1 ].decode()) k1 = (E.lift_x(Integer(r1))).log(G) k2 = (E.lift_x(Integer(r2))).log(G) priv = ((s1*k1-s2*k2)*invert(r1-r2, n))%n r, s = Sign(priv, b'n1junior_2025' , f'cat /flag{level} ' .encode()) io.recv() io.sendline(b" " .join([str (r).encode(), str (s).encode()])) flag = io.recvline().decode() print (flag) level += 1 ctx1=b'\xac}\xd44G\xb3\x83<\xa13\x9fS\xa6\xb6\x89c5\x9e\xd4\x802\t\xca\xdd\xfe\xbdzQ\xe9\xab\xbf\xb1\xfa\xf4\xcc\xe6:kG!\xeb\xd9H\xdcB\xf0*R\x8bz\x9da\xea\x02\xdfd6\x83dO\xa8\xab\xa1\x83\xa3 \x7f\x94\xf2\x98R\xaf\x95\x8b\xfc\x95\x8f\x1d\xb1\x19s\xf4\xcdZ\x13\xc0\x92O\x84-\xf0\xcf_`\xa5\xc1\xb5A\xb5\xea\xf4E\xa3\xf7\x97\x91\xe7\xb8s\xe6\xe0H\xa5\xfa&7\x0e8X\x0c\xcc\x82:\t\x92+S]\xb8V1f\xb2U\xc3\xb7\xd1Y\xbf\xc4\xd8Y\xf6uw\x10\x91u\x03\xf6\x8d\xfa.>Ae(\x8a\x0c\xa45\x1a\xc1\xbf|J\xb6\x17G\x10b\x1c\xd7\xc5\x94`\x98\xaa\xc7\t\x10\x15gT\x9e\x1e\x1a\xd4\x14\x8d\x05\xf8{\x7f\x81(\xc2{X\xa7#\xdb\x1d\r5\xdb\xb3\xed\xbaN\xaa\xb0\x11\xa6.\xee\xc9Z\xfe\xc8\xec\x07\xe2\xed\xf6\x8b\x9e\x9a\x06\x0b\xdfQ\xa8\x8cH\xb7\xa7PAfa\xc1WD\xb8\xce1.9\xd8P\xa0s\x00\xe5\xfdV\xb4t\xe4n\xc5\xd8\xf9[\xb6n{\x00\x96\xdd\xde\xbcQ\xb8[kMk\xc28\xaa;\x02\x8c\xc2"\xb8/\xa9\xc5\xe5\xee\x85MyG\xe2\xbd\x1a\xce\x0b\xd3dbs\x04\x1aY]\x84\x85\xe9\xb1\xa9\x01\x96\xfa}\xa0\xcf\xb5]\xe1`\xba\x98\x885\x17o$\xd5\x16M^8-\xca\xc9!\x86\x0e&\xd1\x1a~7\xec\x06\xdec6e\xa6X\xf4\xca\xe3\x8f\xaaj@w\xbehyj3\x13\xfa\x87\x869\xe6\xa1\xeb\xa2\x00\xdei:&\x05\xbc=\x989\xe4\x86\x1d\r\x869\x10\xe3gM\x19\xc1\xce\xdbE\xa1\x9fj\x9a\x98\x05\xb6\x7f9\xf9\x1d\x13\x03^\r\x0e\xe6Zj}\xfe\x0b\xeeRY\xcb\x97(\\\xe31\t\x18\xf2\xdf\x16\xccWA\x01\xf9.\x15\r\xfdK\x852\xc7\xc67$\x18[\\\x1e5\xb5\xdf\x19[$?\x03\xd2\x05&\x16\xea\xd1\x1a\xf6\xcb\xecG\xfe\xef\xcee\xc6\x95\xf2P\x08\x10x&Y\x0f\x8bd\xf1\xe84K\x886\xe27G\xfe\xd6\xd6\xb4\x9f/\\Y\xaa"\xc9\x1a\x85\xdc\xbc\x990\xd0{\x8f$\x06.h\xa5\xff\xdd\xdaIzB*\xbf\x00\x16y!\x8a>\x18\xa8\x1b\xc6\xc7\x07\\\x8a\x99\xba\xef\x03?\xf4\x1f~lK\xd5\x8c\xcdO\xdb\x1b\xaeu=\x9f\xef\x82\xee5\xf4\x9e\x00\xf7f\xc8#\xec\x9dw\x1f\x99\xb55\xfbE\x11\xa2\xce\x1dFo\xf8=\xe1U\xd1;\x14\xc5P\x1aY\xae\x0b+\xde\xdd[\x19\x83w\x91\xa4\xa1/\xebjT\x84\x8b\x8eP\xb2\xf8a\xea\x9c2\xdaPv\xbd\x89\xc3\xa9*\xf3\x07\x07\xd3\xdd|\x08z_!\xee\x11\xf0J\x9e\xfc\xf9\x1b\xc8\x9c&\xc2\xc5\x15*\x84b.B\xad\x9b=\r\xb9\xc9\xea\xa1\xf1U\xc7\xe7\xde\x1a\xde\x954;\xf1\xd2\x16yi\xdb\x8b%\xebK7dL\xe3\x92\xb7\t2\x190\x1a?\xf1\xf73\xf9=\xb5b$\x8d\xc60/9\x95\xef\xe7\x82\xdd\xf0H\xef\xa4\xd0\x16u}m\x1f?\xe9}\x15\x99&~OUr\x99\x0c.\xbe\xf9\\\xc1xm\xbd30\x16Z\xf9`*\x18\xbcI:[\x8a\t\xde\xdco\xa8\xe3\x81\xae\xe7.F\x94\xcbG\x179\x03#\xc6a\x0e:\x0eC%5,\x8e9\xb2\xed\xfa\xe0\xba\r\x08UG\xe8`Y&\n[n\xfcKQ`\xf7\xe6\xcc\xfb7-\x90\xd1\xca\xac:f\xb5\xd1\xd8\xfa\x8a\xca\x05\x9a\x13\xb9\x9f4C\xc7\xe0\xd5B\xaeA\xa5\x17F\x1e\x9e\xcbZ\x86;\xec\xc7\xfd\xe7\xf0Z\x1e\x98\x06\x8f\xe4\x83\x9a\x86A\xef\xb5\x04vlB_8\x1cP\xac]Y\xad\xd8\x19\x93Ygk\xb8\xa9G\xca[\xca"\xb4{\xc9K\xabf\xf9G\xb5\xc2\xc3\xe0\xc8\xc2s\x8b4\x8c-\x82C\x91S\xb66\x8c"\xc2\xe7\xc5\\. \xceg>dY4\x1e\x87)\x17+?\xb4\xd0h\xa5\x9bLnr\xf0<\x1dA\xb8\xe4\xf1\xf2?\xd3%\xa6\x8b\x1e\xbf\x82\x80M\xea\xbc.\xa8\xbc\xc5\xb1\x1b\xe6\x0e^\xcb\x1an9\xec\x86\xe2\xe5\xe8\x84\x9eW\x02\x92\xfb\x83\x8a\'<\x8f\xb2x\xe6\xea\xe11fn\xec!\xd48^%<\xc4Y\xfbn\xda' ctx2=b'\xac}\xd44G\xb3\x83<\xa13\x9fS\xa6\xb6\x89c5\x9e\xd4\x002\t\xca\xdd\xfe\xbdzQ\xe9\xab\xbf\xb1\xfa\xf4\xcc\xe6:kG!\xeb\xd9H\xdcBp+R\x8bz\x9da\xea\x02\xdfd6\x83d\xcf\xa8\xab\xa1\x83\xa3 \x7f\x94\xf2\x98R\xaf\x95\x8b\xfc\x95\x8f\x1d\xb1\x19s\xf4\xcd\xda\x13\xc0\x92O\x84-\xf0\xcf_`\xa5\xc1\xb5A\xb5\xea\xf4E\xa3\xf7\x97\x91\xe7\xb8sf\xe0H\xa5\xfa&7\x0e8X\x0c\xcc\x82:\x89\x92+S]\xb8V1f\xb2U\xc3\xb7\xd1Y\xbf\xc4\xd8Y\xf6uw\x10\x91u\x03\xf6\x8d\xfa.>Ae(\x8a\x0c\xa45\x1a\xc1\xbf|J\xb6\x17G\x10b\x1c\xd7\xc5\x94`\x98\xaa\xc7\t\x10\x15gT\x9e\x1e\x1a\xd4\x14\x8d\x05\xf8{\x7f\x81(\xc2{X\xa7#\xdb\x1d\r5\xdb\xb3\xed\xbaN\xaa\xb0\x11\xa6.\xee\xc9Z\xfe\xc8\xec\x07\xe2\xed\xf6\x8b\x9e\x9a\x06\x0b\xdfQ\xa8\x8cH\xb7\xa7PAfa\xc1WD\xb8\xce1.9\xd8P\xa0s\x00\xe5\xfdV\xb4t\xe4n\xc5\xd8\xf9[\xb6n{\x00\x96\xdd\xde\xbcQ\xb8\xdbkMk\xc28\xaa;\x02\x8c\xc2"\xb8/\xa9\xc5\xe5\xee\x85MyG\xe2\xbd\x1a\xce\x8b\xd2dbs\x04\x1aY]\x84\x85\xe9\xb1\xa9\x81\x96\xfa}\xa0\xcf\xb5]\xe1`\xba\x98\x885\x17o$\xd5\x16M^8-\xcaI!\x86\x0e&\xd1\x1a~7\xec\x06\xdec6e\xa6X\xf4\xca\xe3\x8f\xaaj@w\xbe\xe8yj3\x13\xfa\x87\x869\xe6\xa1\xeb\xa2\x00^i:&\x05\xbc=\x989\xe4\x86\x1d\r\x869\x10\xe3gM\x19\xc1\xce\xdbE\xa1\x9fj\x9a\x98\x05\xb6\x7f9\xf9\x1d\x13\x03^\r\x0e\xe6Zj}\xfe\x0b\xeeRY\xcb\x97(\\\xe31\t\x18\xf2\xdf\x16\xccWA\x01\xf9.\x15\r\xfdK\x852\xc7\xc67$\x18[\\\x1e5\xb5\xdf\x19[$?\x03\xd2\x05&\x16\xea\xd1\x1a\xf6\xcb\xecG\xfe\xef\xcee\xc6\x95\xf2P\x08\x10x&Y\x0f\x8bd\xf1\xe84K\x886\xe27G\xfe\xd6\xd6\xb4\x9f/\\Y\xaa"\xc9\x1a\x85\xdc\xbc\x990\xd0{\x8f$\x06.h\xa5\xff\xdd\xda\xc9zB*\xbf\x00\x16y!\x8a>\x18\xa8\x1b\xc6\xc7\x07\\\x8a\x99\xba\xef\x03?\xf4\x1f\xfelK\xd5\x8c\xcdO\xdb\x1b\xaeu=\x9f\xef\x02\xee5\xf4\x9e\x00\xf7f\xc8#\xec\x9dw\x1f\x99\xb55\xfbE\x11\xa2\xce\x1dF\xef\xf8=\xe1U\xd1;\x14\xc5P\x1aY\xae\x0b+\xde\xdd[\x19\x83w\x91\xa4\xa1/\xeb\xeaS\x84\x8b\x8eP\xb2\xf8a\xea\x9c2\xdaP\xf6\xbd\x89\xc3\xa9*\xf3\x07\x07\xd3\xdd|\x08z_!\xee\x11\xf0J\x9e\xfc\xf9\x1bH\x9c&\xc2\xc5\x15*\x84b.B\xad\x9b=\r\xb9\xc9\xea\xa1\xf1U\xc7\xe7\xde\x1a\xde\x155;\xf1\xd2\x16yi\xdb\x8b%\xebK7\xe4L\xe3\x92\xb7\t2\x190\x1a?\xf1\xf73\xf9=\xb5b$\x8d\xc60/9\x15\xef\xe7\x82\xdd\xf0H\xef\xa4\xd0\x16u}m\x1f?\xe9}\x15\x99&~OUr\x99\x8c-\xbe\xf9\\\xc1xm\xbd30\x16Z\xf9\xe0*\x18\xbcI:[\x8a\t\xde\xdco\xa8\xe3\x81\xae\xe7.F\x94\xcbG\x179\x03#\xc6a\x0e:\x0eC%5,\x8e9\xb2\xed\xfa\xe0\xba\r\x08UG\xe8`Y&\n[n\xfcKQ`\xf7\xe6\xcc\xfb7-\x90\xd1\xca\xac:f\xb5\xd1\xd8\xfa\x8a\xca\x05\x9a\x13\xb9\x9f4C\xc7\xe0\xd5B\xaeA\xa5\x17F\x1e\x9e\xcbZ\x86;\xec\xc7\xfd\xe7\xf0Z\x1e\x98\x06\x8f\xe4\x83\x9a\x86A\xef\xb5\x04vlB_8\x1cP\xac]Y\xad\xd8\x19\x93Ygk\xb8\xa9G\xca[\xca"\xb4{\xc9K\xabf\xf9G\xb5\xc2\xc3\xe0\xc8Bs\x8b4\x8c-\x82C\x91S\xb66\x8c"\xc2\xe7\xc5\\. \xceg>dY4\x9e\x86)\x17+?\xb4\xd0h\xa5\x9bLnrp<\x1dA\xb8\xe4\xf1\xf2?\xd3%\xa6\x8b\x1e\xbf\x82\x80M\xea\xbc.\xa8\xbc\xc51\x1b\xe6\x0e^\xcb\x1an9\xec\x86\xe2\xe5\xe8\x84\x9eW\x02\x92\xfb\x83\x8a\'<\x8f\xb2\xf8\xe6\xea\xe11fn\xec!\xd48^%<DY\xfbn\xda' ctx3=b'\xac}\xd44G\xb3\x83<\xa13\x9fS\xa6\xb6\x89c5\x9e\xd4\x002\t\xca\xdd\xfe\xbdzQ\xe9\xab\xbf\xb1\xfa\xf4\xcc\xe6:kG!\xeb\xd9H\xdcBp+R\x8bz\x9da\xea\x02\xdfd6\x83d\xcf\xa8\xab\xa1\x83\xa3 \x7f\x94\xf2\x98R\xaf\x95\x8b\xfc\x95\x8f\x1d\xb1\x19s\xf4\xcd\xda\x13\xc0\x92O\x84-\xf0\xcf_`\xa5\xc1\xb5A\xb5\xea\xf4E\xa3\xf7\x97\x91\xe7\xb8sf\xe0H\xa5\xfa&7\x0e8X\x0c\xcc\x82:\x89\x92+S]\xb8V1f\xb2U\xc3\xb7\xd1Y\xbf\xc4\xd8Y\xf6uw\x10\x91u\x03\xf6\x8d\xfa.>Ae(\x8a\x0c\xa45\x1a\xc1\xbf|J\xb6\x17G\x10b\x1c\xd7\xc5\x94`\x98\xaa\xc7\t\x10\x15gT\x9e\x1e\x1a\xd4\x14\x8d\x05\xf8{\x7f\x81(\xc2{X\xa7#\xdb\x1d\r5\xdb\xb3\xed\xbaN\xaa\xb0\x11\xa6.\xee\xc9Z\xfe\xc8\xec\x07\xe2\xed\xf6\x8b\x9e\x9a\x06\x0b\xdfQ\xa8\x8cH\xb7\xa7PAfa\xc1WD\xb8\xce1.9\xd8P\xa0s\x00\xe5\xfdV\xb4t\xe4n\xc5\xd8\xf9[\xb6n{\x00\x96\xdd\xde\xbcQ\xb8[kMk\xc28\xaa;\x02\x8c\xc2"\xb8/\xa9\xc5\xe5\xee\x85MyG\xe2\xbd\x1a\xce\x0b\xd3dbs\x04\x1aY]\x84\x85\xe9\xb1\xa9\x01\x96\xfa}\xa0\xcf\xb5]\xe1`\xba\x98\x885\x17o$\xd5\x16M^8-\xca\xc9!\x86\x0e&\xd1\x1a~7\xec\x06\xdec6e\xa6X\xf4\xca\xe3\x8f\xaaj@w\xbehyj3\x13\xfa\x87\x869\xe6\xa1\xeb\xa2\x00\xdei:&\x05\xbc=\x989\xe4\x86\x1d\r\x869\x10\xe3gM\x19\xc1\xce\xdbE\xa1\x9fj\x9a\x98\x05\xb6\x7f9\xf9\x1d\x13\x03^\r\x0e\xe6Zj}\xfe\x0b\xeeRY\xcb\x97(\\\xe31\t\x18\xf2\xdf\x16\xccWA\x01\xf9.\x15\r\xfdK\x852\xc7\xc67$\x18[\\\x1e5\xb5\xdf\x19[$?\x03\xd2\x05&\x16\xea\xd1\x1a\xf6\xcb\xecG\xfe\xef\xcee\xc6\x95\xf2P\x08\x10x&Y\x0f\x8bd\xf1\xe84K\x886\xe27G\xfe\xd6\xd6\xb4\x9f/\\Y\xaa"\xc9\x1a\x85\xdc\xbc\x990\xd0{\x8f$\x06.h\xa5\xff\xdd\xda\xc9zB*\xbf\x00\x16y!\x8a>\x18\xa8\x1b\xc6\xc7\x07\\\x8a\x99\xba\xef\x03?\xf4\x1f\xfelK\xd5\x8c\xcdO\xdb\x1b\xaeu=\x9f\xef\x02\xee5\xf4\x9e\x00\xf7f\xc8#\xec\x9dw\x1f\x99\xb55\xfbE\x11\xa2\xce\x1dF\xef\xf8=\xe1U\xd1;\x14\xc5P\x1aY\xae\x0b+\xde\xdd[\x19\x83w\x91\xa4\xa1/\xeb\xeaS\x84\x8b\x8eP\xb2\xf8a\xea\x9c2\xdaP\xf6\xbd\x89\xc3\xa9*\xf3\x07\x07\xd3\xdd|\x08z_!\xee\x11\xf0J\x9e\xfc\xf9\x1b\xc8\x9c&\xc2\xc5\x15*\x84b.B\xad\x9b=\r\xb9\xc9\xea\xa1\xf1U\xc7\xe7\xde\x1a\xde\x954;\xf1\xd2\x16yi\xdb\x8b%\xebK7dL\xe3\x92\xb7\t2\x190\x1a?\xf1\xf73\xf9=\xb5b$\x8d\xc60/9\x95\xef\xe7\x82\xdd\xf0H\xef\xa4\xd0\x16u}m\x1f?\xe9}\x15\x99&~OUr\x99\x0c.\xbe\xf9\\\xc1xm\xbd30\x16Z\xf9`*\x18\xbcI:[\x8a\t\xde\xdco\xa8\xe3\x81\xae\xe7.F\x94\xcbG\x179\x83#\xc6a\x0e:\x0eC%5,\x8e9\xb2\xed\xfa\xe0\xba\r\x08UG\xe8`Y&\x8aZn\xfcKQ`\xf7\xe6\xcc\xfb7-\x90Q\xca\xac:f\xb5\xd1\xd8\xfa\x8a\xca\x05\x9a\x13\xb9\x9f4C\xc7\xe0\xd5B\xaeA%\x17F\x1e\x9e\xcbZ\x86;\xec\xc7\xfd\xe7\xf0Z\x1e\x98\x06\x8f\xe4\x83\x9a\x86A\xef\xb5\x84vlB_8\x1cP\xac]Y\xad\xd8\x19\x13Ygk\xb8\xa9G\xca[\xca"\xb4{\xc9K\xabf\xf9G\xb5\xc2\xc3\xe0\xc8Bs\x8b4\x8c-\x82C\x91S\xb66\x8c"\xc2\xe7\xc5\\. \xceg>dY4\x9e\x86)\x17+?\xb4\xd0h\xa5\x9bLnrp<\x1dA\xb8\xe4\xf1\xf2?\xd3%\xa6\x8b\x1e\xbf\x82\x80M\xea\xbc.\xa8\xbc\xc51\x1b\xe6\x0e^\xcb\x1an9\xec\x86\xe2\xe5\xe8\x84\x9eW\x02\x92\xfb\x83\x8a\'<\x8f\xb2\xf8\xe6\xea\xe11fn\xec!\xd48^%<DY\xfbn\xda' ctx4=b'\xac}\xd44G\xb3\x83<\xa13\x9fS\xa6\xb6\x89c5\x9e\xd4\x802\t\xca\xdd\xfe\xbdzQ\xe9\xab\xbf\xb1\xfa\xf4\xcc\xe6:kG!\xeb\xd9H\xdcB\xf0*R\x8bz\x9da\xea\x02\xdfd6\x83dO\xa8\xab\xa1\x83\xa3 \x7f\x94\xf2\x98R\xaf\x95\x8b\xfc\x95\x8f\x1d\xb1\x19s\xf4\xcdZ\x13\xc0\x92O\x84-\xf0\xcf_`\xa5\xc1\xb5A\xb5\xea\xf4E\xa3\xf7\x97\x91\xe7\xb8s\xe6\xe0H\xa5\xfa&7\x0e8X\x0c\xcc\x82:\t\x92+S]\xb8V1f\xb2U\xc3\xb7\xd1Y\xbf\xc4\xd8Y\xf6uw\x10\x91\xf5\x03\xf6\x8d\xfa.>Ae(\x8a\x0c\xa45\x1a\xc1\xbf|J\xb6\x17G\x10b\x1c\xd7E\x94`\x98\xaa\xc7\t\x10\x15gT\x9e\x1e\x1aT\x14\x8d\x05\xf8{\x7f\x81(\xc2{X\xa7#\xdb\x1d\r5\xdb\xb3\xed\xbaN\xaa0\x11\xa6.\xee\xc9Z\xfe\xc8\xec\x07\xe2\xed\xf6\x8b\x9e\x9a\x06\x0b\xdfQ\xa8\x8cH\xb7\xa7\xd0Afa\xc1WD\xb8\xce1.9\xd8P s\x00\xe5\xfdV\xb4t\xe4n\xc5\xd8\xf9[\xb6n{\x00\x96\xdd\xde\xbcQ\xb8[kMk\xc28\xaa;\x02\x8c\xc2"\xb8/\xa9\xc5\xe5\xee\x85MyG\xe2\xbd\x1a\xce\x0b\xd3dbs\x04\x1aY]\x84\x85\xe9\xb1\xa9\x01\x96\xfa}\xa0\xcf\xb5]\xe1`\xba\x98\x885\x17o$\xd5\x16M^8-\xca\xc9!\x86\x0e&\xd1\x1a~7\xec\x06\xdec6e\xa6X\xf4\xca\xe3\x8f\xaaj@w\xbehyj3\x13\xfa\x87\x869\xe6\xa1\xeb\xa2\x00\xdei:&\x05\xbc=\x989\xe4\x86\x1d\r\x869\x10\xe3gM\x19\xc1\xce\xdbE\xa1\x9fj\x9a\x98\x05\xb6\x7f9\xf9\x1d\x13\x03^\r\x0e\xe6Zj}\xfe\x0b\xeeRY\xcb\x97(\\\xe31\t\x18\xf2\xdf\x16\xccWA\x01\xf9.\x15\r\xfdK\x852\xc7\xc67$\x18[\\\x1e5\xb5\xdf\x19[$?\x03\xd2\x05&\x16\xea\xd1\x1a\xf6\xcb\xecG\xfe\xef\xcee\xc6\x95\xf2P\x08\x10x&Y\x0f\x8bd\xf1\xe84K\x886\xe27G\xfe\xd6\xd6\xb4\x9f/\\Y\xaa"\xc9\x1a\x85\xdc\xbc\x990\xd0{\x8f$\x06.h\xa5\xff\xdd\xda\xc9zB*\xbf\x00\x16y!\x8a>\x18\xa8\x1b\xc6\xc7\x07\\\x8a\x99\xba\xef\x03?\xf4\x1f\xfelK\xd5\x8c\xcdO\xdb\x1b\xaeu=\x9f\xef\x02\xee5\xf4\x9e\x00\xf7f\xc8#\xec\x9dw\x1f\x99\xb55\xfbE\x11\xa2\xce\x1dF\xef\xf8=\xe1U\xd1;\x14\xc5P\x1aY\xae\x0b+\xde\xdd[\x19\x83w\x91\xa4\xa1/\xeb\xeaS\x84\x8b\x8eP\xb2\xf8a\xea\x9c2\xdaP\xf6\xbd\x89\xc3\xa9*\xf3\x07\x07\xd3\xdd|\x08z_!\xee\x11\xf0J\x9e\xfc\xf9\x1bH\x9c&\xc2\xc5\x15*\x84b.B\xad\x9b=\r\xb9\xc9\xea\xa1\xf1U\xc7\xe7\xde\x1a\xde\x155;\xf1\xd2\x16yi\xdb\x8b%\xebK7\xe4L\xe3\x92\xb7\t2\x190\x1a?\xf1\xf73\xf9=\xb5b$\x8d\xc60/9\x15\xef\xe7\x82\xdd\xf0H\xef\xa4\xd0\x16u}m\x1f?\xe9}\x15\x99&~OUr\x99\x8c-\xbe\xf9\\\xc1xm\xbd30\x16Z\xf9\xe0*\x18\xbcI:[\x8a\t\xde\xdco\xa8\xe3\x81\xae\xe7.F\x94\xcbG\x179\x03#\xc6a\x0e:\x0eC%5,\x8e9\xb2\xed\xfa\xe0\xba\r\x08UG\xe8`Y&\n[n\xfcKQ`\xf7\xe6\xcc\xfb7-\x90\xd1\xca\xac:f\xb5\xd1\xd8\xfa\x8a\xca\x05\x9a\x13\xb9\x9f4C\xc7\xe0\xd5B\xaeA\xa5\x17F\x1e\x9e\xcbZ\x86;\xec\xc7\xfd\xe7\xf0Z\x1e\x98\x06\x8f\xe4\x83\x9a\x86A\xef\xb5\x04vlB_8\x1cP\xac]Y\xad\xd8\x19\x93Ygk\xb8\xa9G\xca[\xca"\xb4{\xc9K\xabf\xf9G\xb5\xc2\xc3\xe0\xc8\xc2s\x8b4\x8c-\x82C\x91S\xb66\x8c"\xc2\xe7\xc5\\. \xceg>dY4\x1e\x87)\x17+?\xb4\xd0h\xa5\x9bLnr\xf0<\x1dA\xb8\xe4\xf1\xf2?\xd3%\xa6\x8b\x1e\xbf\x82\x80M\xea\xbc.\xa8\xbc\xc5\xb1\x1b\xe6\x0e^\xcb\x1an9\xec\x86\xe2\xe5\xe8\x84\x9eW\x02\x92\xfb\x83\x8a\'<\x8f\xb2x\xe6\xea\xe11fn\xec!\xd48^%<\xc4Y\xfbn\xda' ctx5=b'\xac}\xd44G\xb3\x83<\xa13\x9fS\xa6\xb6\x89c5\x9e\xd4\x002\t\xca\xdd\xfe\xbdzQ\xe9\xab\xbf\xb1\xfa\xf4\xcc\xe6:kG!\xeb\xd9H\xdcBp+R\x8bz\x9da\xea\x02\xdfd6\x83d\xcf\xa8\xab\xa1\x83\xa3 \x7f\x94\xf2\x98R\xaf\x95\x8b\xfc\x95\x8f\x1d\xb1\x19s\xf4\xcd\xda\x13\xc0\x92O\x84-\xf0\xcf_`\xa5\xc1\xb5A\xb5\xea\xf4E\xa3\xf7\x97\x91\xe7\xb8sf\xe0H\xa5\xfa&7\x0e8X\x0c\xcc\x82:\x89\x92+S]\xb8V1f\xb2U\xc3\xb7\xd1Y\xbf\xc4\xd8Y\xf6uw\x10\x91\xf5\x03\xf6\x8d\xfa.>Ae(\x8a\x0c\xa45\x1a\xc1\xbf|J\xb6\x17G\x10b\x1c\xd7E\x94`\x98\xaa\xc7\t\x10\x15gT\x9e\x1e\x1aT\x14\x8d\x05\xf8{\x7f\x81(\xc2{X\xa7#\xdb\x1d\r5\xdb\xb3\xed\xbaN\xaa0\x11\xa6.\xee\xc9Z\xfe\xc8\xec\x07\xe2\xed\xf6\x8b\x9e\x9a\x06\x0b\xdfQ\xa8\x8cH\xb7\xa7\xd0Afa\xc1WD\xb8\xce1.9\xd8P s\x00\xe5\xfdV\xb4t\xe4n\xc5\xd8\xf9[\xb6n{\x00\x96\xdd\xde\xbcQ\xb8[kMk\xc28\xaa;\x02\x8c\xc2"\xb8/\xa9\xc5\xe5\xee\x85MyG\xe2\xbd\x1a\xce\x0b\xd3dbs\x04\x1aY]\x84\x85\xe9\xb1\xa9\x01\x96\xfa}\xa0\xcf\xb5]\xe1`\xba\x98\x885\x17o$\xd5\x16M^8-\xca\xc9!\x86\x0e&\xd1\x1a~7\xec\x06\xdec6e\xa6X\xf4\xca\xe3\x8f\xaaj@w\xbehyj3\x13\xfa\x87\x869\xe6\xa1\xeb\xa2\x00\xdei:&\x05\xbc=\x989\xe4\x86\x1d\r\x869\x10\xe3gM\x19\xc1\xce\xdbE\xa1\x9fj\x9a\x98\x05\xb6\x7f9\xf9\x1d\x13\x03^\r\x0e\xe6Zj}\xfe\x0b\xeeRY\xcb\x97(\\\xe31\t\x18\xf2\xdf\x16\xccWA\x01\xf9.\x15\r\xfdK\x852\xc7\xc67$\x18[\\\x1e5\xb5\xdf\x19[$?\x03\xd2\x05&\x16\xea\xd1\x1a\xf6\xcb\xecG\xfe\xef\xcee\xc6\x95\xf2P\x08\x10x&Y\x0f\x8bd\xf1\xe84K\x886\xe27G\xfe\xd6\xd6\xb4\x9f/\\Y\xaa"\xc9\x1a\x85\xdc\xbc\x990\xd0{\x8f$\x06.h\xa5\xff\xdd\xda\xc9zB*\xbf\x00\x16y!\x8a>\x18\xa8\x1b\xc6\xc7\x07\\\x8a\x99\xba\xef\x03?\xf4\x1f\xfelK\xd5\x8c\xcdO\xdb\x1b\xaeu=\x9f\xef\x02\xee5\xf4\x9e\x00\xf7f\xc8#\xec\x9dw\x1f\x99\xb55\xfbE\x11\xa2\xce\x1dF\xef\xf8=\xe1U\xd1;\x14\xc5P\x1aY\xae\x0b+\xde\xdd[\x19\x83w\x91\xa4\xa1/\xeb\xeaS\x84\x8b\x8eP\xb2\xf8a\xea\x9c2\xdaP\xf6\xbd\x89\xc3\xa9*\xf3\x07\x07\xd3\xdd|\x08z_!\xee\x11\xf0J\x9e\xfc\xf9\x1b\xc8\x9c&\xc2\xc5\x15*\x84b.B\xad\x9b=\r\xb9\xc9\xea\xa1\xf1U\xc7\xe7\xde\x1a\xde\x954;\xf1\xd2\x16yi\xdb\x8b%\xebK7dL\xe3\x92\xb7\t2\x190\x1a?\xf1\xf73\xf9=\xb5b$\x8d\xc60/9\x95\xef\xe7\x82\xdd\xf0H\xef\xa4\xd0\x16u}m\x1f?\xe9}\x15\x99&~OUr\x99\x0c.\xbe\xf9\\\xc1xm\xbd30\x16Z\xf9`*\x18\xbcI:[\x8a\t\xde\xdco\xa8\xe3\x81\xae\xe7.F\x94\xcbG\x179\x03#\xc6a\x0e:\x0eC%5,\x8e9\xb2\xed\xfa\xe0\xba\r\x08UG\xe8`Y&\n[n\xfcKQ`\xf7\xe6\xcc\xfb7-\x90\xd1\xca\xac:f\xb5\xd1\xd8\xfa\x8a\xca\x05\x9a\x13\xb9\x9f4C\xc7\xe0\xd5B\xaeA\xa5\x17F\x1e\x9e\xcbZ\x86;\xec\xc7\xfd\xe7\xf0Z\x1e\x98\x06\x8f\xe4\x83\x9a\x86A\xef\xb5\x04vlB_8\x1cP\xac]Y\xad\xd8\x19\x93Ygk\xb8\xa9G\xca[\xca"\xb4{\xc9K\xabf\xf9G\xb5\xc2\xc3\xe0\xc8Bs\x8b4\x8c-\x82C\x91S\xb66\x8c"\xc2\xe7\xc5\\. \xceg>dY4\x9e\x86)\x17+?\xb4\xd0h\xa5\x9bLnrp<\x1dA\xb8\xe4\xf1\xf2?\xd3%\xa6\x8b\x1e\xbf\x82\x80M\xea\xbc.\xa8\xbc\xc51\x1b\xe6\x0e^\xcb\x1an9\xec\x86\xe2\xe5\xe8\x84\x9eW\x02\x92\xfb\x83\x8a\'<\x8f\xb2\xf8\xe6\xea\xe11fn\xec!\xd48^%<DY\xfbn\xda' ctx_list = [ctx1, ctx2, ctx3, ctx4, ctx5] msg = f'cat /flag{level} ' .encode() CTX_num = [bytes_to_long(md5_pad(i)) for i in ctx_list] PR = PolynomialRing(GF(n), "ke, z, xe, ye, d" ) ke, z, xe, ye, d = PR.gens() eqs = [ye**2 - (xe**3 + 3 )] for i in range (5 ): io.recvuntil(b'context: ' ) print (f"[DEBUG] Sending ctx {i+1 } " ) io.sendline(md5_pad(ctx_list[i]).hex ().encode()) s_line = io.recvline() s_i = int (s_line.strip().split()[-1 ]) print (f"[DEBUG] Received s_line: {s_i} " ) if i == 0 : eqs.append((s_i*ke - (z + xe*d))) else : ki = ke + (CTX_num[i] - CTX_num[0 ]) * 256 **16 delta = (CTX_num[i] - CTX_num[0 ]) * 256 **16 * G delta_x, delta_y = delta.xy() slope = (int (delta_y) - ye)/(int (delta_x) - xe) xi = slope**2 - xe - int (delta_x) eqs.append((s_i*ki - (z + xi*d)).numerator()) ''' I = PR.ideal(eqs) priv = int(I.groebner_basis()[-1].univariate_polynomial().roots()[0][0]) r, s = Sign(priv, b'n1junior_2025', f'cat /flag{level}'.encode()) io.recv() io.sendline(b" ".join([str(r).encode(), str(s).encode()])) flag = io.recvline().decode() print(flag) ''' I = PR.ideal(eqs) d_val = int (I.groebner_basis()[-1 ].univariate_polynomial().roots()[0 ][0 ]) r, s = Sign(d_val, b'n1junior_2025' , msg) io.recvuntil(b'signature: ' ) io.sendline(f"{r} {s} " .encode()) flag = io.recvline().decode() print (flag) if "Traceback" not in flag: print (ch) break except : pass
还有两道等我学会了来补()