雖然在期中考前,還是手癢在大致上複習好了之後稍微解點題目,大概只打了半場比賽,一樣主要以
crypto 和 web 為主,pwn 和 rev 也有各解一題。
題目名稱上有 * 的題目代表是我賽後才解的。
Crypto
dlppp
1 2 3 4 5 6 7 8 9 10 11 12
import os from Crypto.Util.number import getPrime, getRandomNBitInteger
flag = os.getenv("FLAG", "XXXX{sample_flag}").encode() m = int.from_bytes(flag, 'big')
p = getPrime(512) y = pow(1 + p, m, p**3)
assert m < p print(f"p = {hex(p)}") print(f"y = {hex(y)}")
這題要解個 下的
DLP ,其中的 且 。
首先先簡化到
去比較好處理,因為
所以這樣做是沒問題的。
接下來用二項式定理可知:
所以 DLP 的結果
就拿到 flag 了。
1 2 3 4 5 6 7 8 9 10
from Crypto.Util.number import long_to_bytes
p = 0xA1C8E1E9B2301CB1F5D424EC6D959D7F275E11507B2177D55F3DC1268C9A3164B72832F362975023F09623814F80FE0FFAD179D0E51C40B8A1F882D1F5F28E71 y = 0x6FA0FCC8C9C5F695A5709243698D7640C27C45352375919D538137333AB3A2C748CAE5E7C1294D6FFC4007476F6FEC6421C992F9FE1919B381306300CAA2260953E48F2EC0DE7B8C6417FAA42001A748B1B367F5211095DDD6BF4E681F7E7AD787E0A7F562F6F0307D6A8D7E8D18CD59BD7572F0C4F430F0FD4FC61503B203F3BCD6DD0B0F84BBDBD42126D95B525FE77E4BE62C6DBD083DBCAA284B20A9EA6FAF9CBAF20DD88B0180417C9021FA1DCB52B2348C4376BD6B9B38A6C860086AF g = 1 + p
import os import hashlib from Crypto.Util.number import getPrime, getRandomNBitInteger from itertools import product
deffloor_sum(n: int, m: int, a: int) -> int: """Fast calculation for sum([a * i // m for i in range(n)]) """ res, b = 0, 0 while0 < n: res += n * (n - 1) // 2 * (a // m) a %= m res += n * (b // m) b %= m last = a * n + b n, m, a, b = last // m, a, m, last % m return res
#def floor_sum_tests(): # for n, m, a in product(range(50), range(1, 50), range(50)): # result = floor_sum(n, m, a) # expect = sum([a * i // m for i in range(n)]) # assert(result == expect)
if __name__ == '__main__': #floor_sum_tests()
flag = os.getenv('FLAG', 'XXXX{sample_flag}').encode() flag += hashlib.sha512(flag).digest() m = int.from_bytes(flag, 'big') assert m.bit_length() < 2048
p = getPrime(1024) q = getPrime(1024) n = p * q e = 65537 c = pow(m, e, n) s = floor_sum(q, q, p)
c = 23040235907187792043102377766239160347012425454756214402219399982044253963561544138187423569531882081170834886320190973854626011799820277883217582208960795474430615579336090533683566370889382239077437657567815790536809115842475993748108172855688647606634510990327206587307392015543017884876145469179123535144938693302707229724909443912012098405828416163212773471183275687343852756789315215914149905888864296778004572587778916842514807079884644431138433900314631727531570096879428541834626325720522038566946030094711700613155240677360427005636301342509966941323931780006792225168839057660986447452212763627881844882128 n = 25436172154773316497363731760659809627551021985352168624695689317365040018878195925779734249357382145683534839534348832631746578327288150976696513216052612085728199134879493012682967254530827617417753223998955022174337237825391634619718971640535408277659054217709169558518413217237374290054035438476060534235907848570089739603581573457194953083783917042829987113625590656741008590506988903895998008845547262465276679611851110911540261411521221317990139079888782193797945245078986517794660508171428778191152342783279365287710944280356669999624474416422142006473378042779555537142175392801014489187786764971671239717769 s = 12718086077386658248681865880329904813775510992676084312347844658682520009439097962889867124678691072841767419767174416315873289163644075488348256608026306042864099567439746506341483627265413808708876611999477511087168618912695817309859485820267704138829527108854584779259206608618687145027017719238030267117794390566380531016624830798422997060308480467087130633621890831591995264022449058406630323270130520401030807803477672651197312971884784226103671425190328967548002718406368654056897938481966140031709870266384782295285897095028680666943294657806202686252742158733266700286323555374087306844259404255328911060160
pq = (n % s) + 1# idk why...
# (x-p)(x-q)=x^2-pq*x+n defsolve(a, b, c): D = b ^ 2 - 4 * a * c return (-b + sqrt(D)) / (2 * a)
p = solve(1, -pq, n) q = n // p assert p * q == n
d = inverse_mod(65537, (p - 1) * (q - 1)) m = power_mod(c, d, n) print(long_to_bytes(m))
# fmt: off p = 2908561168050746475465170048583677924550221390147321314856251074876765877416890922338619139786060615096740196376171212325702080653039392939240436429222829 vs = [(1, 1651293975450381579706844999808202297670211173037061827272908790114230592434748044848097133563469251678879059156225205298834971071359017469397331605782920), (2, 49656064002974834481096383104316375265711545391722811288216446968986145936494966876404160910407919885451814058823146922107458035910700220495010462147112), (3, 1481214561214496310917942246038921499126047497749957535731608952096552856013930232284898279007009260107597472601959627310496773682697020898442717240484400), (4, 1950790377868548708758723604473108315857898618124646291056275632619091046294238343215502355242288776617394025418770078552886012721353626716473759644786481)] fflag = 708078355843841364722603057137729966137248436075776171805731561888875332687774464375592593202164126123800524500062359645261336234459019198930345744751457 # fmt: on
ys = [v[1] for v in vs]
P.<a, b, x> = GF(p)[]
defg(): global x x = a * x + b return x
cs = [g() for _ inrange(6)] print(cs) M = matrix.vandermonde([1, 2, 3, 4, 5, 6])[:-2] eqs = M * vector(cs) - vector(ys) I = P.ideal(list(eqs)) assert I.dimension() == 0 V = I.variety() sol = V[0] a = sol["a"] b = sol["b"] x = sol["x"]
print(a, b, x)
P.<X> = PolynomialRing(GF(p)) f = g() + g() * X + g() * X ** 2 + g() * X ** 3 + g() * X ** 4 + g() * X ** 5 flag = (f - fflag).roots()[0][0] print(long_to_bytes(flag))
from Crypto.Util.number import getPrime from hashlib import sha256 import random
defgen_parameters(): p = getPrime(512) q = getPrime(512) N = p * q a = -3 whileTrue: b = random.randint(0, N) if (4*a**3 + 27*b**2) % N != 0: break x = random.randint(0, N) whileTrue: y2 = (x**3 + a*x + b) % N if Zmod(p)(y2).is_square() and Zmod(q)(y2).is_square(): break x = random.randint(0, N) y = CRT([int(Zmod(p)(y2).sqrt()), int(Zmod(q)(y2).sqrt())], [p, q]) return (N, a, b, (x, y))
withopen("flag.txt", "rb") as f: FLAG = f.read().strip()
N, a, b, (x, y) = gen_parameters()
EC = EllipticCurve(Zmod(N), (a, b)) P = EC(x, y)
T = P ct = [] for byte in FLAG: r = int(T.xy()[0]) ct.append(pow(byte*r, 65537, N)) T += T
withopen("backdoor.txt", "w") as f: f.write(str(P.xy()))
print(N) print(a) print(b) print(ct)
題目隨機生成的 RSA 的 ,然後在
上生成一條隨機的橢圓曲線
和上面的一點 。
加密的部分是拿 flag 的每個 byte 去算 ,而 是 的 x 座標,初始時 且每次迴圈會更新 。
defGCD(a, b): print(a.degree(), b.degree()) q, r = a.quo_rem(b) if r == 0: return b R00, R01, R10, R11 = HGCD(a, b) c = R00 * a + R01 * b d = R10 * a + R11 * b if d == 0: return c.monic() q, r = c.quo_rem(d) if r == 0: return d return GCD(d, r)
import sys
sys.setrecursionlimit(500000)
res = GCD(f, g) # res = ( # 68765093455835208028392258104907079565692659302812829782588600660675613929548799131035775043283907905375438946721292784903505396871443341473054747563228096356170292887552741209158721931281480445553591933194005921593589247544342013684870547235753590331284739460827586347933151294607856549542345658089301181459 # * x # + 57976660076847746693047667669843141709781328208657608892943399238042073050136437602076395330212978534265956439717721582591882414227440127179227428240681552957224873749894765553704124594310498445840959011243768636829159507147665544078137706841681096739053274910222133055138566326690047859724098578096845570031 # ) # precomputed result r = Z(-res.monic().coefficients()[0])
invtbl = {power_mod(i, e, N): i for i inrange(256)}
for c in ct: c /= Z(r) ^ e print(chr(invtbl[c]), end="") r = Z(up(r)) / Z(down(r))
# Neko{h4lf_gcd_g0es_brrr...}
*They Were Eleven
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import os from Crypto.Util.number import getPrime, getRandomRange
withopen("flag.txt", "rb") as f: m = f.read().strip() m += os.urandom(111 - len(m)) m = int.from_bytes(m, "big")
xs = [] for i inrange(11): p = getPrime(512) q = getPrime(512) n = p * q
cs = [ZZ(x[0]) for x in xs] ns = [ZZ(x[1]) for x in xs] T = [crt([1if i == j else0for j inrange(11)], ns) for i inrange(11)] N = product(ns)
M = matrix(12, 12) M[0, 0] = N for i, (c, t) inenumerate(zip(cs, T)): M[i + 1, 0] = (c * t) % N M[i + 1, i + 1] = 1
print(M.change_ring(Zmod(10)))
b = N.nbits() Q = matrix.diagonal([2 ^ b // (2 ^ 9889)] + [2 ^ b // (2 ^ 110)] * 11)
M *= Q M = M.LLL() M /= Q
for row in M: if row[0] < 0: row = -row ifmin(row) >= 0and [row[0] % x == 0for x in row[1:]]: for k1 inrange(1, 2 ^ 11): R = k1 * row[1] if row[0] % R != 0: continue m11 = ZZ(row[0] // R) try: m = m11.nth_root(11) flag = int(m).to_bytes(111, "big") print(flag) except ValueError as e: pass
constID_TABLE = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; functiongenerateId(n=8) { let res = ''; for (let i = 0; i < n; i++) { res += ID_TABLE[Math.random() * ID_TABLE.length | 0]; } return res; }
const fileName = file.originalname; const ext = fileName.split('.').slice(-1)[0]; // check if the file is safe if (isValidFile(ext, buf)) { const newFileName = uuidv4() + '.' + ext; fs.writeFile('uploads/' + newFileName, buf, (err, data) => { let id; do { id = generateId(); } while (id in uploadedFiles);
P.<x, y> = GF(c3)[] a = x * x b = y * y f1 = a + b - c1 * c1 f2 = x * y - c2 I = P.ideal([f1, f2]) assert I.dimension() == 0 V = I.variety() for sol in V: first = sol["x"] second = sol["y"] print(long_to_bytes(first) + long_to_bytes(second))