This only me + n2l team writeup ( because i also play in another team called Huntik ) . im not played in N2L so N2L got 119th place.
getting-closer-dang
chall.py
import os, json, random, math
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.number import getPrime, GCD
from hashlib import sha256
#from secret import FLAG
def get_prod():
return math.prod([random.choice(pool) for _ in range(3)])
FLAG = b'cr3{???????????????????????????????}'
N = getPrime(512)
pool = [getPrime(9) for _ in range(10)]
a, b = [get_prod() for _ in range(2)]
g = GCD(N**a - 1, N**b - 1) # pros of having a quantum computer ^-^
key = sha256(str(g).encode()).digest()[:16]
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
ct = cipher.encrypt(pad(FLAG, 16))
out = {'iv': iv.hex(), 'ct': ct.hex()}
with open('output.txt', 'w') as f:
f.write(f'{N = }\n')
f.write(f'{out = }')
program enkripsi aes cbc sederhana di mana, pada variabel g terdapat penghitungan GCD antara (N^a)-1 dengan (N^b)-1 output.txt
N = 13185232652915309492470700885494158416479364343127310426787872363041960044885500175769971795951432028221543122753022991035176378747918784016983155565886369
out = {'iv': '6f69ac380715dbf9b00ef32ca8c204bb', 'ct': 'e654237a76d61d3bf97b315af1c2a517797b34b8eca270dbc8132dda1f425065b7b84690d4c21cdaf2ab17c2876738ed'}
mekanisme enkripsi:
Generate N prime random sebesar 512 bit
Generate nilai array pool
Menghitung faktor secara random yang terdapat pada array pool dan di simpan pada variabel a dan b
Menghitung GCD(FPB) dari (N^a) - 1 dengan (N^b) - 1)
Menyimpan hasil perhitungan GCD kemudian dijadikan sebagai key untuk mengencrypt
mekanisme decrypt menurut gwhj: Merecover nilai a,b -> tidak mungkin karena tidak disediakan nilai g, karena hal tersebut saya menemukan opsi lain yakni penghitungan nilai g dari GCD akan sama dengan persamaan berikut (N^GCD(a,b))-1, karena hal tersebut sama maka tinggal bruteforce saja nilai GCD(a,b)
solver.py
import os, json, random, math
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.number import getPrime, GCD
from hashlib import sha256
import sys
sys.set_int_max_str_digits(0)
#from secret import FLAG
N = 13185232652915309492470700885494158416479364343127310426787872363041960044885500175769971795951432028221543122753022991035176378747918784016983155565886369
iv = b'oi\xac8\x07\x15\xdb\xf9\xb0\x0e\xf3,\xa8\xc2\x04\xbb'
ct = b'\xe6T#zv\xd6\x1d;\xf9{1Z\xf1\xc2\xa5\x17y{4\xb8\xec\xa2p\xdb\xc8\x13-\xda\x1fBPe\xb7\xb8F\x90\xd4\xc2\x1c\xda\xf2\xab\x17\xc2\x87g8\xed'
g = ((N**(439))-1)
#g = [((N**i)-1) for i in range(1000)]
key = sha256(str(g).encode()).digest()[:16]
#key = [sha256(str(g).encode()).digest()[:16] for g in g]
#iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
#cipher = [AES.new(key, AES.MODE_CBC, iv) for key in key]
fl = cipher.decrypt(ct)
#fl = [i.decrypt(ct) for i in cipher]
#ct = cipher.encrypt(pad(FLAG, 16))
#out = {'iv': iv.hex(), 'ct': ct.hex()}
print(f"""
g = {g}
key = {key}
N = {N}
flag = {fl.decode('latin-1')}""")
by : gr3yr4t
donut
after we extract it we can see there is a .git files and my terminal shows it git
bet the git seems broken after i use command log or status
so i directly use grep or strings like this:
cd .git
grep -roa 'flag'
and we can see in the head we can strings to see the log of commit
strings logs/HEAD
e1cf8e13bfe7f2b9522642a878368677621349b1 e1cf8e13bfe7f2b9522642a878368677621349b1 dxqwww <minikkat1337@gmail.com> 1713541575 +0300 checkout: moving from master to flag
e1cf8e13bfe7f2b9522642a878368677621349b1 2a461812df0b80851da28cf6e69f3a2d84129b01 dxqwww <minikkat1337@gmail.com> 1713541687 +0300 commit: added flag
2a461812df0b80851da28cf6e69f3a2d84129b01 e1cf8e13bfe7f2b9522642a878368677621349b1 dxqwww <minikkat1337@gmail.com> 1713541710 +0300 checkout: moving from flag to master
we can see the hash of the added flag we directly use git show