CRYPTO
Power tower
题目:
from Crypto.Util.number import *import randomfrom numpy import number
m = b'ISCTF{****************}'flag = bytes_to_long(m)n = getPrime(256)t = getPrime(63)l = pow(2,pow(2,t),n)c = flag ^ lprint(t)print(n)print(c)
'''t = 6039738711082505929n = 107502945843251244337535082460697583639357473016005252008262865481138355040617c = 114092817888610184061306568177474033648737936326143099257250807529088213565247'''原题链接:[CryptoCTF 2019]Time Capsule
exp.py:
from Crypto.Util.number import long_to_bytes
t = 6039738711082505929n = 107502945843251244337535082460697583639357473016005252008262865481138355040617c = 114092817888610184061306568177474033648737936326143099257250807529088213565247# factordb n# n = 127 * 841705194007 * 1005672644717572752052474808610481144121914956393489966622615553p, q, r = 127, 841705194007, 1005672644717572752052474808610481144121914956393489966622615553phi = (p - 1) * (q - 1) * (r - 1)l = pow(2, pow(2, t, phi), n)flag = c ^ lprint(long_to_bytes(flag).decode())# ISCTF{Euler_1s_v3ry|useful!!!!!}easy_RSA
题目:
from Crypto.Util.number import *
p = getPrime(1024)q = getPrime(1024)N = p*qe = 65537msg = bytes_to_long(b"ISCTF{dummy_flag}")ct1 = pow(msg, e, N)ct2 = pow(msg, p+q, N)print(f"{N = }")print(f"{ct1 = }")print(f"{ct2 = }")"""N = ...ct1 = ...ct2 = ..."""p + q在模n同余式的加密指数上等价于N + 1。
这里e和N + 1互素,所以直接共模打就好了。
原题链接:[WHY2025 CTF]Somkracht 65537
exp.py:
from Crypto.Util.number import long_to_bytesfrom gmpy2 import gcdext
N = ...e = 65537ct1 = ...ct2 = ...g, s1, s2 = gcdext(e, N + 1)m = pow(ct1, s1, N) * pow(ct2, s2, N) % Nprint(long_to_bytes(m).decode())# ISCTF{Congratulations_you_master_Mathematical_ability}baby_math
题目:
from Crypto.Util.number import bytes_to_long
print(len(flag))R = RealField(1000)a,b = bytes_to_long(flag[:len(flag)//2]),bytes_to_long(flag[len(flag)//2:])x = R(...)enc = a*cos(x)+b*sin(x)# ...直接基础格打就行,原题链接:[CyberSpaceCTF 2024]trendy windy trigonity。
exp.py:
# SageMath 10.7from Crypto.Util.number import long_to_bytes
R = RealField(1000)x = R(...)c = ...cx = int(cos(x) * 2 ** 1000)sx = int(sin(x) * 2 ** 1000)c = (c * 2 ** 1000)M = matrix(ZZ, [[1, 0, cx], [0, 1, sx], [0, 0, -c]])L = M.LLL()[0]print((long_to_bytes(L[0])+long_to_bytes(L[1])).decode())# ISCTF{164a3221-7306-4024-88c3-4ef557b86895}baby_equation
题目:
from Crypto.Util.number import *from secret import a,bflag = b'ISCTF{***********}'c = bytes_to_long(flag)
4*b**6-2*a**3+3*a*c = ...b**5+6*c**3+2*a*b*c = ...3*a**3-3*a*c-3*b**6 = ...原题链接:[陕西省省赛2023]ezmath
# SageMath 10.7from Crypto.Util.number import long_to_bytesfrom sage.matrix.matrix2 import Matrix
def resultant(f1, f2, var): return Matrix.determinant(f1.sylvester_matrix(f2, var))
R.<a, b, c> = PolynomialRing(ZZ)f1 = 4 * b ** 6 - 2 * a ** 3 + 3 * a * c - ...f2 = b ** 5 + 6 * c ** 3 + 2 * a * b * c - ...f3 = 3 * a ** 3 - 3 * a * c - 3 * b ** 6 + ...h1 = resultant(f1, f2, a)h2 = resultant(f1, f3, a)h3 = resultant(h1, h2, b)m = int(h3.univariate_polynomial().roots()[0][0])print(long_to_bytes(m).decode())# ISCTF{y0u_93t_7h3_3qu4710n_50lv3}小蓝鲨的LFSR系统
题目:
import secretsimport binascii
def simple_lfsr_encrypt(plaintext, init_state): mask = [random.randint(0,1) for _ in range(128)]
state = init_state.copy() for _ in range(256): feedback = sum(state[i] & mask[i] for i in range(128)) % 2 state.append(feedback)
key = bytes(int(''.join(str(bit) for bit in mask[i*8:(i+1)*8]), 2) for i in range(16))
keystream = (key * (len(plaintext)//16 + 1))[:len(plaintext)] return bytes(p ^ k for p, k in zip(plaintext, keystream)), maskSage秒了。
exp.py:
# SageMath 10.7
initState = [...]outputState = [...]ciphertext = bytes.fromhex('...')F2 = GF(2)allState = initState + outputStaten_eq = 256n_var = 128rows = []for t in range(n_eq): rows.append(allState[t:t + n_var])M = Matrix(F2, rows)b = vector(F2, outputState)mask_vec = M.solve_right(b)mask = [int(bit) for bit in mask_vec]key = bytes(int(''.join(str(bit) for bit in mask[i * 8:(i + 1) * 8]), 2) for i in range(16))keystream = (key * (len(ciphertext) // 16 + 1))[:len(ciphertext)]print(bytes(c ^^ k for c, k in zip(ciphertext, keystream)).decode())# ISCTF{lf5R_jUst_So_s0}小蓝鲨的RSA密文
题目:
import json, secretsfrom Crypto.Util.number import getPrime, bytes_to_longfrom Crypto.Cipher import AESfrom Crypto.Util.Padding import pad
e = 3N = getPrime(512) * getPrime(512)
a2_high = a2 >> LOW_BITS
aes_key = secrets.token_bytes(16)m = bytes_to_long(aes_key)
f = a2 * (m * m) + a1 * m + a0
c = (pow(m, e) + f) % N
iv = secrets.token_bytes(16)cipher = AES.new(aes_key, AES.MODE_CBC, iv=iv)ct = cipher.encrypt(pad(FLAG, 16))题目其实就是给了一个多项式的值,然后给出了三项系数以及一项系数的高位。关键就是怎么从多项式中恢复系数的低位以及原本的密钥值。多项式如下:
其中给出了c = f(m) % n,a2_high = a2 >> 16,下面令H = a2_high,L = a2 - H << 16。我们有:
这个时候可以推出,实际真的m满足:
而求个导数可以发现,G(x)在x > 0上是单调递增的,所以一定有正实根r,且m < r,可以用二分法在整数上找到一个数k,使得
然后从k开始往下枚举m,就可以找到唯一符合条件的(m, L),搜索区间也就是|m - r|的大小可以估算一下:
可以估算出|m - r|大概和L同级别,而L < 2 ** 16,所以区间可以取[k - 2 ** 16, k]。
exp.py:
# SageMath 10.7from Crypto.Cipher import AESfrom Crypto.Util.number import *from Crypto.Util.Padding import unpad
N = ...c = ...a2_high = 9012778LOW_BITS = 16a1 = 621315a0 = 452775142iv = bytes.fromhex("...")ct = bytes.fromhex("...")H = a2_high << LOW_BITSR.<x> = PolynomialRing(ZZ)G = x ** 3 + H * x ** 2 + a1 * x + a0 - clow = ZZ(0)high = ZZ(1)while G(high) <= 0: high *= 2while low + 1 < high: mid = (low + high) // 2 if G(mid) > 0: high = mid else: low = midk = lowbound = 1 << 16m_found = Nonea2_low = Nonefor d in range(bound + 1): m = k - d if m <= 0: break Gm = G(m) if Gm >= 0: continue num = -Gm if num >= (1 << 16) * m * m: continue if num % (m * m) != 0: continue L = num // (m * m) if 0 <= L < (1 << 16): m_found = m a2_low = L breakassert c == m_found ** 3 + ((a2_high << LOW_BITS) + a2_low) * m_found ** 2 + a1 * m_found + a0key = int(m_found).to_bytes(16, "big")cipher = AES.new(key, AES.MODE_CBC, iv=iv)pt = unpad(cipher.decrypt(ct), 16)print(pt.decode())# ISCTF{i7_533M5_Lik3_You_R34lLy_UNd3R574nd_Polinomials_4nD_RSA}沉迷数学的小蓝鲨
题目:
y² = x³ + 3x + 27 (mod p)
Q(0xa61ae2f42348f8b84e4b8271ee8ce3f19d7760330ef6a5f6ec992430dccdc167, 0x8a3ceb15b94ee7c6ce435147f31ca8028d1dd07a986711966980f7de20490080)
k= ?
最终flag请将解出k值的16进制转换为32位md5以ISCTF{}包裹提交
小蓝鲨最近沉迷于椭圆曲线,但是有一个椭圆曲线问题它始终做不出来,据说它广泛应用于区块链技术。如果你可以帮助小蓝鲨解决这个问题,它将会给予你丰厚的报酬。
HINT1:你验证过基点 G 真的在曲线上吗?(这只是个ez题,别想太复杂)
HINT2:G是这条曲线上的冒牌货,但代数运算不在乎,因为计算机可不是数学家
反正是凑着凑着对上脑电波了,无效曲线攻击,在La佬的博客翻到了。具体也不难理解,就是这个曲线给的a是对的,b是错误的,我们需要找一个b'满足基点G和Q,然后具体是哪条曲线就只能爆了,在常用区块链曲线里找就行。
exp.py:
# SageMath 10.7from hashlib import md5from math import isqrt
xQ = 0xa61ae2f42348f8b84e4b8271ee8ce3f19d7760330ef6a5f6ec992430dccdc167yQ = 0x8a3ceb15b94ee7c6ce435147f31ca8028d1dd07a986711966980f7de20490080a_attack = 3candidates = [ { "name": "SM2", "p": 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF, "Gx": 0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7, "Gy": 0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0 }, { "name": "NIST P-256 (secp256r1)", "p": 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff, "Gx": 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, "Gy": 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 }, { "name": "secp256k1", "p": 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F, "Gx": 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, "Gy": 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 }]O = Nonedef inv_mod(x, p): return pow(x, p - 2, p)
def point_add(P, Q, p, a, b): if P is None: return Q if Q is None: return P x1, y1 = P x2, y2 = Q if x1 == x2 and (y1 + y2) % p == 0: return O if P == Q: num = (3 * x1 * x1 + a) % p den = (2 * y1) % p else: num = (y2 - y1) % p den = (x2 - x1) % p lam = (num * inv_mod(den, p)) % p x3 = (lam * lam - x1 - x2) % p y3 = (lam * (x1 - x3) - y1) % p return (x3, y3)
def scalar_mul(k, P, p, a, b): R = O N = P while k > 0: if k & 1: R = point_add(R, N, p, a, b) N = point_add(N, N, p, a, b) k >>= 1 return R
def is_on_curve(P, p, a, b): if P is None: return True x, y = P return (y * y - (x ** 3 + a * x + b)) % p == 0
def bsgs(G, Q, p, a, b, N): m = isqrt(N) + 1 # baby steps: jG table = {} R = O for j in range(m): if R not in table: table[R] = j R = point_add(R, G, p, a, b) # giant steps: Q - i * (mG) mG = scalar_mul(m, G, p, a, b) neg_mG = (mG[0], (-mG[1]) % p) R = Q for i in range(m + 1): if R in table: j = table[R] k = i * m + j if k < N: return k R = point_add(R, neg_mG, p, a, b) return None
for item in candidates: name = item['name'] p = item['p'] Gx = item['Gx'] Gy = item['Gy'] b_prime = (pow(Gy, 2, p) - pow(Gx, 3, p) - a_attack * Gx) % p lhs_Q = pow(yQ, 2, p) rhs_Q = (pow(xQ, 3, p) + a_attack * xQ + b_prime) % p if lhs_Q == rhs_Q: print(f"\n[+] 命中! 系统使用的是 {name} 的 p 和 G") print(f"[+] 实际生效的 b' = {hex(b_prime)}") G = (Gx, Gy) Q = (xQ, yQ) assert is_on_curve(G, p, a_attack, b_prime) assert is_on_curve(Q, p, a_attack, b_prime) N = 2_000_000 print(f"[*] 使用 BSGS 在 [0, {N}) 上求 k 使得 Q = kG ...") k = bsgs(G, Q, p, a_attack, b_prime, N) if k is None: print("[-] 在设定范围内未找到 k,可适当增大 N 再试。") break print(f"[SUCCESS] k = {k} (dec) = {hex(k)}") flag = md5(hex(k)[2:].encode()).hexdigest() print(f"ISCTF{{{flag}}}") break else: print(f"[-] {name} 不匹配。")"""[-] SM2 不匹配。[-] NIST P-256 (secp256r1) 不匹配。
[+] 命中! 系统使用的是 secp256k1 的 p 和 G[+] 实际生效的 b' = 0x92c4cc831269ccfaff1ed83e946adeeaf82c096e76958573f2287becbb17b19d[*] 使用 BSGS 在 [0, 2000000) 上求 k 使得 Q = kG ...[SUCCESS] k = 954761 (dec) = 0xe9189ISCTF{43896099feea21a3d5804863075e1aaa}"""小蓝鲨的密码箱
题目:
小蓝鲨有一个神秘的black-box,里面藏着它最珍贵的秘密。小蓝鲨告诉我们,只有知道密码箱的运算逻辑,你才能知道它的秘密。
黑盒,笑的,就测呗,先固定(a, b, c),修改m,发现密文一直在变,flag一直不变,说明flag的加密只依赖(a, b, c),和m无关,然后观察flag长度一直是 43,可以推测明文长度。然后开始瞎试,固定(a, b)换c,会发现密文一直在c的范围内,很明显说明c应该是模数。
然后选(a, b, c) = (1, 1, 97),明文根据长度取 43 个 0,对应密文为 43 个 31(十六进制)。
选(a, b, c) = (1, 1, 89)时也是 43 个 31(十六进制)。有点敏感了,好像是仿射加密hhhhh,那怎么拿flag呢,发现a和b都不能取 0,那取 1 吧,然后c = 129,得到加密后的 flag 值减一转 ascii 就行了。最新靶机的测试结果:
加密结果
原文: 0000000000000000000000000000000000000000000
密文:
31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
Flag:
4a 54 44 55 47 7c 63 39 31 63 35 65 39 31 2e 32 3a 33 3a 2e 35 32 63 38 2e 63 34 64 33 2e 31 3a 64 34 38 38 65 66 65 63 67 65 7e
使用的参数: a=1, b=1, c=129
c = "4a 54 44 55 47 7c 63 39 31 63 35 65 39 31 2e 32 3a 33 3a 2e 35 32 63 38 2e 63 34 64 33 2e 31 3a 64 34 38 38 65 66 65 63 67 65 7e"c_list = c.split(" ")for i in c_list: print(chr(int(i, 16) - 1), end="")# ISCTF{b80b4d80-1929-41b7-b3c2-09c377dedbfd}小蓝鲨的费马谜题
题目:
import randomimport math
p = get_prime(1024)q = get_prime(1024)n = p * qe = 65537
m = bytes_to_long(flag)c = pow(m, e, n)
bases = get_primes_up_to(100)
hints = []for i in range(len(bases)): for j in range(i+1, len(bases)): hint_value = (pow(bases[i], p-1, n) + pow(bases[j], p-1, n)) % n hints.append((bases[i], bases[j], hint_value))给了 50 组,爆一下找gcd(hint - 2, n)不为 1 的就是p了。
exp.py:
from Crypto.Util.number import long_to_bytesfrom gmpy2 import gcd, invert
n = ...e = ...c = ...hint_vals = [...]for hint_val in hint_vals: p = gcd(hint_val - 2, n) if p != 1: q = n // p phi = (p - 1) * (q - 1) d = invert(e, phi) m = pow(c, d, n) print(long_to_bytes(m).decode()) break# ISCTF{M0dIFi3D_f3RM47_7H30r3m_I5_fUn_8U7_h4rD3r!}Some information may be outdated









