2023CCTF复现计划(持续更新中)

2023CCTF复现计划(持续更新中)barak P 0 1 Q

大家好,我是讯享网,很高兴认识大家。

barak

P = (0, ,1) Q = (, 0,1) from Crypto.Util.number import * import gmpy2 from tqdm import tqdm p =  d =  c = 1 E = (c, d, p) PR.<x,y,z> = Zmod(p)[] cubic = x3 - d*x*y*z + z^3 + y^3 E = EllipticCurve_from_cubic(cubic, P, morphism=True) # PP = E(P)  = E(Q) # # m = discrete_log(,PP,operation = "+") # print(m) m =  print(long_to_bytes(m)) for i in tqdm(range()): M = m + i*int(PP.order()) if all(30<j<125 for j in long_to_bytes(M)): print(long_to_bytes(M)) # break print("Finished")

讯享网

blue_office

讯享网import binascii from Crypto.Util.number import * import gmpy2 from tqdm import tqdm enc = b'b0cbf8a5ab20fff89a71bbc4ed2d57142e05f39d434fce' enc = int(enc,16) def dereseed(s): return (s-)// # print(long_to_bytes(enc)[0]) S = bytes_to_long(b'C') ^ long_to_bytes(enc)[0] print(long_to_bytes(enc)[0]) print(0xb0) def reseed(s): return s *  +  for i in tqdm(range(216)): s = (S<<16) + i k = [] k.append(s) for x in range(30): s = reseed(s) k.append(s) m = b'C' # if (long_to_bytes(enc)[2] ^ ((k[1] >> 16) & 0xff)).to_bytes(1, 'big') == b'C': # print(i) for j in range(len(long_to_bytes(enc))): m += (long_to_bytes(enc)[j] ^ ((k[j] >> 16) & 0xff)).to_bytes(1, 'big') if b'CCTF' in m: print(m) 

Derik

from Crypto.Util.number import * import gmpy2 from z3 import * C = [000, 00, 00, , 0, 0000, 10543, 4] c = 0000 O = [49983, 89518, 319, 31337] e = 3 d = (C[6]*e - O[3])//C[7] print(d) S = gmpy2.gcdext(C[1],C[2]) Solve = Solver() p,q,r = Reals('p q r') Solve.add(C[0]*p - C[1]*q == O[0]) Solve.add(C[2]*q - C[3]*r == O[1]) Solve.add(C[4]*r - C[5]*p == O[2]) Solve.check() a = Solve.model() print(a) q = 0 r = 000 p =  n = e*d*q*p*r phi = (e-1)*(q-1)*(p-1)*(r-1)*(d-1) D = gmpy2.invert(65537,phi) print(long_to_bytes(gmpy2.powmod(c,D,n)))

DId it!

讯享网from pwn import * from random import randint import sys # context.log_level = 'Debug' while True: c = remote('01.cr.yp.toc.tf',11337) c.recvuntil(b'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') c.recvuntil(b'+ .:: Hi all, she DID it, you should do it too! Are you ready? ::. +') c.recvuntil(b'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') n, l = 127, 20 cnt, STEP = 0, 2 * n // l - 1 m = [] for i in range(11): k = ','.join(str((20*i + j)%n) for j in range(20)).encode() k1 = eval(k) # print(k) c.sendline(k) c.recvuntil(b'+ DID = ') x = c.recvuntil(b'\n')[:-1] x = eval(x) # print(x) for j in range(20): if pow(int(k1[j]),2,n) not in x and pow(int(k1[j]),2,n)+1 not in x: if k1[j] not in m: m.append(int(k1[j])) # print(m) if len(m) == 20: a = ','.join(str(l) for l in m) c.sendline(a.encode()) c.interactive() print(len(m),m) c.close() 

Insights

from Crypto.Util.number import * import gmpy2 import sympy import time # Config """ Setting debug to true will display more informations about the lattice, the bounds, the vectors... """ debug = True """ Setting strict to true will stop the algorithm (and return (-1, -1)) if we don't have a correct upperbound on the determinant. Note that this doesn't necesseraly mean that no solutions will be found since the theoretical upperbound is usualy far away from actual results. That is why you should probably use `strict = False` """ strict = False """ This is experimental, but has provided remarkable results so far. It tries to reduce the lattice as much as it can while keeping its efficiency. I see no reason not to use this option, but if things don't work, you should try disabling it """ helpful_only = True dimension_min = 7 # stop removing if lattice reaches that dimension # Functions # display stats on helpful vectors def helpful_vectors(BB, modulus): nothelpful = 0 for ii in range(BB.dimensions()[0]): if BB[ii, ii] >= modulus: nothelpful += 1 print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful") # display matrix picture with 0 and X def matrix_overview(BB, bound): for ii in range(BB.dimensions()[0]): a = ('%02d ' % ii) for jj in range(BB.dimensions()[1]): a += '0' if BB[ii, jj] == 0 else 'X' if BB.dimensions()[0] < 60: a += ' ' if BB[ii, ii] >= bound: a += '~' print(a) # tries to remove unhelpful vectors # we start at current = n-1 (last vector) def remove_unhelpful(BB, monomials, bound, current): # end of our recursive function if current == -1 or BB.dimensions()[0] <= dimension_min: return BB # we start by checking from the end for ii in range(current, -1, -1): # if it is unhelpful: if BB[ii, ii] >= bound: affected_vectors = 0 affected_vector_index = 0 # let's check if it affects other vectors for jj in range(ii + 1, BB.dimensions()[0]): # if another vector is affected: # we increase the count if BB[jj, ii] != 0: affected_vectors += 1 affected_vector_index = jj # level:0 # if no other vectors end up affected # we remove it if affected_vectors == 0: print("* removing unhelpful vector", ii) BB = BB.delete_columns([ii]) BB = BB.delete_rows([ii]) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii - 1) return BB # level:1 # if just one was affected we check # if it is affecting someone else elif affected_vectors == 1: affected_deeper = True for kk in range(affected_vector_index + 1, BB.dimensions()[0]): # if it is affecting even one vector # we give up on this one if BB[kk, affected_vector_index] != 0: affected_deeper = False # remove both it if no other vector was affected and # this helpful vector is not helpful enough # compared to our unhelpful one if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs( bound - BB[ii, ii]): print("* removing unhelpful vectors", ii, "and", affected_vector_index) BB = BB.delete_columns([affected_vector_index, ii]) BB = BB.delete_rows([affected_vector_index, ii]) monomials.pop(affected_vector_index) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii - 1) return BB # nothing happened return BB """ Returns: * 0,0 if it fails * -1,-1 if `strict=true`, and determinant doesn't bound * x0,y0 the solutions of `pol` """ def boneh_durfee(pol, modulus, mm, tt, XX, YY): """ Boneh and Durfee revisited by Herrmann and May finds a solution if: * d < N^delta * |x| < e^delta * |y| < e^0.5 whenever delta < 1 - sqrt(2)/2 ~ 0.292 """ # substitution (Herrman and May) PR.<u, x, y> = PolynomialRing(ZZ) Q = PR.quotient(x * y + 1 - u) # u = xy + 1 polZ = Q(pol).lift() UU = XX * YY + 1 # x-shifts gg = [] for kk in range(mm + 1): for ii in range(mm - kk + 1): xshift = x ^ ii * modulus ^ (mm - kk) * polZ(u, x, y) ^ kk gg.append(xshift) gg.sort() # x-shifts list of monomials monomials = [] for polynomial in gg: for monomial in polynomial.monomials(): if monomial not in monomials: monomials.append(monomial) monomials.sort() # y-shifts (selected by Herrman and May) for jj in range(1, tt + 1): for kk in range(floor(mm / tt) * jj, mm + 1): yshift = y ^ jj * polZ(u, x, y) ^ kk * modulus ^ (mm - kk) yshift = Q(yshift).lift() gg.append(yshift) # substitution # y-shifts list of monomials for jj in range(1, tt + 1): for kk in range(floor(mm / tt) * jj, mm + 1): monomials.append(u ^ kk * y ^ jj) # construct lattice B nn = len(monomials) BB = Matrix(ZZ, nn) for ii in range(nn): BB[ii, 0] = gg[ii](0, 0, 0) for jj in range(1, ii + 1): if monomials[jj] in gg[ii].monomials(): BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU, XX, YY) # Prototype to reduce the lattice if helpful_only: # automatically remove BB = remove_unhelpful(BB, monomials, modulus ^ mm, nn - 1) # reset dimension nn = BB.dimensions()[0] if nn == 0: print("failure") return 0, 0 # check if vectors are helpful if debug: helpful_vectors(BB, modulus ^ mm) # check if determinant is correctly bounded det = BB.det() bound = modulus ^ (mm * nn) if det >= bound: print("We do not have det < bound. Solutions might not be found.") print("Try with highers m and t.") if debug: diff = (log(det) - log(bound)) / log(2) print("size det(L) - size e^(m*n) = ", floor(diff)) if strict: return -1, -1 else: print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)") # display the lattice basis if debug: matrix_overview(BB, modulus ^ mm) # LLL if debug: print("optimizing basis of the lattice via LLL, this can take a long time") BB = BB.LLL() if debug: print("LLL is done!") # transform vector i & j -> polynomials 1 & 2 if debug: print("looking for independent vectors in the lattice") found_polynomials = False for pol1_idx in range(nn - 1): for pol2_idx in range(pol1_idx + 1, nn): # for i and j, create the two polynomials PR.<w, z> = PolynomialRing(ZZ) pol1 = pol2 = 0 for jj in range(nn): pol1 += monomials[jj](w * z + 1, w, z) * BB[pol1_idx, jj] / monomials[jj](UU, XX, YY) pol2 += monomials[jj](w * z + 1, w, z) * BB[pol2_idx, jj] / monomials[jj](UU, XX, YY) # resultant PR.<q> = PolynomialRing(ZZ) rr = pol1.resultant(pol2) # are these good polynomials? if rr.is_zero() or rr.monomials() == [1]: continue else: print("found them, using vectors", pol1_idx, "and", pol2_idx) found_polynomials = True break if found_polynomials: break if not found_polynomials: print("no independant vectors could be found. This should very rarely happen...") return 0, 0 rr = rr(q, q) # solutions soly = rr.roots() if len(soly) == 0: print("Your prediction (delta) is too small") return 0, 0 soly = soly[0][0] ss = pol1(q, soly) solx = ss.roots()[0][0] # return solx, soly def example(): # How To Use This Script # # The problem to solve (edit the following values) # # the modulus N = 000000000089 # the public exponent e = 0000003013 # the hypothesis on the private exponent (the theoretical maximum is 0.292) delta = .291 # this means that d < N^delta # # Lattice (tweak those values) # # you should tweak this (after a first run), (e.g. increment it until a solution is found) m = 6 # size of the lattice (bigger the better/slower) # you need to be a lattice master to tweak these t = int((1-2*delta) * m) # optimization from Herrmann and May X = 2*floor(N^delta) # this _might_ be too much Y = 1<<(1024 - 71) # correct if p, q are ~ same size # # Don't touch anything below # # Problem put in equation P.<x,y> = PolynomialRing(ZZ) pbar = int('0000000',2)<<(1024-71) A = int((N+1-2*pbar)/2) pol = 1 + x * (A + y) # # Find the solutions! # # Checking bounds if debug: print("=== checking values ===") print("* delta:", delta) print("* delta < 0.292", delta < 0.292) print("* size of e:", int(log(e)/log(2))) print("* size of N:", int(log(N)/log(2))) print("* m:", m, ", t:", t) # boneh_durfee if debug: print("=== running algorithm ===") start_time = time.time() solx, soly = boneh_durfee(pol, e, m, t, X, Y) # found a solution? if solx > 0: print("=== solution found ===") if False: print("x:", solx) print("y:", soly) d = int(pol(solx, soly) / e) print("private key found:", d) c = 00000 m = pow(c,d,N) print("message found:", long_to_bytes(int(m))) else: print("=== no solution was found ===") if debug: print("=== %s seconds ===" % (time.time() - start_time)) if __name__ == "__main__": example()

Reduction

讯享网from Crypto.Util.number import * import gmpy2 from tqdm import tqdm PKEY = 0000000000 enc = 000000382 # print(str(bin(PKEY))[2:2042]) N_ = int(str(bin(PKEY))[2:2042],2) E_ = int(str(bin(PKEY))[2042:],2) print(N_) # print(E_) def rational_to_quotients(x, y): a = x // y quotients = [a] while a * y != x: x, y = y, x - a * y a = x // y quotients.append(a) return quotients def convergents_from_quotients(quotients): convergents = [(quotients[0], 1)] for i in range(2, len(quotients) + 1): quotients_partion = quotients[0:i] denom = quotients_partion[-1] # 分母 num = 1 for _ in range(-2, -len(quotients_partion), -1): num, denom = denom, quotients_partion[_] * denom + num num += denom * quotients_partion[0] convergents.append((num, denom)) return convergents def WienerAttack(e, n): quotients = rational_to_quotients(e, n) convergents = convergents_from_quotients(quotients) for (k, d) in convergents: if k and not (e * d - 1) % k: phi = (e * d - 1) // k # check if (x^2 - coef * x + n = 0) has integer roots coef = n - phi + 1 delta = coef * coef - 4 * n if delta > 0 and gmpy2.iroot(delta, 2)[1] == True: print('d = ' + str(d)) return d # num = [] # for i in range(256): # for j in sieve_base: # if ((N_<<8) + i) % j == 0: # break # else: # num.append((N_<<8) + i) # print(len(num)) # # con,k = [],[] # for j in tqdm(range(256)): # for i in num: # N = i # E = (E_<<8) + j # d = WienerAttack(E,N) # # print(d) # if d != None: # k.append(N) # k.append(E) # k.append(d) # con.append(k) # # print(con) # print(con) N = 00000 E = 0000 d =  for i in range(256): C = (enc<<8) + i m = pow(C,d,N) if m.bit_length()<800: print(long_to_bytes(m))

RISK

from Crypto.Util.number import * import gmpy2 import requests import time import random import math pkey = (, 0000000083) enc = 0000009883 sh = requests.get(f'http://factordb.com/api?query={pkey[0]}') r = sh.json()["factors"] ab = gmpy2.iroot(pkey[1],4)[0] print(ab) h = pkey[1] - ab4 - pkey[0] xk = h2 - 4 * (ab4) * pkey[0] xk1 = gmpy2.iroot(xk,2)[0] a4s = (h + xk1) //2 b4r = (h - xk1) //2 s = [int(r[-1][0]) int(r[-1][1]),pkey[0]//(int(r[-1][0]) int(r[-1][1]))] print(s) for i in s: print(GCD(a4s,i)) s = 14071 R = 10728 a = gmpy2.iroot(a4s//s,4)[0] b = gmpy2.iroot(b4r//R,4)[0] p = a4 + R q = b4 + s print(GCD(pkey[0],(p-1)*(q-1))) print(p,q) e = p[0] print(GCD(e,p-1)) import random import time from tqdm import tqdm from Crypto.Util.number import * def AMM(o, r, q): start = time.time() print('\n----------------------------------------------------------------------------------') print('Start to run Adleman-Manders-Miller Root Extraction Method') print('Try to find one {:#x}th root of {} modulo {}'.format(r, o, q)) g = GF(q) o = g(o) p = g(random.randint(1, q)) while p ^ ((q - 1) // r) == 1: p = g(random.randint(1, q)) print('[+] Find p:{}'.format(p)) t = 0 s = q - 1 while s % r == 0: t += 1 s = s // r print('[+] Find s:{}, t:{}'.format(s, t)) k = 1 while (k * s + 1) % r != 0: k += 1 alp = (k * s + 1) // r print('[+] Find alp:{}'.format(alp)) a = p ^ (r (t - 1) * s) b = o ^ (r * alp - 1) c = p ^ s h = 1 for i in range(1, t): d = b ^ (r ^ (t - 1 - i)) if d == 1: j = 0 else: print('[+] Calculating DLP...') j = - discrete_log(d, a) print('[+] Finish DLP...') b = b * (c ^ r) ^ j h = h * c ^ j c = c ^ r result = o ^ alp * h end = time.time() print("Finished in {} seconds.".format(end - start)) print('Find one solution: {}'.format(result)) return result def onemod(p, r): t = random.randint(2, p) while pow(t, (p - 1) // r, p) == 1: t = random.randint(2, p) return pow(t, (p - 1) // r, p) def solution(p, root, e): while True: g = onemod(p, e) may = [] for i in tqdm(range(e)): may.append(root * pow(g, i, p) % p) if len(may) == len(set(may)): return may def solve_in_subset(ep, p): cp = int(pow(c, inverse(int(e // ep), p - 1), p)) com_factors = [] while GCD(ep, p - 1) != 1: com_factors.append(GCD(ep, p - 1)) ep //= GCD(ep, p - 1) com_factors.sort() cps = [cp] for factor in com_factors: mps = [] for cp in cps: mp = AMM(cp, factor, p) mps += solution(p, mp, factor) cps = mps for each in cps: assert pow(each, e, p) == c % p return cps

Suction

讯享网PKEY = 0 ENC =  c = ENC e = int(bin(PKEY)[-8:],2) # print(e) from Crypto.Util.number import * # from flag import flag import gmpy2 import requests from tqdm import * a = 0 # for i in tqdm(range(28)): # a = (PKEY>>8)<<8 # A = a + i # # print(A) # sh = requests.get(f'http://factordb.com/api?query={A}') # ciper = sh.json()['factors'] # if len(ciper) == 2: # print(A,ciper) n = 0 p =  q =  for i in tqdm(range(28)): for j in range(28): C = (c<<8) + i E = (e<<8) + j try: assert GCD(E,(p-1)*(q-1)) == 1 d = inverse(E,(p-1)*(q-1)) m = (gmpy2.powmod(C,d,n)) if m < 2200: print(long_to_bytes(m)) except: pass


讯享网

小讯
上一篇 2025-02-17 10:30
下一篇 2025-02-17 09:14

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/34587.html