2022西湖论剑WriteUp
MyErrorLearn
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def XennyOracle (): r = getPrime(512 ) d = invert(secret+r, p) - getPrime(246 ) print ('> r =' , r) print ('> d =' , d) def task (): for _ in range (3 ): op = int (input ()) if op == 1 : XennyOracle() elif op == 2 : ss = int (input ()) if ss == secret: print ('flag: ' , flag)
与题目交互3次,前两次拿数据,最后一次验证secret拿flag
\[(s+r1)^{-1}-x \equiv d1
\pmod{p}\]
\[(s+r2)^{-1}-y \equiv d2
\pmod{p}\]
\(x,y\) 分别表示两次数据中的\(Prime(246)\)
\[(d1+x)^{-1}-r1 \equiv s
\pmod{p}\]
\[(d2+y)^{-1}-r2 \equiv s
\pmod{p}\]
两式相减 \[
(d1+x)^{-1}-r1-(d2+y)^{-1}+r2 \equiv 0 \pmod{p}
\] 上式乘\((d1+x)(d2+y)\) \[
(d2+y) - (d1+x) + (r2-r1)*(d1+x)*(d2+y) \equiv 0 \pmod{p}
\] 一个二元的coppersmith 构造等式\(f =
(r1-r2)*(d1+x)*(d2+y)-(d2+y-d1-x)\) ,
找个多元copper的板子套上
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 def small_roots (f, bounds, m=1 , d=None ): if not d: d = f.degree() R = f.base_ring() N = R.cardinality() f /= f.coefficients().pop(0 ) f = f.change_ring(ZZ) G = Sequence ([], f.parent()) for i in range (m + 1 ): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range (d), repeat=f.nvariables()): g = base * prod(map (power, f.variables(), shifts)) G.append(g) B, monomials = G.coefficient_matrix() monomials = vector(monomials) factors = [monomial(*bounds) for monomial in monomials] for i, factor in enumerate (factors): B.rescale_col(i, factor) B = B.dense_matrix().LLL() B = B.change_ring(QQ) for i, factor in enumerate (factors): B.rescale_col(i, 1 / factor) H = Sequence ([], f.parent().change_ring(QQ)) for h in filter (None , B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1 : H.pop() elif I.dimension() == 0 : roots = [] for root in I.variety(ring=ZZ): root = tuple (R(root[var]) for var in f.variables()) roots.append(root) return roots return [] r1 = 10416632501801974694227453996514471230510822844141537215435310761282236706010374287476167228551720127564766961486909719901188052844926828718157982353509009 r2 = 10945694515092921935765033073472221225431374672659751536595840465276073402439042169265480667452817278318006398182876136457632746343409326182238053908029751 d1 = 56888336937500044415702919773416114217028770468080853282740190270108239476041614796007252946794331087237297216052651102131387831331715788882702697436356478481466698200484763202280365937244685692432494727290180152495648130890129145398986742781650456719538128804602194272879452329225793378627305015814235006449 d2 = 39564785910816285169732671501865632983688744846819855674275371020624933955200211958646008885482995237194222616193536005648361431696101118452470392982186472493910970565702639588941011814416028774758786985291250896861107704070339750852212760711413327701632586870290470689206960878069267347698863426921542358105 p = 117772635282729418285879412631216935490806524671311266185546790504745904196135114727754422648999093257461858612228556910365982066740540367638744157494110844029055193511998422999596748975390734628418184477450856691002269702533884505178634105672240426552752649855510423531462598366536500750787631689349504137087 import itertoolsR.<x,y> = PolynomialRing(Zmod(p)) f = (r1-r2)*(d1+x)*(d2+y)-(d2+y-d1-x) ans = small_roots(f, bounds=(2 ^246 ,2 ^246 ), m=2 ) x, y = ans[0 ] secret = 1 /(d1+x)-r1 print (secret)
LockbyLock
比赛的时候脑瘫代错数据了,半小时没跑出来
比赛结束一看改过来,三分钟就出了
第一次第二次分别发2和4过去,通过rsa同态,gcd拿到n
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 from pwn import *from Crypto.Util.number import *from gmpy2 import gcdio = remote('tcp.cloud.dasctf.com' , 21488 ) io.recvuntil(b'msg1 = ' ) m1 = int (io.recvline()) io.recvuntil(b'msg2 = ' ) m2 = int (io.recvline()) io.recvuntil(b'msg3 = ' ) m3 = int (io.recvline()) io.sendline(b'2' ) io.recvuntil(b'msg1 = ' ) m11 = int (io.recvline()) io.recvuntil(b'msg2 = ' ) m12 = int (io.recvline()) io.recvuntil(b'msg3 = ' ) m13 = int (io.recvline()) io.sendline(b'4' ) io.recvuntil(b'msg1 = ' ) m21 = int (io.recvline()) io.recvuntil(b'msg2 = ' ) m22 = int (io.recvline()) io.recvuntil(b'msg3 = ' ) m23 = int (io.recvline()) n = gcd(m11**2 -m21, m12**2 -m22, m13**2 -m23) print ('n = ' , n)print ('m1 = ' , m1)print ('m2 = ' , m2)print ('m3 = ' , m3)print ('m11 = ' , m11)print ('m12 = ' , m12)print ('m13 = ' , m13)print ('m21 = ' , m21)print ('m22 = ' , m22)print ('m23 = ' , m23)
对发送2(或者4)时拿到的数据,使用Pollard’s kangaroo
algorithm求解离散对数,时间复杂度大概在10^7
Ps:比赛的时候误拿了最开始给的第一组数据去跑了我有罪qwq
1 2 3 4 5 6 7 8 9 n = 27950092418645918795271296476246539971431421044767995947796205802943478655421653573048132032794234798415984952652376438949021032706491508283019165573213412785457536560835247461258996700097675642961189941397147832121215798258718677899047430424242917316567794068767871489924536948337626278187554943376441787903310776418948278970828056614007480123321047526250014275143243282932429377977743696352171804147086603083279288062958658420062643379022044426846987241250137102448598685606712521741583607474213255315746187154198844169065935475113145789594643131816301778344794413391236892556628344738627222814821415207388109885721 m11 = 20376839897483150202591245279988785405360453405518229860314688355462074916580107129330682477462552663163126795528589023633648581007626813266919326759350958000841142246828917207676253853232169554216424361180522508797731315528852217133666113558436155410718944260169577145534697157368360316333345542201829151854115374449392740319226345217386316755786443394636434084405240052107608897042547234279512095541661926355330342347645389032183986346153775559868246848334225734203525123266991086247401891517240101646138518686721872066661769309263715716056740461960894538873962031902453537598108351613389507079566414498498479169599 print ('e1 = ' , discrete_log_lambda(m11,mod(2 ,n),(10 **14 ,10 **15 )))m13 = 25654168760396958029792298552570736468682480823084565803373285663407780762485503411904748880883813230583714779620465503738003648395595616814054655108314643554108891626126605868539398053448468263238189719286443578861455115451473982124850952368091893597737777395501987491639060745712330371967127518105827612033705562056542312813576000021698561975189704496509514959272625270304453384259337771998645760374945175685616354851961881768292039874827087997461444008148949745457037468733732431091509683231366382582177637282818474046552143645887960397145203641778786138850215567179584185583145503621183907129930648092263851567807 print ('e2 = ' , discrete_log_lambda(m13,mod(2 ,n),(10 **14 ,10 **15 )))
最后一步,rsa共模攻击,直接套
1 2 3 4 5 6 7 8 9 10 11 12 e1 = 710179922790353 e2 = 871767685631399 m1 = 18750007013174536423532792814200623641168684158537875023748157501043254834580359946005782798296094859389089373500698907014613039137711295832309784735974363506728965819640087175515796834513477450080858989016689349728236691024985081556114367071105810780697020942697446551986754568210757566280492351447198167578093986707571108589625817862709984743133957428410783190472709108509345889765505376018262071861959201900814249687461034976969943031661314448282010075462891703692709064089097420481900561158105185207229830775312377353386152497009445846705513245630211941745950480797566412389719032698035360150224973575890501234349 m3 = 7797790268283288534585277663447783093020314808581197168654721551908450973265373361401405475956787957261162271142906099769330725245515346716540341701573417181548009002140256280036084891830998092431760582730910699403915059015408500826152174941526987251255119134941854685885210496410310463675404149461859807594357045329568535924128371829778827795984952587210383466369410277156253887474458529307937131048870052343339798306152534342663301893903024266179991962280108122818029085323024355732887033339956485454178220409801766544479498601241502177418664898422266425022618582009534572842700671485483690331035082266707254176987 n = 27950092418645918795271296476246539971431421044767995947796205802943478655421653573048132032794234798415984952652376438949021032706491508283019165573213412785457536560835247461258996700097675642961189941397147832121215798258718677899047430424242917316567794068767871489924536948337626278187554943376441787903310776418948278970828056614007480123321047526250014275143243282932429377977743696352171804147086603083279288062958658420062643379022044426846987241250137102448598685606712521741583607474213255315746187154198844169065935475113145789594643131816301778344794413391236892556628344738627222814821415207388109885721 from gmpy2 import *_, s1, s2 = gcdext(e1, e2) m = pow (m1, s1, n) * pow (m3, s2, n) m %= n flag = long_to_bytes(m) print (flag)