安全矩阵

 找回密码
 立即注册
搜索
查看: 2762|回复: 2

2021赣网杯题目收录

[复制链接]

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
发表于 2021-12-7 21:54:17 | 显示全部楼层 |阅读模式
1. e1、e2不互素的共模攻击
2.多元coppersmith
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-12-7 21:56:33 | 显示全部楼层
题干:
  1. ZnJvbSBzZWNyZXQgaW1wb3J0IGZsYWcKZnJvbSBDcnlwdG8uVXRpbC5udW1iZXIgaW1wb3J0ICoKCm0gPSBieXRlc190b19sb25nKGZsYWcpCgplMSA9IDY2NzQzMDEwNDg2NTI4OQplMiA9IDUzNzQwOTkzMDUyMzQyMQpwID0gZ2V0UHJpbWUoNTEyKQpxID0gZ2V0UHJpbWUoNTEyKQpuID0gcCpxCmMxID0gcG93KG0sIGUxLCBuKQpjMiA9IHBvdyhtLCBlMiwgbikKCnByaW50KGYnYzEgPSB7YzF9JykKcHJpbnQoZidjMiA9IHtjMn0nKQpwcmludChmJ24gPSB7bn0nKQoiIiIKYzEgPSA2NTkwMjY3ODU3MjcyNzcyNDE3OTE3NjQ5NjU3Mzk2ODk5NzE4MjcxMjA2MzMxNzA4MjI4OTEyMDQ1MzA5NDA2ODE5OTMyNTQxOTk4OTY4ODM4MjE3NzgwODUyOTA0MjMyMjIxNzg4NzMzNDAwNTA4NDUwNDc5NjM5NzIyMDgwNDg1NjE2NzI1NTE3NjQxNTY5MDIxNzM0ODI1MjEyNjA5NzgwOTEzMDE5NTIwODAyMDY5NDAyNjI1MDE5NDA0NzQ2MDU4MTE2NTAyNDE3ODM1ODQzNDMwNTQ5NTM2NDk4MzgzMDc1NjU1MjM3OTMzNTk4NTM5OTg3NjUyODkyMjA3NjAzMDU5NTIzMjY3OTA0Njk0MTMxMDc4NjYzNzI2MDc2NDk5MjQ5OTM3NTQyMTQ2NDUyOQpjMiA9IDg1ODA5NDAzNjc4MjUwMTUwMTUzMjkxNDcxMTg1OTk5ODA1ODcwODU4MTIzMDAxMjczMDM0MjEyNTgyODQ3NzMxODI1Mjk2ODkxMDE2ODEwODcxMzk3NTQ2MTM0MTE3MDEyMTk3NTk5NjUxNzI5NDAxNTkwOTgwMDIwMDI4MzgyODg0MDY4NTEzMjAxNzU4OTI2NDE2MTkyMjExODIxOTIyNTkzNjg2MjMyNDc1OTY3ODA4OTY0MDA2Nzg2MDc2NDYwMTYwNDI4NjM5MzUzMTUzNjU4MzIzMjA4MTE5NDUzMDU1MDcwMTk5MjQzMjk1MzMwNTIyODA0OTc0ODQ5MzMwOTI2NTAxMDkxNDMwNDE5Nzc1MTU1NjcwMjY0MzA2MjIyOTYyNDEzMjg5NjE2OTU3NTE5Cm4gPSA5MzAxMjM3OTk0OTU5NjY3OTg3NDAxMDgzNjUyMDk3MjQ2MzQzODE1NTE3NTk2MTI4MzI3Nzc0MzUxNDIwMzg3MTExNDMyOTAwODA0NDczNTUwMDcyNjQ0MDAxMjQ2NDAyOTE0NDIwNDgxMzQxMzkwOTMyMjM4OTU4NTk2NjMxMzQyNjYxMTQ4ODkyNzI5Mjg3NDMxOTYyODA2MzUyNjAwOTQwNTE0NDQzNjYwNTk5NjM4OTk4NTk3NzM0MDI4MDk4MzQ2OTgwMzQxMjExOTQ1ODE4NTA0NzQ3NTI1MzA1OTYzNjEyNjU1NTQ1MTU1NzM0ODE2OTUxNDk3NTI0OTcxMDkwMTg5OTUyNjk3NDI0NjEzOTU1OTczMDQ2MTU0MDY2MDk5MDM3NTAzNDY2OTA0Mjk1OQoiIiI=
复制代码
base64解码之后:
  1. from secret import flag
  2. from Crypto.Util.number import *

  3. m = bytes_to_long(flag)

  4. e1 = 667430104865289
  5. e2 = 537409930523421
  6. p = getPrime(512)
  7. q = getPrime(512)
  8. n = p*q
  9. c1 = pow(m, e1, n)
  10. c2 = pow(m, e2, n)

  11. print(f'c1 = {c1}')
  12. print(f'c2 = {c2}')
  13. print(f'n = {n}')
  14. """
  15. c1 = 65902678572727724179176496573968997182712063317082289120453094068199325419989688382177808529042322217887334005084504796397220804856167255176415690217348252126097809130195208020694026250194047460581165024178358434305495364983830756552379335985399876528922076030595232679046941310786637260764992499375421464529
  16. c2 = 85809403678250150153291471185999805870858123001273034212582847731825296891016810871397546134117012197599651729401590980020028382884068513201758926416192211821922593686232475967808964006786076460160428639353153658323208119453055070199243295330522804974849330926501091430419775155670264306222962413289616957519
  17. n = 93012379949596679874010836520972463438155175961283277743514203871114329008044735500726440012464029144204813413909322389585966313426611488927292874319628063526009405144436605996389985977340280983469803412119458185047475253059636126555451557348169514975249710901899526974246139559730461540660990375034669042959
  18. """
复制代码
​​
  1. import gmpy2
  2. from Crypto.Util.number import *

  3. c1 = 65902678572727724179176496573968997182712063317082289120453094068199325419989688382177808529042322217887334005084504796397220804856167255176415690217348252126097809130195208020694026250194047460581165024178358434305495364983830756552379335985399876528922076030595232679046941310786637260764992499375421464529
  4. c2 = 85809403678250150153291471185999805870858123001273034212582847731825296891016810871397546134117012197599651729401590980020028382884068513201758926416192211821922593686232475967808964006786076460160428639353153658323208119453055070199243295330522804974849330926501091430419775155670264306222962413289616957519
  5. n = 93012379949596679874010836520972463438155175961283277743514203871114329008044735500726440012464029144204813413909322389585966313426611488927292874319628063526009405144436605996389985977340280983469803412119458185047475253059636126555451557348169514975249710901899526974246139559730461540660990375034669042959

  6. e1 = 667430104865289
  7. e2 = 537409930523421

  8. g = gmpy2.gcd(e1, e2)
  9. print(g)
  10. # g = 3
  11. l, x, y = gmpy2.gcdext(e1//3, e2//3)
  12. print(x, y)

  13. m = pow(c1, x, n)*pow(c2, y, n) % n
  14. m = gmpy2.iroot(m, 3)
  15. m = 56006392793429430154056421945568912277006938354753284086685860659829848328383664134484234657728574333
  16. print(long_to_bytes(m))
复制代码


回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-12-7 21:59:40 | 显示全部楼层
这道题涉及了三元copper,又学习了新的知识点。
题干:
  1. from Crypto.Util.number import *
  2. from random import randint, getrandbits
  3. from sympy import nextprime
  4. from secret import flag, secreteBitNum

  5. hint = bytes_to_long((f'secreteBitNum = {secreteBitNum}').encode())
  6. tmp_e = 65537
  7. tmp_p = getPrime(int(512))
  8. tmp_q = getPrime(int(512))
  9. tmp_N = tmp_p * tmp_q
  10. print(f'tmp_N = {tmp_N}')
  11. print(pow(hint, tmp_e, tmp_N))
  12. print(tmp_p >> 180)

  13. target_bits = int(256)
  14. prime = getPrime(target_bits)
  15. s = randint(prime>>10, prime)
  16. r = getrandbits(secreteBitNum)
  17. t = (r*(s^2 + 2*s)) % prime
  18. gifts = [3, 2]
  19. ks = [floor(target_bits * (gift / (gift + 1))) for gift in gifts]
  20. leak1 = s >> (target_bits - ks[0])
  21. leak2 = t >> (target_bits - ks[1])

  22. p = nextprime((s*(nextprime(s) * nextprime(r) + t)))
  23. q = getPrime(p.bit_length())
  24. N = p*q
  25. e = 65537
  26. m = bytes_to_long(flag)
  27. c = pow(m, e, N)

  28. print(f'prime = {prime}')
  29. print(f'c = {c}')
  30. print(f'N = {N}')
  31. print(f'leak1 = {leak1}')
  32. print(f'leak2 = {leak2}')

  33. """
  34. tmp_N = 67275889677378946734903321404206582364153218707836044936581311977721676158433934674861722018390091292542128885311842688233567992017423854706617140651934525455990460080562308585391373661331461122947028205118969966760791488914164391921330229025670176008518053339148134137770309365614255463111202481834705060173
  35. 40399377632586118650556149454962332599993544072289982576457293479237148938553095258299197606759611718110458893982875730643146645623512300513916266262798465380752083932871857821720398540072426424439422364690204675516506456125988918985863308292449915493404572808822346197667419207669315093927318993921905479596
  36. 4877155090632997781879191807827231697420271396210537080241322765167927413977000532975047982026915056
  37. prime = 82321753209337659641812698792368753307257174920293482309329229017641186204037
  38. c = 4327179356609269294409009935591795772603625779675971467878490086808144060225614005300908314649047950861015994603326121468330956776913366179511247457747179889685304469999218104955814145411915021238933150884498316563808220329632240175418452382843973948334446343545955570063628905102384071000832724697885872043017030707897928
  39. N = 43941665823196509154346632368475246193489316520677500866461851257383928558997955146720003171553041820199105630143274308184375615057136594812756966125202091119439909980006181740220827474838356621605513939553184451557022029987518161532780360148932769025277495283357745880781214097057768654158857096614016596756958574010574773
  40. leak1 = 4392924728395269190263639346144303703257730516994610750658
  41. leak2 = 838456777370923849008096179359487752850229097203212
  42. """
复制代码
首先分析题目流程:
第一部分如下:
  1. hint = bytes_to_long((f'secreteBitNum = {secreteBitNum}').encode())
  2. tmp_e = 65537
  3. tmp_p = getPrime(int(512))
  4. tmp_q = getPrime(int(512))
  5. tmp_N = tmp_p * tmp_q
  6. print(f'tmp_N = {tmp_N}')
  7. print(pow(hint, tmp_e, tmp_N))
  8. print(tmp_p >> 180)
复制代码
已知n、c和p的高位,可以利用一元的coppersmith求出secreteBitNum。
  1. ph = 4877155090632997781879191807827231697420271396210537080241322765167927413977000532975047982026915056
  2. pp = ph << 180
  3. print(pp)
  4. N = 67275889677378946734903321404206582364153218707836044936581311977721676158433934674861722018390091292542128885311842688233567992017423854706617140651934525455990460080562308585391373661331461122947028205118969966760791488914164391921330229025670176008518053339148134137770309365614255463111202481834705060173
  5. PR.<x> = PolynomialRing(Zmod(N))
  6. f = x+pp
  7. pl = f.small_roots(X=2^180,beta=0.4)[0]
  8. print(pl)
  9. p=pp+pl
  10. print(p)
  11. #p=7474218428506439131024561238447007658574698902527126414652353026654065729675401366440504060759323896095490193371294094265057254763085596066166150006638181
复制代码
求出p后,就可以正常流程解出明文secreteBitNum了。
  1. tmp_e = 65537
  2. tmp_N = 67275889677378946734903321404206582364153218707836044936581311977721676158433934674861722018390091292542128885311842688233567992017423854706617140651934525455990460080562308585391373661331461122947028205118969966760791488914164391921330229025670176008518053339148134137770309365614255463111202481834705060173
  3. tmp_p = 7474218428506439131024561238447007658574698902527126414652353026654065729675401366440504060759323896095490193371294094265057254763085596066166150006638181
  4. tmp_q = tmp_N // tmp_p
  5. phi = (tmp_q-1)*(tmp_p-1)
  6. d = gmpy2.invert(tmp_e, phi)
  7. c = 40399377632586118650556149454962332599993544072289982576457293479237148938553095258299197606759611718110458893982875730643146645623512300513916266262798465380752083932871857821720398540072426424439422364690204675516506456125988918985863308292449915493404572808822346197667419207669315093927318993921905479596
  8. m = pow(c,d,tmp_N)
  9. print(long_to_bytes(m))
  10. #b'secreteBitNum = 26'
复制代码
得到secreteBitNum = 26后,继续分析题目第二部分。经过运算得出ks=[192, 170]
  1. target_bits = int(256)
  2. prime = getPrime(target_bits)
  3. s = randint(prime>>10, prime)
  4. r = getrandbits(secreteBitNum)
  5. t = (r*(s^2 + 2*s)) % prime
  6. gifts = [3, 2]
  7. ks = [floor(target_bits * (gift / (gift + 1))) for gift in gifts]
  8. leak1 = s >> (target_bits - ks[0])
  9. leak2 = t >> (target_bits - ks[1])
复制代码
这是一个三元的copper,使用脚本解出s,r,t。
  1. import itertools

  2. def small_roots(f, bounds, m=1, d=None):
  3.         if not d:
  4.                 d = f.degree()

  5.         R = f.base_ring()
  6.         N = R.cardinality()
  7.         
  8.         f /= f.coefficients().pop(0)
  9.         f = f.change_ring(ZZ)

  10.         G = Sequence([], f.parent())
  11.         for i in range(m+1):
  12.                 base = N^(m-i) * f^i
  13.                 for shifts in itertools.product(range(d), repeat=f.nvariables()):
  14.                         g = base * prod(map(power, f.variables(), shifts))
  15.                         G.append(g)

  16.         B, monomials = G.coefficient_matrix()
  17.         monomials = vector(monomials)

  18.         factors = [monomial(*bounds) for monomial in monomials]
  19.         for i, factor in enumerate(factors):
  20.                 B.rescale_col(i, factor)

  21.         B = B.dense_matrix().LLL()

  22.         B = B.change_ring(QQ)
  23.         for i, factor in enumerate(factors):
  24.                 B.rescale_col(i, 1/factor)

  25.         H = Sequence([], f.parent().change_ring(QQ))
  26.         for h in filter(None, B*monomials):
  27.                 H.append(h)
  28.                 I = H.ideal()
  29.                 if I.dimension() == -1:
  30.                         H.pop()
  31.                 elif I.dimension() == 0:
  32.                         roots = []
  33.                         for root in I.variety(ring=ZZ):
  34.                                 root = tuple(R(root[var]) for var in f.variables())
  35.                                 roots.append(root)
  36.                         return roots
  37.         return []

  38. def trivariate():
  39.         print('Trivariate')
  40.         bounds = (1<<64, 1<<86, 1<<26)
  41.         #roots = tuple(randrange(bound) for bound in bounds)
  42.         R = Integers(prime)
  43.         P.<sl, tl, r> = PolynomialRing(R)
  44.         f = ((sh + sl)**2+2*(sh+sl))*r - (th + tl)
  45.         print(small_roots(f, bounds,6))

  46. if __name__ == '__main__':
  47.         prime = 82321753209337659641812698792368753307257174920293482309329229017641186204037
  48.         leak1 = 4392924728395269190263639346144303703257730516994610750658
  49.         leak2 = 838456777370923849008096179359487752850229097203212
  50.         sh = leak1 << 64
  51.         th = leak2 << 86
  52.         trivariate()
  53. #[(2837580634489900859, 63360403616040741532234070, 29943235)]
复制代码
继续分析第三部分,第三部分就是简单的RSA加解密。得到flag:
  1. import gmpy2
  2. from Crypto.Util.number import *
  3. from sympy import nextprime

  4. leak1 = 4392924728395269190263639346144303703257730516994610750658
  5. leak2 = 838456777370923849008096179359487752850229097203212
  6. sl, tl, r = (2837580634489900859, 63360403616040741532234070, 29943235)
  7. sh = leak1 << 64
  8. th = leak2 << 86
  9. s = sh+sl
  10. t = th+tl
  11. p = nextprime((s*(nextprime(s) * nextprime(r) + t)))
  12. n = 43941665823196509154346632368475246193489316520677500866461851257383928558997955146720003171553041820199105630143274308184375615057136594812756966125202091119439909980006181740220827474838356621605513939553184451557022029987518161532780360148932769025277495283357745880781214097057768654158857096614016596756958574010574773
  13. q = n // p
  14. phi = (p-1)*(q-1)
  15. e = 65537
  16. d = gmpy2.invert(e, phi)
  17. c = 4327179356609269294409009935591795772603625779675971467878490086808144060225614005300908314649047950861015994603326121468330956776913366179511247457747179889685304469999218104955814145411915021238933150884498316563808220329632240175418452382843973948334446343545955570063628905102384071000832724697885872043017030707897928
  18. m = pow(c,d,n)
  19. print(long_to_bytes(m))
  20. #b'flag{bc33c490-4b95-11ec-ad04-00155d9a1603}'
复制代码
附上找到的coppersmith脚本,可用于1、2、3元copper,approximate_factor,boneh_durfee
  1. import itertools

  2. def small_roots(f, bounds, m=1, d=None):
  3.         if not d:
  4.                 d = f.degree()

  5.         R = f.base_ring()
  6.         N = R.cardinality()
  7.         
  8.         f /= f.coefficients().pop(0)
  9.         f = f.change_ring(ZZ)

  10.         G = Sequence([], f.parent())
  11.         for i in range(m+1):
  12.                 base = N^(m-i) * f^i
  13.                 for shifts in itertools.product(range(d), repeat=f.nvariables()):
  14.                         g = base * prod(map(power, f.variables(), shifts))
  15.                         G.append(g)

  16.         B, monomials = G.coefficient_matrix()
  17.         monomials = vector(monomials)

  18.         factors = [monomial(*bounds) for monomial in monomials]
  19.         for i, factor in enumerate(factors):
  20.                 B.rescale_col(i, factor)

  21.         B = B.dense_matrix().LLL()

  22.         B = B.change_ring(QQ)
  23.         for i, factor in enumerate(factors):
  24.                 B.rescale_col(i, 1/factor)

  25.         H = Sequence([], f.parent().change_ring(QQ))
  26.         for h in filter(None, B*monomials):
  27.                 H.append(h)
  28.                 I = H.ideal()
  29.                 if I.dimension() == -1:
  30.                         H.pop()
  31.                 elif I.dimension() == 0:
  32.                         roots = []
  33.                         for root in I.variety(ring=ZZ):
  34.                                 root = tuple(R(root[var]) for var in f.variables())
  35.                                 roots.append(root)
  36.                         return roots
  37.         return []

  38. def univariate():
  39.         print('Univariate')
  40.         bounds = (floor(N^.3),)
  41.         roots = tuple(randrange(bound) for bound in bounds)
  42.         R = Integers(N)
  43.         P.<x> = PolynomialRing(R, 1)
  44.         monomials = [x, x^2, x^3]
  45.         f = sum(randrange(N)*monomial for monomial in monomials)
  46.         f -= f(*roots)
  47.         print(small_roots(f, bounds, m=7))

  48. def bivariate():
  49.         print('Bivariate')
  50.         bounds = (floor(N^.15), floor(N^.15))
  51.         roots = tuple(randrange(bound) for bound in bounds)
  52.         R = Integers(N)
  53.         P.<x, y> = PolynomialRing(R)
  54.         monomials = [x, y, x*y, x^2]
  55.         f = sum(randrange(N)*monomial for monomial in monomials)
  56.         f -= f(*roots)
  57.         print(small_roots(f, bounds))

  58. def trivariate():
  59.         print('Trivariate')
  60.         bounds = (floor(N^.12), floor(N^.12), floor(N^.12))
  61.         roots = tuple(randrange(bound) for bound in bounds)
  62.         R = Integers(N)
  63.         P.<x, y, z> = PolynomialRing(R)
  64.         monomials = [x, y, x*y, x*z, y*z]
  65.         f = sum(randrange(N)*monomial for monomial in monomials)
  66.         f -= f(*roots)
  67.         print(small_roots(f, bounds))

  68. def boneh_durfee():
  69.         print('Boneh Durfee')
  70.         bounds = (floor(N^.25), 2^1024)
  71.         d = random_prime(bounds[0])
  72.         e = inverse_mod(d, (p-1)*(q-1))
  73.         roots = (e*d//((p-1)*(q-1)), (p+q)//2)
  74.         R = Integers(e)
  75.         P.<k, s> = PolynomialRing(R)
  76.         f = 2*k*((N+1)//2 - s) + 1
  77.         print(small_roots(f, bounds, m=3, d=4))

  78. def approximate_factor():
  79.         print('Approximate factor')
  80.         bounds = (floor(N^.05), floor(N^.05))
  81.         roots = tuple(randrange(bound) for bound in bounds)
  82.         R = Integers(N)
  83.         P = PolynomialRing(R, len(bounds), 'x')
  84.         f = sum(randrange(2^128)*x for x in P.gens())
  85.         f += p - f(*roots)
  86.         print(small_roots(f, bounds, m=2, d=4))

  87. if __name__ == '__main__':
  88.         print('Generating primes')
  89.         p = random_prime(2^1024)
  90.         q = random_prime(2^1024)
  91.         N = p*q
  92.         univariate()
  93.         bivariate()
  94.         trivariate()
  95.         boneh_durfee()
  96.         approximate_factor()
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-27 22:35 , Processed in 0.013927 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表