• [UIUCTF 2022] crypto ASR,WringingRing


    crypto-2 ASR

    基本上ASR就是RSA的代称了。

    原题

    1. from secret import flag
    2. from Crypto.Util.number import bytes_to_long, getPrime, isPrime
    3. from math import prod
    4. small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
    5. def gen_prime(bits, lim = 7, sz = 64):
    6. while True:
    7. p = prod([getPrime(sz) for _ in range(bits//sz)])
    8. for i in range(lim):
    9. if isPrime(p+1):
    10. return p+1
    11. p *= small_primes[i]
    12. p = gen_prime(512)
    13. q = gen_prime(512)
    14. n = p*q
    15. phi = (p-1)*(q-1)
    16. e = 0x10001
    17. d = pow(e, -1, phi)
    18. msg = bytes_to_long(flag)
    19. ct = pow(msg, e, n)
    20. print("e = ", e)
    21. print("d = ", d)
    22. print("ct = ", ct)
    23. '''
    24. e = 65537
    25. d = 195285722677343056731308789302965842898515630705905989253864700147610471486140197351850817673117692460241696816114531352324651403853171392804745693538688912545296861525940847905313261324431856121426611991563634798757309882637947424059539232910352573618475579466190912888605860293465441434324139634261315613929473
    26. ct = 212118183964533878687650903337696329626088379125296944148034924018434446792800531043981892206180946802424273758169180391641372690881250694674772100520951338387690486150086059888545223362117314871848416041394861399201900469160864641377209190150270559789319354306267000948644929585048244599181272990506465820030285
    27. '''

    这里只给了e,d,c没有给n也就没法直接用ed来分解n了。

    不过p,q生成的方式比较特殊,先生成8个64位素数然后相乘,再乘以2,3,5,...(最多7个) 最后+1得到p,q

    由于  e\cdot d\equiv 1(mod phi) 所以有 k*phi = e*d -1 这时候对k*phi进行分解质因数可以得到

    2^12 * 3^3 * 5^3 * 7^2 * 11 * ...

    后边是16个64位的素数,显然将这16个素数分两组然后再乘2,3,5,7,(11)再加1就得到p,q

    1. from Crypto.Util.number import bytes_to_long, long_to_bytes, getPrime, isPrime
    2. e = 65537
    3. d = 195285722677343056731308789302965842898515630705905989253864700147610471486140197351850817673117692460241696816114531352324651403853171392804745693538688912545296861525940847905313261324431856121426611991563634798757309882637947424059539232910352573618475579466190912888605860293465441434324139634261315613929473
    4. ct = 212118183964533878687650903337696329626088379125296944148034924018434446792800531043981892206180946802424273758169180391641372690881250694674772100520951338387690486150086059888545223362117314871848416041394861399201900469160864641377209190150270559789319354306267000948644929585048244599181272990506465820030285
    5. k_phi = e*d -1
    6. k_phi = 12798440407105031908999784124548472446040018889572960817730530853573947469787170113848247037843114210766860084237698041237300679054325293570244618517445055261481120413825585349170515207419290554629935870091105933806157817778443160330590022707245776617234034051475753857980562266052844635281301139210583841390095872000
    7. # 2^12 * 3^3 * 5^3 * 7^2 * 11 * ...
    8. '''
    9. P20 = 13923226921736843531
    10. P20 = 15789155524315171763
    11. P20 = 11157595634841645959
    12. P20 = 16303174734043925501
    13. P20 = 10476183267045952117
    14. P20 = 10441209995968076929
    15. P20 = 10357495682248249393
    16. P20 = 11865228112172030291
    17. P20 = 12775011866496218557
    18. P20 = 16070004423296465647
    19. P20 = 14695627525823270231
    20. P20 = 13403263815706423849
    21. P20 = 14497899396819662177
    22. P20 = 18318015934220252801
    23. P20 = 16755840154173074063
    24. P20 = 17757525673663327889
    25. '''
    26. pa = [13923226921736843531,15789155524315171763,11157595634841645959,16303174734043925501,10476183267045952117,10441209995968076929,10357495682248249393,11865228112172030291,12775011866496218557,16070004423296465647,14695627525823270231,13403263815706423849,14497899396819662177,18318015934220252801,16755840154173074063,17757525673663327889]
    27. #p,q分别为pa取8个再乘2,3,5,7,(11) +1得到
    28. for i in [2,2,3,3,5,5,7,7,11]:
    29. k_phi //=i
    30. def get_pq(idx, tp,tq, np,nq):
    31. if np==8:
    32. if not isPrime(tp+1):
    33. return
    34. if nq==8:
    35. if not isPrime(tq+1):
    36. return
    37. if idx >= 16:
    38. print(tp+1, tq+1)
    39. p = tp+1
    40. q = tq+1
    41. n = p*q
    42. m = pow(ct, d, n)
    43. print(m)
    44. print(long_to_bytes(m))
    45. return
    46. if np<8:
    47. get_pq(idx+1, tp*pa[idx], tq, np+1, nq)
    48. if nq<8:
    49. get_pq(idx+1, tp, tq*pa[idx], np, nq+1)
    50. get_pq(0, 2*3*5*7, 2*3*5*7*11,0,0)
    51. #uiuctf{bru4e_f0rc3_1s_FUn_fuN_Fun_f0r_The_whOLe_F4miLY!}

    虽然有16层,但爆破题不大

    crypto-3 WringingRing

    这个由于没有远端只能测下程序

    1. import sympy as sp
    2. import random
    3. import signal
    4. #from secret import FLAG
    5. FLAG = 'flag{testxxxxxx}'
    6. secret = random.SystemRandom().randint(1, 500_000) #19位数
    7. print("secret:", secret)
    8. _MAX = 10 ** (len(str(secret)) - 1) # 10**5
    9. # generating a polynomial
    10. def _f(secret, minimum=3):
    11. coeffs = [secret] + [
    12. random.SystemRandom().randint(1, _MAX) for _ in range(minimum - 1)
    13. ]
    14. # print("Secret Polynomial:")
    15. # f_str = str(secret)
    16. # for i, coeff in enumerate(coeffs[1:]):
    17. # f_str += " + " + str(coeff) + "*x^" + str(i + 1)
    18. # print(f_str)
    19. def f(x):
    20. res = 0
    21. for i, coeff in enumerate(coeffs):
    22. res += coeff * x ** (i)
    23. return res
    24. return f
    25. def gen_shares(secret, minimum=3):
    26. f = _f(secret, minimum)
    27. shares = [(i + 1, f(i + 1)) for i in range(minimum)]
    28. return shares
    29. def challenge(secret, minimum=3):
    30. shares = gen_shares(secret, minimum)
    31. print(shares)
    32. points = random.sample(shares, minimum - 1)
    33. print(points)
    34. points.sort()
    35. return points
    36. def main():
    37. minimum = 10
    38. points = challenge(secret, minimum)
    39. print("[SSSS] Known shares of the secret polynomial: ")
    40. for point in points:
    41. print(f" {point}")
    42. print()
    43. #signal.alarm(60)
    44. guess = int(input("[SSSS] Enter my secret: "))
    45. if guess == secret:
    46. print(f"[SSSS] Correct! {FLAG}")
    47. else:
    48. print("[SSSS] Incorrect...")
    49. if __name__ == "__main__":
    50. main()
    51. '''
    52. Wringing Rings - 139 points
    53. "comic book style person at a chalkboard drawing a curve"
    54. crypto
    55. Everyone says we should use finite fields, but I loved sharing secrets this way so much that I put a ring on it!
    56. $ nc ring.chal.uiuc.tf 1337
    57. author: Spamakin
    58. '''

    先成生10个数,第1个是secret这个数小于500000(500_000中间的下划线是分隔符直接去掉就行),后9个比它小一位(10进制),然后这些数作10次运算生成10个数会显示出9个。

    这10次运算的\sum c*x^{i},虽然只给了9个但是影响不大,直接用z3

    1. from z3 import *
    2. from pwn import *
    3. '''
    4. context.log_level = 'debug'
    5. p = remote("ring.chal.uiuc.tf", 1337)
    6. p.recvuntil(b'[SSSS] Known shares of the secret polynomial:\n')
    7. points = []
    8. for i in range(9):
    9. p.append(eval(p.recvline()))
    10. print(points)
    11. '''
    12. data = '''
    13. (1, 104137)
    14. (3, 73506441)
    15. (4, 879095644)
    16. (5, 6249646673)
    17. (6, 31430072352)
    18. (7, 123848462689)
    19. (8, 407425874756)
    20. (9, 1166688459129)
    21. (10, 2993217169048)
    22. '''
    23. data = data.strip().split("\n")
    24. points = []
    25. for v in data:
    26. points.append(eval(v))
    27. print(points)
    28. c = [Int(f'c{i}') for i in range(10)]
    29. s = Solver()
    30. s.add(c[0]>0)
    31. s.add(c[0]<500000)
    32. for i in range(1,10):
    33. s.add(c[i]>0)
    34. s.add(c[i]<100000)
    35. for (i,n) in points:
    36. r = 0
    37. for j in range(10):
    38. r += c[j]*i**j
    39. s.add(r == n)
    40. s.check()
    41. d = s.model()
    42. d = d[c[0]].as_long()
    43. print(d)
    44. #p.sendline(str(d).encode())

  • 相关阅读:
    Js逆向教程20-Hook基础
    软件测试面试题之自动化测试题合集(金九银十必备)
    ffplay 源码剖析——框架分析
    数据库-DQL
    聊聊SpringBootTest的webEnvironment
    计算机网络 - 数据链路层 选择填空复习题
    10 路由协议:西出网关无故人,敢问路在何方
    Go语言之协程和管道
    ABP微服务系列学习-使用Tye启动微服务
    css设置遮罩层(半透明)
  • 原文地址:https://blog.csdn.net/weixin_52640415/article/details/126639554