• [祥云杯 2022] crypto部分


    目录

    DLP

    RSA

    leak_rsa 未完成

    tracing

    fill

    fermat


    有几个差一点,看了个  Arr3stY0u 的WP,豁然开朗 

    DLP

    原题是个DLP加密,输入g可对其加密,加密后如果是4则返回flag。

    1. import socketserver
    2. from time import sleep
    3. from secret import flag
    4. import signal
    5. import random
    6. from Crypto.Util.number import *
    7. import random
    8. #通过快速幂的方法求幂,每次通过4的状态设置t,泄露t
    9. #当返回值t==1时,说明这个密文经历过4
    10. def pow_d(g, e, n):
    11. t, r = 0, 1
    12. for _ in bin(e)[2:]:
    13. if r == 4: t += 1
    14. r = pow(r, 2, n)
    15. if _ == '1': r = r * g % n
    16. return t, r
    17. def ts(m, p):
    18. m = m % p
    19. return pow(m, (p - 1) // 2, p) == 1
    20. class Task(socketserver.BaseRequestHandler):
    21. def _recvall(self):
    22. BUFF_SIZE = 2048
    23. data = b''
    24. while True:
    25. part = self.request.recv(BUFF_SIZE)
    26. data += part
    27. if len(part) < BUFF_SIZE:
    28. break
    29. return data.strip()
    30. def send(self, msg, newline=True):
    31. try:
    32. if newline:
    33. msg += b'\n'
    34. self.request.sendall(msg)
    35. except:
    36. pass
    37. def recv(self):
    38. return self._recvall()
    39. def handle(self):
    40. border = b"|"
    41. self.send(border*72)
    42. self.send(border+b"Solve a DLP challenge in some special way to get the flag", border)
    43. p = 2 ** 1024 - 2 ** 234 - 2 ** 267 - 2 ** 291 - 2 ** 403 - 1
    44. s = random.randint(2, (p - 1) // 2)
    45. while True:
    46. self.send(s)
    47. self.send(b"| Options: \n|\t[T]ry the magic machine \n|\t[Q]uit")
    48. ans = self.recv().lower()
    49. if ans == b't':
    50. self.send(border+b"please send your desired integer: ")
    51. g = self.recv()
    52. try:
    53. g = int(g)
    54. except:
    55. self.send(border+b"The given input is not integer!")
    56. break
    57. sleep(0.3)
    58. if ts(g, p):
    59. t, r = pow_d(g, s, p)
    60. if r == 4:
    61. self.send(border+b'Great! you got the flag:'+flag)
    62. else:
    63. self.send(border+b"t, r = "+f"{t, r}".encode())
    64. else:
    65. self.send(border+"The given base is NOT valid!!!")
    66. elif ans == b'q':
    67. self.send(border+"Quitting ...")
    68. break
    69. else:
    70. self.send(border+"Bye bye ...")
    71. break
    72. '''
    73. DLP题由s进行加密
    74. c = g**s %p
    75. 可根据用户输入的g得到c, 求c=4时g
    76. '''
    77. class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    78. pass
    79. class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    80. pass
    81. if __name__ == "__main__":
    82. HOST, PORT = '0.0.0.0', 10001
    83. server = ForkedServer((HOST, PORT), Task)
    84. server.allow_reuse_address = True
    85. print(HOST, PORT)
    86. server.serve_forever()

    这里边给了个t,r其中r是密文,t是表示在乘幂过程中是否有过结果是4的情况,一直不清楚怎么弄,看了WP才知道,正是这个t的泄露这题才能解。WP也没看大明白,先存一下,回头慢慢看

    1. from pwn import *
    2. from sage import *
    3. from Crypto.Util.number import *
    4. context.proxy = 'localhost'
    5. class Gao:
    6. def __init__(self):
    7. #self.conn = process(['python3', '1_DLP_chall.py'])
    8. self.conn = remote('101.201.71.136', 38476)
    9. self.p = 2 ** 1024 - 2 ** 234 - 2 ** 267 - 2 ** 291 - 2 ** 403 - 1
    10. self.s_high = 1
    11. self.Zp = Zmod(self.p)
    12. def gao_check(self):
    13. self.conn.sendline('T')
    14. ans = self.Zp(4).nth_root(self.s_high)
    15. print('Guessing: {}'.format(ans))
    16. self.conn.sendline(str(ans))
    17. self.conn.recvuntil('integer: n')
    18. a = self.conn.recvline()
    19. if ('Great!' in a):
    20. print(a)
    21. print(ZZ(ans).nbits())
    22. return True
    23. else:
    24. return False
    25. def gao_one(self):
    26. self.conn.sendline('T')
    27. ans = self.Zp(2).nth_root(self.s_high) #对2开s_high次幂
    28. self.conn.sendline(str(ans))
    29. self.conn.recvuntil('integer: n')
    30. a = self.conn.recvline()
    31. if ('Great!' in a):
    32. print(a)
    33. print(ZZ(ans).nbits())
    34. return True
    35. else:
    36. a = a[8:]
    37. t, r = eval(a)
    38. self.s_high <<= 1
    39. if (t == 0):
    40. self.s_high |= 1
    41. self.t = 1 - t
    42. print('{:b}'.format(self.s_high))
    43. return False
    44. def gao(self):
    45. while (True):
    46. if (self.gao_one()):
    47. break
    48. if (self.t == 1):
    49. if (self.gao_check()):
    50. break
    51. def gao_2(self):
    52. for i in range(1023):
    53. if (self.gao_one()):
    54. break
    55. else:
    56. for i in range(20):
    57. self.gao_check()
    58. self.s_high >>= 1
    59. if __name__ == '__main__':
    60. g = Gao()
    61. g.gao_2()

     

    RSA

    一直以来RSA的n从来没有分解成功过,这回也没有,不知道是不是yafu是不是真的。

    1. from Crypto.Util.number import getPrime, isPrime, bytes_to_long, inverse
    2. from math import lcm
    3. from secret import flag
    4. def gen(g):
    5. bits = 512 - g.bit_length()
    6. while True:
    7. a = getPrime(bits)
    8. p = 2 * a * g + 1
    9. if isPrime(p):
    10. return p
    11. flag = bytes_to_long(flag)
    12. g = getPrime(320)
    13. p = gen(g)
    14. q = gen(g)
    15. n = p * q
    16. d = getPrime(135)
    17. phi = lcm(p - 1, q - 1)
    18. e = inverse(d, phi)
    19. c = pow(flag, e, n)
    20. print("n = {}".format(n))
    21. print("e = {}".format(e))
    22. print("c = {}".format(c))

    想分解n-1也没有成功,看WP说是直接分解。也就没啥说的了。

    1. from gmpy2 import invert
    2. from Crypto.Util.number import long_to_bytes
    3. n = 253784908428481171520644795825628119823506176672683456544539675613895749357067944465796492899363087465652749951069021248729871498716450122759675266109104893465718371075137027806815473672093804600537277140261127375373193053173163711234309619016940818893190549811778822641165586070952778825226669497115448984409
    4. e = 31406775715899560162787869974700016947595840438708247549520794775013609818293759112173738791912355029131497095419469938722402909767606953171285102663874040755958087885460234337741136082351825063419747360169129165
    5. c = 97724073843199563126299138557100062208119309614175354104566795999878855851589393774478499956448658027850289531621583268783154684298592331328032682316868391120285515076911892737051842116394165423670275422243894220422196193336551382986699759756232962573336291032572968060586136317901595414796229127047082707519
    6. #p = 2 * a * g + 1
    7. #tn = 2*a1*a2*g**2 + (a1+a2)*g
    8. #WP 直接分解
    9. p=21007149684731457068332113266097775916630249079230293735684085460145700796880956996855348862572729597251282134827276249945199994121834609654781077209340587
    10. q = n//p
    11. print(long_to_bytes(pow(c,invert(e,(p-1)*(q-1)),n)))

    leak_rsa 未完成

    这个给出了p和q的42%的位,想爆破,但也没成功

    1. from Crypto.Util.number import getPrime, inverse, bytes_to_long
    2. from secret import flag
    3. from random import randint
    4. from math import floor
    5. def hint(p, length, upper):
    6. gift = {}
    7. pstr = bin(p)[2:].zfill(upper + 1)
    8. for i in range(length):
    9. idx = randint(1, upper)
    10. if idx not in gift:
    11. gift[idx] = pstr[idx]
    12. return gift
    13. p = getPrime(512)
    14. q = getPrime(512)
    15. n = p * q
    16. e = getPrime(32)
    17. d = inverse(e, (p - 1) * (q - 1))
    18. c = pow(bytes_to_long(flag), e, n)
    19. hint1 = hint(p, floor(0.42 * p.bit_length()), 511)
    20. hint2 = hint(q, floor(0.42 * q.bit_length()), 511)
    21. hint3 = hint(d, floor(0.42 * d.bit_length()), 1023)
    22. print("n =", n)
    23. print("e =", e)
    24. print("c =", c)
    25. print("hint1 =", hint1)
    26. print("hint2 =", hint2)
    27. print("hint3 =", hint3)

    爆破脚本,小数试过,题目不成

    1. n = 73380160475470842653695210816683702314062827937540324056880543809752271506601290265975543542548117392788987830919581511428492717214125296973338501980504384307279414528799452106399062576988406269897425829853390463840834798274139351938197666753546672052277640048588091137812362810008344723302886421059831149393
    2. e = 3116872133
    3. c = 69574121902821459446683688068339366486115223765903849266663001038736496551168104587683366853482649748413400537793260948337629422998336301256862519087984048032673577462034223842650399943613576577927825123830629917138007035313624847266208032195071033675853881447717750353382112841885318776240405314057286867952
    4. hint1 = {120: '0', 401: '0', 58: '1', 420: '0', 192: '1', 164: '0', 100: '0', 425: '1', 227: '0', 497: '0', 284: '0', 110: '1', 257: '0', 31: '1', 68: '0', 2: '1', 206: '0', 174: '1', 326: '0', 320: '0', 498: '1', 50: '1', 7: '0', 128: '1', 54: '1', 15: '1', 222: '0', 166: '1', 496: '1', 151: '1', 317: '0', 449: '1', 181: '1', 288: '1', 311: '1', 80: '1', 69: '1', 410: '1', 127: '1', 308: '1', 39: '0', 435: '0', 258: '0', 235: '1', 94: '1', 93: '1', 412: '0', 427: '0', 352: '1', 123: '0', 25: '0', 316: '1', 3: '0', 88: '1', 390: '0', 72: '1', 450: '1', 397: '0', 309: '1', 487: '1', 207: '0', 234: '0', 144: '1', 229: '1', 48: '1', 506: '0', 253: '1', 86: '0', 384: '0', 428: '0', 359: '1', 104: '0', 339: '0', 142: '0', 452: '1', 480: '0', 224: '1', 310: '1', 98: '1', 508: '0', 133: '0', 90: '1', 170: '0', 146: '0', 101: '1', 416: '1', 460: '1', 387: '0', 67: '0', 285: '0', 213: '1', 162: '1', 14: '0', 485: '1', 413: '1', 312: '1', 458: '0', 75: '0', 242: '1', 177: '1', 30: '1', 501: '0', 434: '1', 456: '0', 264: '0', 407: '0', 135: '1', 84: '0', 476: '0', 471: '1', 430: '1', 191: '0', 176: '0', 29: '1', 156: '0', 26: '0', 322: '1', 388: '1', 364: '1', 321: '1', 351: '0', 230: '1', 345: '0', 432: '1', 36: '0', 296: '1', 79: '0', 23: '0', 290: '1', 117: '0', 507: '1', 421: '0', 274: '0', 6: '1', 327: '1', 204: '1', 383: '0', 305: '1', 113: '0', 334: '0', 85: '1', 511: '1', 464: '1', 491: '0', 370: '0', 92: '0', 495: '0', 279: '1', 346: '1', 16: '1', 44: '1', 24: '0', 466: '1', 87: '0', 243: '0', 461: '0', 379: '0', 256: '0', 473: '1', 17: '0', 276: '1', 147: '1', 187: '0', 112: '1', 218: '1', 78: '1', 411: '1', 343: '0', 10: '1', 271: '1', 378: '0', 492: '0', 269: '1', 291: '0', 289: '0', 132: '1', 9: '1', 408: '0', 398: '1', 468: '1', 124: '1', 236: '0', 377: '1', 83: '0'}
    5. hint2 = {125: '0', 86: '1', 8: '0', 498: '1', 311: '0', 93: '0', 385: '0', 315: '1', 300: '1', 454: '0', 152: '0', 205: '0', 400: '1', 348: '1', 18: '1', 154: '0', 51: '1', 435: '0', 25: '1', 430: '0', 72: '1', 136: '0', 294: '0', 466: '0', 388: '0', 428: '0', 440: '1', 250: '1', 506: '0', 48: '0', 270: '1', 318: '0', 107: '0', 327: '1', 474: '0', 325: '0', 281: '0', 392: '0', 473: '1', 13: '1', 90: '0', 278: '0', 425: '0', 109: '1', 423: '1', 412: '1', 190: '1', 171: '0', 475: '1', 441: '1', 336: '0', 371: '0', 323: '0', 22: '1', 469: '0', 451: '0', 438: '0', 203: '1', 121: '0', 52: '1', 494: '1', 399: '0', 314: '0', 24: '1', 183: '0', 492: '1', 246: '1', 108: '1', 379: '0', 460: '1', 56: '0', 372: '1', 313: '1', 44: '0', 237: '1', 12: '0', 6: '0', 204: '1', 80: '1', 339: '1', 296: '0', 483: '0', 402: '0', 67: '0', 338: '1', 116: '0', 406: '1', 218: '0', 115: '0', 301: '0', 490: '1', 502: '0', 343: '1', 46: '1', 321: '0', 231: '1', 88: '0', 404: '1', 426: '0', 344: '0', 123: '1', 463: '0', 45: '1', 461: '1', 1: '0', 229: '0', 28: '1', 274: '1', 134: '1', 104: '1', 21: '0', 256: '0', 471: '1', 157: '0', 217: '1', 158: '0', 307: '1', 26: '0', 255: '0', 386: '1', 373: '0', 114: '1', 360: '0', 148: '1', 383: '1', 63: '0', 19: '1', 472: '0', 201: '1', 262: '1', 47: '0', 221: '0', 310: '0', 352: '1', 224: '1', 185: '0', 214: '1', 285: '1', 410: '0', 455: '0', 445: '0', 464: '0', 284: '1', 503: '1', 298: '1', 449: '0', 477: '0', 376: '0', 16: '0', 133: '0', 177: '1', 210: '0', 364: '1', 163: '1', 213: '1', 295: '1', 111: '1', 458: '0', 146: '0', 244: '0', 261: '1', 508: '1', 106: '0', 112: '1', 120: '0', 156: '1', 303: '0', 259: '1', 35: '0', 444: '0', 215: '1', 304: '0', 140: '0', 351: '0', 443: '0'}
    6. hint3 = {891: '0', 74: '0', 129: '0', 477: '0', 880: '1', 57: '0', 473: '0', 289: '1', 361: '1', 1012: '0', 529: '0', 294: '1', 174: '1', 500: '0', 257: '1', 392: '1', 405: '1', 11: '0', 763: '1', 637: '1', 564: '0', 941: '1', 923: '1', 1014: '1', 670: '1', 558: '0', 304: '1', 444: '1', 716: '0', 208: '0', 130: '1', 634: '1', 661: '0', 862: '0', 412: '1', 796: '1', 761: '1', 113: '1', 752: '0', 818: '0', 797: '1', 390: '1', 337: '0', 133: '1', 367: '1', 470: '1', 345: '1', 170: '1', 312: '0', 624: '1', 53: '1', 75: '1', 281: '1', 522: '1', 100: '0', 554: '1', 583: '1', 16: '1', 836: '0', 715: '1', 450: '0', 484: '0', 876: '0', 165: '0', 842: '0', 62: '0', 442: '1', 927: '0', 586: '1', 399: '1', 227: '0', 886: '1', 663: '0', 947: '0', 906: '1', 377: '0', 246: '1', 365: '0', 177: '1', 59: '1', 63: '0', 936: '1', 144: '0', 416: '1', 228: '1', 366: '0', 117: '0', 78: '0', 717: '1', 14: '0', 800: '1', 47: '0', 80: '0', 34: '0', 662: '1', 970: '0', 986: '1', 287: '1', 597: '0', 783: '0', 805: '1', 112: '1', 671: '1', 540: '1', 153: '1', 577: '1', 543: '0', 414: '0', 123: '1', 626: '1', 452: '1', 810: '1', 30: '0', 905: '0', 602: '1', 537: '1', 374: '0', 408: '1', 434: '0', 137: '1', 532: '0', 397: '0', 333: '1', 258: '1', 359: '1', 134: '1', 322: '1', 653: '0', 1018: '0', 639: '1', 40: '1', 826: '1', 489: '0', 5: '0', 858: '0', 44: '1', 516: '0', 149: '0', 945: '0', 106: '1', 694: '0', 221: '0', 207: '0', 186: '1', 316: '0', 449: '1', 297: '1', 276: '0', 103: '0', 437: '0', 802: '0', 108: '1', 921: '1', 427: '0', 728: '1', 879: '0', 953: '0', 51: '1', 459: '0', 37: '0', 559: '0', 610: '1', 341: '0', 299: '0', 952: '0', 201: '0', 327: '0', 741: '1', 253: '1', 310: '1', 946: '1', 696: '0', 398: '1', 266: '1', 829: '0', 908: '0', 469: '0', 873: '1', 658: '0', 798: '1', 54: '0', 621: '0', 238: '0', 654: '1', 205: '0', 925: '0', 391: '1', 480: '0', 4: '0', 598: '0', 677: '0', 142: '1', 606: '0', 118: '0', 164: '0', 973: '1', 347: '0', 159: '1', 307: '1', 83: '1', 668: '1', 675: '0', 924: '1', 191: '1', 890: '0', 352: '1', 965: '1', 692: '1', 782: '1', 817: '1', 889: '1', 515: '1', 433: '0', 356: '0', 845: '1', 104: '0', 18: '0', 979: '0', 426: '0', 785: '1', 546: '0', 52: '0', 55: '0', 824: '1', 704: '1', 510: '1', 710: '0', 1022: '0', 647: '0', 465: '1', 245: '0', 850: '1', 657: '0', 1007: '0', 807: '1', 158: '1', 328: '0', 292: '1', 355: '1', 596: '0', 275: '1', 371: '0', 1004: '0', 594: '0', 384: '1', 446: '1', 7: '0', 994: '1', 616: '1', 317: '0', 305: '0', 151: '1', 400: '0', 900: '1', 203: '0', 563: '1', 745: '1', 536: '1', 726: '0', 751: '1', 402: '1', 116: '0', 781: '1', 988: '0', 768: '1', 688: '1', 954: '1', 976: '1', 868: '1', 723: '1', 131: '1', 794: '0', 513: '0', 914: '1', 641: '1', 319: '0', 629: '1', 620: '1', 711: '0', 601: '0', 531: '0', 393: '0', 168: '0', 132: '0', 17: '0', 950: '0', 488: '0', 679: '0', 568: '0', 43: '1', 545: '1', 217: '0', 680: '1', 501: '1', 1008: '0', 514: '0', 746: '0', 187: '0', 436: '1', 336: '1', 139: '1', 338: '0', 695: '1', 300: '0', 584: '1', 152: '0', 828: '1', 251: '0', 691: '1', 296: '1', 128: '0', 394: '1', 655: '1', 544: '1', 58: '0', 313: '1', 565: '1', 685: '1', 720: '0', 178: '1', 667: '0', 403: '1', 697: '1', 138: '1', 659: '0', 960: '0', 454: '0', 271: '0', 33: '0', 295: '0', 600: '0', 579: '1', 68: '1', 211: '1', 82: '1', 114: '1', 209: '0', 226: '0', 753: '0', 874: '0', 903: '1', 358: '0', 141: '0', 236: '1'}
    7. nbits = 511
    8. #爆破得到p,q
    9. def get_pq(tp,tq, idx):
    10. #print(idx)
    11. if idx<100:
    12. print(idx, hex(tp),hex(tq))
    13. if tp*tq == n:
    14. print('OK-------->',tp,tq)
    15. exit()
    16. if idx>=nbits:
    17. return
    18. if ((tp*tq)^n)&((1<1) != 0:
    19. return False
    20. b = nbits-idx
    21. if b in hint1:
    22. tp+= int(hint1[b])<
    23. #print('h1', hint1[b])
    24. if b in hint2:
    25. #print('h2', hint2[b])
    26. tq += int(hint2[b])<
    27. get_pq(tp,tq, idx+1)
    28. else:
    29. tq1 = tq
    30. tq2 = tq + (1<
    31. get_pq(tp,tq1, idx+1)
    32. get_pq(tp,tq2, idx+1)
    33. else:
    34. if b in hint2:
    35. #print('h2', hint2[b])
    36. tq += int(hint2[b])<
    37. tp1 = tp
    38. tp2 = tp + (1<
    39. get_pq(tp1,tq, idx+1)
    40. get_pq(tp2,tq, idx+1)
    41. else:
    42. tp1 = tp
    43. tp2 = tp + (1<
    44. tq1 = tq
    45. tq2 = tq + (1<
    46. get_pq(tp1,tq1, idx+1)
    47. get_pq(tp1,tq2, idx+1)
    48. get_pq(tp2,tq1, idx+1)
    49. get_pq(tp2,tq2, idx+1)
    50. return False
    51. '''
    52. >>> bin(865579743731)[2:].zfill(40)
    53. '1100100110001000100100101011100111110011'
    54. >>> bin(749495783639)[2:].zfill(40)
    55. '1010111010000001011011100001000011010111'
    56. ^ ^ ^ ^
    57. hint1 = {12: '1', 22: '1', 2: '0', 25: '0', 29: '0', 8: '1', 36: '0', 16: '1', 5: '0', 28: '1', 11: '0', 21: '0', 18: '0', 32: '1'}
    58. hint2 = {26: '0', 15: '1', 19: '0', 7: '0', 12: '0', 14: '0', 24: '0', 3: '0', 8: '1', 30: '0', 27: '1', 11: '0', 17: '1', 10: '0'}
    59. n = 648748368329710642617109
    60. nbits = 39
    61. '''
    62. get_pq((1<1,(1<1,1)

     

    tracing

    题目就是个简单的rsa,但对gcd(phi,e)进行了tracing

    1. from secret import p, q, flag
    2. from Crypto.Util.number import bytes_to_long
    3. def gcd(a, b):
    4. s = 0
    5. while b != 0:
    6. print(a, b)
    7. if isOdd(a):
    8. if isOdd(b):
    9. a = a - b
    10. a = rshift1(a)
    11. if a < b:
    12. a, b = b, a
    13. else:
    14. b = rshift1(b)
    15. if a < b:
    16. a, b = b, a
    17. else:
    18. if isOdd(b):
    19. a = rshift1(a)
    20. if a < b:
    21. a, b = b, a
    22. else:
    23. a = rshift1(a) #同为偶数运行不到
    24. b = rshift1(b)
    25. s += 1
    26. if s:
    27. return lshift(a, s)
    28. return a
    29. def isOdd(a):
    30. return a & 1 == 1
    31. def rshift1(a):
    32. return a >> 1
    33. def lshift(a, s):
    34. return a << s
    35. n = p * q
    36. e = 65537
    37. phi = (p - 1) * (q - 1)
    38. assert gcd(phi, e) == 1
    39. c = pow(bytes_to_long(flag), e, n)
    40. print(c)
    41. print(n)

    在700多行的位置有gcd的内容

    1. task.py(30): def isOdd(a):
    2. task.py(33): def rshift1(a):
    3. task.py(36): def lshift(a, s):
    4. task.py(40): n = p * q
    5. task.py(41): e = 65537
    6. task.py(42): phi = (p - 1) * (q - 1)
    7. task.py(43): assert gcd(phi, e) == 1
    8. --- modulename: task, funcname: gcd
    9. task.py(5): s = 0
    10. task.py(6): while b != 0:
    11. task.py(7): if isOdd(a):
    12. --- modulename: task, funcname: isOdd
    13. task.py(31): return a & 1 == 1
    14. task.py(18): if isOdd(b):
    15. --- modulename: task, funcname: isOdd
    16. task.py(31): return a & 1 == 1
    17. task.py(19): a = rshift1(a)
    18. --- modulename: task, funcname: rshift1
    19. task.py(34): return a >> 1
    20. task.py(20): if a < b:
    21. task.py(6): while b != 0:
    22. task.py(7): if isOdd(a):

     显然它这个运行到的流程就是它作的判断过程,不过判断本身没有,执行的操作才有用。把涉及到9,10,12,14,16,19,21,28行的操作过滤出来,然后把逆向操作就能把phi,e从1,0逆回到原始状态

    1. op = [9,10,12,14,16,19,21,28]
    2. sop = [(str(i)+')')[:2] for i in op]
    3. print(sop)
    4. lines = open('4_trace.out').read().split('\n')
    5. ostr = []
    6. for i,line in enumerate(lines):
    7. if not line.startswith('task.py('):
    8. continue
    9. if line[8:10] in sop:
    10. ostr.append(line[12:].strip())
    11. #print(ostr)
    12. cmd = 'a,b = 1,0\n'
    13. for o in ostr[::-1]:
    14. if o == 'a = a - b':
    15. cmd += "a +=b\n"
    16. elif o == 'a = rshift1(a)':
    17. cmd += "a <<=1\n"
    18. elif o == 'a, b = b, a':
    19. cmd += "a, b = b, a\n"
    20. elif o == 'b = rshift1(b)':
    21. cmd += "b <<=1\n"
    22. elif o == 'return a':
    23. pass
    24. else:
    25. print('XXXX',o)
    26. cmd+= 'print(a,b)\n'
    27. open('a4_a.py', 'w').write(cmd)

    把这些操作写成的脚本是这样的

    1. a,b = 1,0
    2. a, b = b, a
    3. a <<=1
    4. a +=b
    5. a <<=1
    6. a <<=1
    7. a <<=1
    8. a +=b
    9. b <<=1
    10. b <<=1
    11. a, b = b, a
    12. a <<=1
    13. a +=b
    14. a <<=1
    15. a +=b
    16. a <<=1
    17. a <<=1
    18. a +=b
    19. b <<=1
    20. b <<=1
    21. a, b = b, a
    22. a <<=1
    23. a +=b
    24. a, b = b, a
    25. a <<=1
    26. ...以下略...
    27. print(a,b)

     得到phi后就能直接操作得到flag 了

    1. phi = 113793513490894881175568252406666081108916791207947545198428641792768110581083359318482355485724476407204679171578376741972958506284872470096498674038813744206060043230633366541996120990867169768523014939944773017185662017479011094588132516102178922759206005551241577259317764398494195585166584573218495824732
    2. e = 65537
    3. c = 64885875317556090558238994066256805052213864161514435285748891561779867972960805879348109302233463726130814478875296026610171472811894585459078460333131491392347346367422276701128380739598873156279173639691126814411752657279838804780550186863637510445720206103962994087507407296814662270605713097055799853102
    4. n = 113793513490894881175568252406666081108916791207947545198428641792768110581083359318482355485724476407204679171578376741972958506284872470096498674038813765700336353715590069074081309886710425934960057225969468061891326946398492194812594219890553185043390915509200930203655022420444027841986189782168065174301
    5. from gmpy2 import invert
    6. d = invert(e,phi)
    7. m = pow(c,d,n)
    8. print(bytes.fromhex(hex(m)[2:]))

    fill

    这个题前边是个LCG求参数,后边是背包问题,小LCG,小背包,都比较容易。

    1. from Crypto.Util.number import *
    2. from random import *
    3. from gmpy2 import gcd
    4. from numpy import dot
    5. nbits = 32
    6. msg = getRandomNBitInteger(nbits)
    7. flag = b'flag{sha256(msg)}'
    8. tmp_m = bin(msg)[2:]
    9. f_list = []
    10. for i in range(len(tmp_m)):
    11. f_list.append(int(tmp_m[i]))
    12. r_list =[randint(20, 50)]
    13. for i in range(nbits - 1):
    14. r_list.append(randint(2 * r_list[-1], 3 * r_list[-1]))
    15. while True:
    16. A = randint(2 * r_list[-1] + 1, 3 * r_list[-1])
    17. B = randint(2 * r_list[-1] + 1, 3 * r_list[-1])
    18. if gcd(A, B) == 1:
    19. break
    20. M = [A * x % B for x in r_list]
    21. S = dot(f_list, M)
    22. print(S)
    23. seed = getRandomNBitInteger(30)
    24. s = [0] * nbits
    25. s[0] = seed
    26. m = getRandomNBitInteger(20)
    27. c = getPrime(24)
    28. n = 991125622
    29. for i in range(1, nbits):
    30. s[i] = (s[i-1]*m+c)%n
    31. print(s[0], s[1], s[2])
    32. for t in range(nbits):
    33. M[t] = M[t] + s[t]
    34. print(M)
    35. '''
    36. 492226042629702
    37. 562734112 859151551 741682801
    38. M = [19621141192340, 39617541681643, 3004946591889, 6231471734951, 3703341368174, 48859912097514, 4386411556216, 11028070476391, 18637548953150, 29985057892414, 20689980879644, 20060557946852, 46908191806199, 8849137870273, 28637782510640, 35930273563752, 20695924342882, 36660291028583, 10923264012354, 29810154308143, 4444597606142, 31802472725414, 23368528779283, 15179021971456, 34642073901253, 44824809996134, 31243873675161, 27159321498211, 2220647072602, 20255746235462, 24667528459211, 46916059974372]
    39. '''

    先求LCG的参数a,b,然后通过得到的s还原M

    1. from gmpy2 import *
    2. nbits = 32
    3. S = 492226042629702
    4. n = 991125622
    5. s =[562734112, 859151551, 741682801]
    6. M = [19621141192340, 39617541681643, 3004946591889, 6231471734951, 3703341368174, 48859912097514, 4386411556216, 11028070476391, 18637548953150, 29985057892414, 20689980879644, 20060557946852, 46908191806199, 8849137870273, 28637782510640, 35930273563752, 20695924342882, 36660291028583, 10923264012354, 29810154308143, 4444597606142, 31802472725414, 23368528779283, 15179021971456, 34642073901253, 44824809996134, 31243873675161, 27159321498211, 2220647072602, 20255746235462, 24667528459211, 46916059974372]
    7. '''
    8. for i in range(1, nbits):
    9. s[i] = (s[i-1]*m+c)%n
    10. '''
    11. #LCG求a,b
    12. m = (s[2]-s[1])*invert((s[1]-s[0]),n) %n
    13. c = (s[1]-s[0]*m )%n
    14. for i in range(3,32):
    15. s.append(int(s[i-1]*m + c)%n)
    16. #还原M
    17. for t in range(nbits):
    18. M[t] = M[t] - s[t]
    19. M = [19620578458228, 39616682530092, 3004204909088, 6231457508054, 3702963666023, 48859283851499, 4385984544187, 11027662187202, 18637179189873, 29985033726663, 20689315151593, 20060155940897, 46908062454518, 8848251127828, 28637097081675, 35930247189963, 20695167327567, 36659598017280, 10923228050453, 29810039803392, 4443991557077, 31801732862419, 23368424737916, 15178683835989, 34641771567914, 44824471397533, 31243260877608, 27158599500744, 2219939459559, 20255089091807, 24667494760808, 46915118179747]

     然后用sagemath求背包的解,最后作sha256

    1. #sage
    2. #背包加密
    3. A = Matrix(ZZ, nbits + 1, nbits + 1)
    4. for i in range(nbits):
    5. A[i, i] = 1
    6. A[i, nbits] = M[i]
    7. A[nbits,nbits] = -int(S)
    8. res = A.LLL()
    9. for i in range(0, nbits + 1):
    10. # print solution
    11. M = res.row(i).list()
    12. flag = True
    13. for m in M:
    14. if m != 0 and m != 1:
    15. flag = False
    16. break
    17. if flag:
    18. print(i, M)
    19. M = ''.join(str(j) for j in M)
    20. # remove the last bit
    21. M = M[:-1] #矩阵是n+1行,结果是n+1个值,最后一个去掉
    22. m = int(M, 2)
    23. print(m)
    24. m = 3617517412
    25. #flag = b'flag{sha256(msg)}'
    26. #flag{8f504aee71626212f275117326722b6c0ccc94f4039ed31fbcfde08e026352c4}

    fermat

    最后一题名字叫费马,一开始是q=p+A说明两数相差很小,可以分解,分解得到p和q之后作了个异或加密,异或的x有114514**x %p == 1 虽然说费马定理不能证明必要性但这里也没什么别的方法了,只能相信x=p-1,然后就出多半个flag和一堆乱码,百思不得其解。

    1. from Crypto.Util.number import *
    2. from random import *
    3. from libnum import *
    4. import gmpy2
    5. from secret import x
    6. flag = b'?????????'
    7. m = bytes_to_long(flag)
    8. def obfuscate(p, k):
    9. nbit = p.bit_length()
    10. while True:
    11. l1 = [getRandomRange(-1, 1) for _ in '_' * k]
    12. l2 = [getRandomRange(100, nbit) for _ in '_' * k]
    13. l3 = [getRandomRange(10, nbit//4) for _ in '_' * k]
    14. l4 = [getRandomRange(2, 6) for _ in '_' *k]
    15. A = sum([l1[_] * 2 ** ((l2[_]+l3[_])//l4[_]) for _ in range(0, k)])
    16. q = p + A
    17. if isPrime(q) * A != 0:
    18. return q
    19. p = getPrime(512)
    20. q = obfuscate(p, 5)
    21. e = 65537
    22. n = p*q
    23. print(f'n = {n}')
    24. assert 114514 ** x % p == 1
    25. m = m ^ (x**2)
    26. c = pow(m, e, n)
    27. print(f'c = {c}')
    28. '''
    29. n = 141321067325716426375483506915224930097246865960474155069040176356860707435540270911081589751471783519639996589589495877214497196498978453005154272785048418715013714419926299248566038773669282170912502161620702945933984680880287757862837880474184004082619880793733517191297469980246315623924571332042031367393
    30. c = 81368762831358980348757303940178994718818656679774450300533215016117959412236853310026456227434535301960147956843664862777300751319650636299943068620007067063945453310992828498083556205352025638600643137849563080996797888503027153527315524658003251767187427382796451974118362546507788854349086917112114926883
    31. '''

    其实这里的p,q可以通过大小来确定的(q=p+sum(...)),而题目说的确实是p,后来发现题目第1个参数是个正负号,sum之后确实会出现负数,是我脑子不走了。

    1. '''
    2. yafu
    3. ***factors found***
    4. P155 = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734648016476153593841839977704512156756634066593725142934001
    5. P155 = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734646483980612727952939084061619889139517526028673988305393
    6. '''
    7. #p
    8. p = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734646483980612727952939084061619889139517526028673988305393
    9. q = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734648016476153593841839977704512156756634066593725142934001
    10. n = 141321067325716426375483506915224930097246865960474155069040176356860707435540270911081589751471783519639996589589495877214497196498978453005154272785048418715013714419926299248566038773669282170912502161620702945933984680880287757862837880474184004082619880793733517191297469980246315623924571332042031367393
    11. e = 65537
    12. c = 81368762831358980348757303940178994718818656679774450300533215016117959412236853310026456227434535301960147956843664862777300751319650636299943068620007067063945453310992828498083556205352025638600643137849563080996797888503027153527315524658003251767187427382796451974118362546507788854349086917112114926883
    13. from gmpy2 import *
    14. from Crypto.Util.number import long_to_bytes
    15. d = invert(e, (p-1)*(q-1))
    16. m = pow(c,d,n)
    17. print(long_to_bytes(int(m))) #x != 0
    18. #114514 ** x % p == 1 => x = p-1
    19. m ^= (q-1)**2
    20. print(long_to_bytes(int(m)))
    21. #b'flag{I~ju5t_w@nt_30_te11_y0u_how_I_@m_f3ll1ng~}45108#@7++3@79?3328?!!@08#712/+963-60#9-/83#+/1@@=59!/84@?3#4!4=-9542/##'

  • 相关阅读:
    基于SpringBoot + Vue的学生成绩管理系统的设计与实现源码及搭建视频
    Nodejs 相关知识
    Vue2与Vue3:深度剖析核心差异与升级亮点
    【vue】在vue.config.js文件中导入模块
    125. 验证回文串
    让写代码燃起来!vscode插件Power Mode
    数据结构——排序【仅用于考试】
    微软的这个按钮又双叒叕变了位置?有时候还不见了……
    Java语言特性运用:各种Java语法特性是怎样被Spring各种版本巧妙运用的?-3
    时间复杂度
  • 原文地址:https://blog.csdn.net/weixin_52640415/article/details/127670711