目录
有几个差一点,看了个 Arr3stY0u 的WP,豁然开朗
原题是个DLP加密,输入g可对其加密,加密后如果是4则返回flag。
- import socketserver
- from time import sleep
- from secret import flag
- import signal
- import random
-
- from Crypto.Util.number import *
- import random
-
- #通过快速幂的方法求幂,每次通过4的状态设置t,泄露t
- #当返回值t==1时,说明这个密文经历过4
- def pow_d(g, e, n):
- t, r = 0, 1
- for _ in bin(e)[2:]:
- if r == 4: t += 1
- r = pow(r, 2, n)
- if _ == '1': r = r * g % n
- return t, r
-
- def ts(m, p):
- m = m % p
- return pow(m, (p - 1) // 2, p) == 1
- class Task(socketserver.BaseRequestHandler):
- def _recvall(self):
- BUFF_SIZE = 2048
- data = b''
- while True:
- part = self.request.recv(BUFF_SIZE)
- data += part
- if len(part) < BUFF_SIZE:
- break
- return data.strip()
-
- def send(self, msg, newline=True):
- try:
- if newline:
- msg += b'\n'
- self.request.sendall(msg)
- except:
- pass
-
- def recv(self):
- return self._recvall()
-
-
-
-
- def handle(self):
- border = b"|"
- self.send(border*72)
- self.send(border+b"Solve a DLP challenge in some special way to get the flag", border)
-
- p = 2 ** 1024 - 2 ** 234 - 2 ** 267 - 2 ** 291 - 2 ** 403 - 1
- s = random.randint(2, (p - 1) // 2)
-
- while True:
- self.send(s)
- self.send(b"| Options: \n|\t[T]ry the magic machine \n|\t[Q]uit")
- ans = self.recv().lower()
-
- if ans == b't':
- self.send(border+b"please send your desired integer: ")
- g = self.recv()
- try:
- g = int(g)
- except:
- self.send(border+b"The given input is not integer!")
- break
- sleep(0.3)
- if ts(g, p):
- t, r = pow_d(g, s, p)
- if r == 4:
- self.send(border+b'Great! you got the flag:'+flag)
- else:
- self.send(border+b"t, r = "+f"{t, r}".encode())
- else:
- self.send(border+"The given base is NOT valid!!!")
- elif ans == b'q':
- self.send(border+"Quitting ...")
- break
- else:
- self.send(border+"Bye bye ...")
- break
-
- '''
- DLP题由s进行加密
- c = g**s %p
- 可根据用户输入的g得到c, 求c=4时g
- '''
-
-
-
-
-
-
-
- class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
- pass
-
-
- class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
- pass
-
-
- if __name__ == "__main__":
- HOST, PORT = '0.0.0.0', 10001
- server = ForkedServer((HOST, PORT), Task)
- server.allow_reuse_address = True
- print(HOST, PORT)
- server.serve_forever()
这里边给了个t,r其中r是密文,t是表示在乘幂过程中是否有过结果是4的情况,一直不清楚怎么弄,看了WP才知道,正是这个t的泄露这题才能解。WP也没看大明白,先存一下,回头慢慢看
- from pwn import *
- from sage import *
- from Crypto.Util.number import *
-
- context.proxy = 'localhost'
-
- class Gao:
- def __init__(self):
- #self.conn = process(['python3', '1_DLP_chall.py'])
- self.conn = remote('101.201.71.136', 38476)
- self.p = 2 ** 1024 - 2 ** 234 - 2 ** 267 - 2 ** 291 - 2 ** 403 - 1
- self.s_high = 1
- self.Zp = Zmod(self.p)
- def gao_check(self):
- self.conn.sendline('T')
- ans = self.Zp(4).nth_root(self.s_high)
- print('Guessing: {}'.format(ans))
- self.conn.sendline(str(ans))
- self.conn.recvuntil('integer: n')
- a = self.conn.recvline()
- if ('Great!' in a):
- print(a)
- print(ZZ(ans).nbits())
- return True
- else:
- return False
-
- def gao_one(self):
- self.conn.sendline('T')
- ans = self.Zp(2).nth_root(self.s_high) #对2开s_high次幂
- self.conn.sendline(str(ans))
- self.conn.recvuntil('integer: n')
- a = self.conn.recvline()
- if ('Great!' in a):
- print(a)
- print(ZZ(ans).nbits())
- return True
- else:
- a = a[8:]
- t, r = eval(a)
- self.s_high <<= 1
- if (t == 0):
- self.s_high |= 1
- self.t = 1 - t
- print('{:b}'.format(self.s_high))
- return False
- def gao(self):
- while (True):
- if (self.gao_one()):
- break
- if (self.t == 1):
- if (self.gao_check()):
- break
- def gao_2(self):
- for i in range(1023):
- if (self.gao_one()):
- break
- else:
- for i in range(20):
- self.gao_check()
- self.s_high >>= 1
-
- if __name__ == '__main__':
- g = Gao()
- g.gao_2()
一直以来RSA的n从来没有分解成功过,这回也没有,不知道是不是yafu是不是真的。
- from Crypto.Util.number import getPrime, isPrime, bytes_to_long, inverse
- from math import lcm
- from secret import flag
-
- def gen(g):
- bits = 512 - g.bit_length()
- while True:
- a = getPrime(bits)
- p = 2 * a * g + 1
- if isPrime(p):
- return p
-
- flag = bytes_to_long(flag)
- g = getPrime(320)
- p = gen(g)
- q = gen(g)
- n = p * q
- d = getPrime(135)
- phi = lcm(p - 1, q - 1)
- e = inverse(d, phi)
- c = pow(flag, e, n)
- print("n = {}".format(n))
- print("e = {}".format(e))
- print("c = {}".format(c))
想分解n-1也没有成功,看WP说是直接分解。也就没啥说的了。
- from gmpy2 import invert
- from Crypto.Util.number import long_to_bytes
-
- n = 253784908428481171520644795825628119823506176672683456544539675613895749357067944465796492899363087465652749951069021248729871498716450122759675266109104893465718371075137027806815473672093804600537277140261127375373193053173163711234309619016940818893190549811778822641165586070952778825226669497115448984409
- e = 31406775715899560162787869974700016947595840438708247549520794775013609818293759112173738791912355029131497095419469938722402909767606953171285102663874040755958087885460234337741136082351825063419747360169129165
- c = 97724073843199563126299138557100062208119309614175354104566795999878855851589393774478499956448658027850289531621583268783154684298592331328032682316868391120285515076911892737051842116394165423670275422243894220422196193336551382986699759756232962573336291032572968060586136317901595414796229127047082707519
-
- #p = 2 * a * g + 1
- #tn = 2*a1*a2*g**2 + (a1+a2)*g
- #WP 直接分解
- p=21007149684731457068332113266097775916630249079230293735684085460145700796880956996855348862572729597251282134827276249945199994121834609654781077209340587
- q = n//p
- print(long_to_bytes(pow(c,invert(e,(p-1)*(q-1)),n)))
这个给出了p和q的42%的位,想爆破,但也没成功
- from Crypto.Util.number import getPrime, inverse, bytes_to_long
- from secret import flag
- from random import randint
- from math import floor
-
- def hint(p, length, upper):
- gift = {}
- pstr = bin(p)[2:].zfill(upper + 1)
- for i in range(length):
- idx = randint(1, upper)
- if idx not in gift:
- gift[idx] = pstr[idx]
- return gift
-
- p = getPrime(512)
- q = getPrime(512)
- n = p * q
- e = getPrime(32)
- d = inverse(e, (p - 1) * (q - 1))
- c = pow(bytes_to_long(flag), e, n)
- hint1 = hint(p, floor(0.42 * p.bit_length()), 511)
- hint2 = hint(q, floor(0.42 * q.bit_length()), 511)
- hint3 = hint(d, floor(0.42 * d.bit_length()), 1023)
- print("n =", n)
- print("e =", e)
- print("c =", c)
- print("hint1 =", hint1)
- print("hint2 =", hint2)
- print("hint3 =", hint3)
爆破脚本,小数试过,题目不成
- n = 73380160475470842653695210816683702314062827937540324056880543809752271506601290265975543542548117392788987830919581511428492717214125296973338501980504384307279414528799452106399062576988406269897425829853390463840834798274139351938197666753546672052277640048588091137812362810008344723302886421059831149393
- e = 3116872133
- c = 69574121902821459446683688068339366486115223765903849266663001038736496551168104587683366853482649748413400537793260948337629422998336301256862519087984048032673577462034223842650399943613576577927825123830629917138007035313624847266208032195071033675853881447717750353382112841885318776240405314057286867952
- 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'}
- 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'}
- 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'}
-
-
- nbits = 511
-
- #爆破得到p,q
- def get_pq(tp,tq, idx):
- #print(idx)
- if idx<100:
- print(idx, hex(tp),hex(tq))
- if tp*tq == n:
- print('OK-------->',tp,tq)
- exit()
-
- if idx>=nbits:
- return
-
- if ((tp*tq)^n)&((1<
1) != 0: - return False
-
- b = nbits-idx
- if b in hint1:
- tp+= int(hint1[b])<
- #print('h1', hint1[b])
- if b in hint2:
- #print('h2', hint2[b])
- tq += int(hint2[b])<
- get_pq(tp,tq, idx+1)
- else:
- tq1 = tq
- tq2 = tq + (1<
- get_pq(tp,tq1, idx+1)
- get_pq(tp,tq2, idx+1)
- else:
- if b in hint2:
- #print('h2', hint2[b])
- tq += int(hint2[b])<
- tp1 = tp
- tp2 = tp + (1<
- get_pq(tp1,tq, idx+1)
- get_pq(tp2,tq, idx+1)
- else:
- tp1 = tp
- tp2 = tp + (1<
- tq1 = tq
- tq2 = tq + (1<
- get_pq(tp1,tq1, idx+1)
- get_pq(tp1,tq2, idx+1)
- get_pq(tp2,tq1, idx+1)
- get_pq(tp2,tq2, idx+1)
- return False
-
- '''
- >>> bin(865579743731)[2:].zfill(40)
- '1100100110001000100100101011100111110011'
- >>> bin(749495783639)[2:].zfill(40)
- '1010111010000001011011100001000011010111'
- ^ ^ ^ ^
- 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'}
- 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'}
- n = 648748368329710642617109
- nbits = 39
- '''
- get_pq((1<
1,(1<1,1)
tracing
题目就是个简单的rsa,但对gcd(phi,e)进行了tracing
- from secret import p, q, flag
- from Crypto.Util.number import bytes_to_long
-
- def gcd(a, b):
- s = 0
- while b != 0:
- print(a, b)
- if isOdd(a):
- if isOdd(b):
- a = a - b
- a = rshift1(a)
- if a < b:
- a, b = b, a
- else:
- b = rshift1(b)
- if a < b:
- a, b = b, a
- else:
- if isOdd(b):
- a = rshift1(a)
- if a < b:
- a, b = b, a
- else:
- a = rshift1(a) #同为偶数运行不到
- b = rshift1(b)
- s += 1
- if s:
- return lshift(a, s)
- return a
-
- def isOdd(a):
- return a & 1 == 1
-
- def rshift1(a):
- return a >> 1
-
- def lshift(a, s):
- return a << s
-
-
- n = p * q
- e = 65537
- phi = (p - 1) * (q - 1)
- assert gcd(phi, e) == 1
- c = pow(bytes_to_long(flag), e, n)
- print(c)
- print(n)
在700多行的位置有gcd的内容
- task.py(30): def isOdd(a):
- task.py(33): def rshift1(a):
- task.py(36): def lshift(a, s):
- task.py(40): n = p * q
- task.py(41): e = 65537
- task.py(42): phi = (p - 1) * (q - 1)
- task.py(43): assert gcd(phi, e) == 1
- --- modulename: task, funcname: gcd
- task.py(5): s = 0
- task.py(6): while b != 0:
- task.py(7): if isOdd(a):
- --- modulename: task, funcname: isOdd
- task.py(31): return a & 1 == 1
- task.py(18): if isOdd(b):
- --- modulename: task, funcname: isOdd
- task.py(31): return a & 1 == 1
- task.py(19): a = rshift1(a)
- --- modulename: task, funcname: rshift1
- task.py(34): return a >> 1
- task.py(20): if a < b:
- task.py(6): while b != 0:
- task.py(7): if isOdd(a):
显然它这个运行到的流程就是它作的判断过程,不过判断本身没有,执行的操作才有用。把涉及到9,10,12,14,16,19,21,28行的操作过滤出来,然后把逆向操作就能把phi,e从1,0逆回到原始状态
- op = [9,10,12,14,16,19,21,28]
- sop = [(str(i)+')')[:2] for i in op]
- print(sop)
- lines = open('4_trace.out').read().split('\n')
- ostr = []
- for i,line in enumerate(lines):
- if not line.startswith('task.py('):
- continue
-
- if line[8:10] in sop:
- ostr.append(line[12:].strip())
-
- #print(ostr)
-
- cmd = 'a,b = 1,0\n'
- for o in ostr[::-1]:
- if o == 'a = a - b':
- cmd += "a +=b\n"
- elif o == 'a = rshift1(a)':
- cmd += "a <<=1\n"
- elif o == 'a, b = b, a':
- cmd += "a, b = b, a\n"
- elif o == 'b = rshift1(b)':
- cmd += "b <<=1\n"
- elif o == 'return a':
- pass
- else:
- print('XXXX',o)
-
- cmd+= 'print(a,b)\n'
- open('a4_a.py', 'w').write(cmd)
把这些操作写成的脚本是这样的
- a,b = 1,0
- a, b = b, a
- a <<=1
- a +=b
- a <<=1
- a <<=1
- a <<=1
- a +=b
- b <<=1
- b <<=1
- a, b = b, a
- a <<=1
- a +=b
- a <<=1
- a +=b
- a <<=1
- a <<=1
- a +=b
- b <<=1
- b <<=1
- a, b = b, a
- a <<=1
- a +=b
- a, b = b, a
- a <<=1
- ...以下略...
- print(a,b)
得到phi后就能直接操作得到flag 了
- phi = 113793513490894881175568252406666081108916791207947545198428641792768110581083359318482355485724476407204679171578376741972958506284872470096498674038813744206060043230633366541996120990867169768523014939944773017185662017479011094588132516102178922759206005551241577259317764398494195585166584573218495824732
- e = 65537
- c = 64885875317556090558238994066256805052213864161514435285748891561779867972960805879348109302233463726130814478875296026610171472811894585459078460333131491392347346367422276701128380739598873156279173639691126814411752657279838804780550186863637510445720206103962994087507407296814662270605713097055799853102
- n = 113793513490894881175568252406666081108916791207947545198428641792768110581083359318482355485724476407204679171578376741972958506284872470096498674038813765700336353715590069074081309886710425934960057225969468061891326946398492194812594219890553185043390915509200930203655022420444027841986189782168065174301
- from gmpy2 import invert
- d = invert(e,phi)
- m = pow(c,d,n)
- print(bytes.fromhex(hex(m)[2:]))
fill
这个题前边是个LCG求参数,后边是背包问题,小LCG,小背包,都比较容易。
- from Crypto.Util.number import *
- from random import *
- from gmpy2 import gcd
- from numpy import dot
-
- nbits = 32
- msg = getRandomNBitInteger(nbits)
- flag = b'flag{sha256(msg)}'
- tmp_m = bin(msg)[2:]
- f_list = []
- for i in range(len(tmp_m)):
- f_list.append(int(tmp_m[i]))
-
- r_list =[randint(20, 50)]
- for i in range(nbits - 1):
- r_list.append(randint(2 * r_list[-1], 3 * r_list[-1]))
-
- while True:
- A = randint(2 * r_list[-1] + 1, 3 * r_list[-1])
- B = randint(2 * r_list[-1] + 1, 3 * r_list[-1])
- if gcd(A, B) == 1:
- break
-
- M = [A * x % B for x in r_list]
-
- S = dot(f_list, M)
- print(S)
-
- seed = getRandomNBitInteger(30)
- s = [0] * nbits
- s[0] = seed
- m = getRandomNBitInteger(20)
- c = getPrime(24)
- n = 991125622
- for i in range(1, nbits):
- s[i] = (s[i-1]*m+c)%n
- print(s[0], s[1], s[2])
- for t in range(nbits):
- M[t] = M[t] + s[t]
- print(M)
-
-
- '''
- 492226042629702
- 562734112 859151551 741682801
- 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]
- '''
先求LCG的参数a,b,然后通过得到的s还原M
- from gmpy2 import *
-
- nbits = 32
- S = 492226042629702
- n = 991125622
- s =[562734112, 859151551, 741682801]
- 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]
-
- '''
- for i in range(1, nbits):
- s[i] = (s[i-1]*m+c)%n
- '''
- #LCG求a,b
- m = (s[2]-s[1])*invert((s[1]-s[0]),n) %n
- c = (s[1]-s[0]*m )%n
- for i in range(3,32):
- s.append(int(s[i-1]*m + c)%n)
- #还原M
- for t in range(nbits):
- M[t] = M[t] - s[t]
-
- 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
- #sage
- #背包加密
- A = Matrix(ZZ, nbits + 1, nbits + 1)
- for i in range(nbits):
- A[i, i] = 1
- A[i, nbits] = M[i]
- A[nbits,nbits] = -int(S)
-
- res = A.LLL()
- for i in range(0, nbits + 1):
- # print solution
- M = res.row(i).list()
- flag = True
- for m in M:
- if m != 0 and m != 1:
- flag = False
- break
- if flag:
- print(i, M)
- M = ''.join(str(j) for j in M)
- # remove the last bit
- M = M[:-1] #矩阵是n+1行,结果是n+1个值,最后一个去掉
- m = int(M, 2)
- print(m)
-
- m = 3617517412
- #flag = b'flag{sha256(msg)}'
- #flag{8f504aee71626212f275117326722b6c0ccc94f4039ed31fbcfde08e026352c4}
fermat
最后一题名字叫费马,一开始是q=p+A说明两数相差很小,可以分解,分解得到p和q之后作了个异或加密,异或的x有114514**x %p == 1 虽然说费马定理不能证明必要性但这里也没什么别的方法了,只能相信x=p-1,然后就出多半个flag和一堆乱码,百思不得其解。
- from Crypto.Util.number import *
- from random import *
- from libnum import *
- import gmpy2
- from secret import x
-
- flag = b'?????????'
- m = bytes_to_long(flag)
- def obfuscate(p, k):
- nbit = p.bit_length()
- while True:
- l1 = [getRandomRange(-1, 1) for _ in '_' * k]
- l2 = [getRandomRange(100, nbit) for _ in '_' * k]
- l3 = [getRandomRange(10, nbit//4) for _ in '_' * k]
- l4 = [getRandomRange(2, 6) for _ in '_' *k]
- A = sum([l1[_] * 2 ** ((l2[_]+l3[_])//l4[_]) for _ in range(0, k)])
- q = p + A
- if isPrime(q) * A != 0:
- return q
-
- p = getPrime(512)
- q = obfuscate(p, 5)
- e = 65537
- n = p*q
- print(f'n = {n}')
-
- assert 114514 ** x % p == 1
- m = m ^ (x**2)
- c = pow(m, e, n)
- print(f'c = {c}')
-
- '''
- n = 141321067325716426375483506915224930097246865960474155069040176356860707435540270911081589751471783519639996589589495877214497196498978453005154272785048418715013714419926299248566038773669282170912502161620702945933984680880287757862837880474184004082619880793733517191297469980246315623924571332042031367393
- c = 81368762831358980348757303940178994718818656679774450300533215016117959412236853310026456227434535301960147956843664862777300751319650636299943068620007067063945453310992828498083556205352025638600643137849563080996797888503027153527315524658003251767187427382796451974118362546507788854349086917112114926883
- '''
其实这里的p,q可以通过大小来确定的(q=p+sum(...)),而题目说的确实是p,后来发现题目第1个参数是个正负号,sum之后确实会出现负数,是我脑子不走了。
- '''
- yafu
- ***factors found***
- P155 = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734648016476153593841839977704512156756634066593725142934001
- P155 = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734646483980612727952939084061619889139517526028673988305393
- '''
- #p
- p = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734646483980612727952939084061619889139517526028673988305393
- q = 11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734648016476153593841839977704512156756634066593725142934001
-
- n = 141321067325716426375483506915224930097246865960474155069040176356860707435540270911081589751471783519639996589589495877214497196498978453005154272785048418715013714419926299248566038773669282170912502161620702945933984680880287757862837880474184004082619880793733517191297469980246315623924571332042031367393
- e = 65537
- c = 81368762831358980348757303940178994718818656679774450300533215016117959412236853310026456227434535301960147956843664862777300751319650636299943068620007067063945453310992828498083556205352025638600643137849563080996797888503027153527315524658003251767187427382796451974118362546507788854349086917112114926883
-
- from gmpy2 import *
- from Crypto.Util.number import long_to_bytes
- d = invert(e, (p-1)*(q-1))
- m = pow(c,d,n)
-
- print(long_to_bytes(int(m))) #x != 0
- #114514 ** x % p == 1 => x = p-1
- m ^= (q-1)**2
-
- print(long_to_bytes(int(m)))
- #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