# Evil CBC ```Source``` ```python from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from os import urandom import json import socket import threading flag = 'KCSC{s0m3_r3ad4ble_5tr1ng_like_7his}' menu = ('\n\n|---------------------------------------|\n' + '| Welcome to Evil_ECB! |\n' + '| Maybe we can change the Crypto world |\n' + '| with a physical phenomena :D |\n' + '|---------------------------------------|\n' + '| [1] Login |\n' + '| [2] Register ^__^ |\n' + '| [3] Quit X__X |\n' + '|---------------------------------------|\n') bye = ( '[+] Closing Connection ..\n'+ '[+] Bye ..\n') class Evil_ECB: def __init__(self): self.key = urandom(16) self.cipher = AES.new(self.key, AES.MODE_ECB) self.users = ['admin'] def login(self, token): try: data = json.loads(unpad(self.cipher.decrypt(bytes.fromhex(token)), 16).decode()) if data['username'] not in self.users: return '[-] Unknown user' if data['username'] == "admin" and data["isAdmin"]: return '[+] Hello admin , here is your secret : %s\n' % flag return "[+] Hello %s , you don't have any secret in our database" % data['username'] except: return '[-] Invalid token !' def register(self, user): if user in self.users: return '[-] User already exists' data = b'{"username": "%s", "isAdmin": false}' % (user.encode()) token = self.cipher.encrypt(pad(data, 16)).hex() self.users.append(user) return '[+] You can use this token to access your account : %s' % token class ThreadedServer(object): def __init__(self, host, port): self.host = host self.port = port self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((self.host, self.port)) def listen(self): self.sock.listen(5) while True: client, address = self.sock.accept() client.settimeout(60) threading.Thread(target = self.listenToClient,args = (client,address)).start() def listenToClient(self, client, address): size = 1024 chal = Evil_ECB() client.send(menu.encode()) for i in range(10): try: client.send(b'> ') choice = client.recv(size).strip() if choice == b'1': client.send(b'Token: ') token = client.recv(size).strip().decode() client.send(chal.login(token).encode() + b'\n') elif choice == b'2': client.send(b'Username: ') user = client.recv(size).strip().decode() client.send(chal.register(user).encode() + b'\n') elif choice == b'3': client.send(bye.encode()) client.close() else: client.send(b'Invalid choice!!!!\n') client.close() except: client.close() return False client.send(b'No more rounds\n') client.close() if __name__ == "__main__": ThreadedServer('',2003).listen() ``` ## Phân tích Với bài này server cho ta 2 lựa chọn : `1 - Login , decrypt token và kiểm tra mình có phải admin và isAdmin` `2 - Register , encrypt data với username mình được chọn` ```python data = b'{"username": "%s", "isAdmin": false}' % (user.encode()) ``` Với bài đấy thì đây là dạng : ```Cut and Paste của ecb``` [Link](https://bernardoamc.com/ecb-cut-paste-attack/) Vậy mục tiêu của mình là : ```b'{"username": "admin", "isAdmin": true}``` Vậy để có được nó ta cần 3 block : ```python block_1 = b'{"username": "ad' block_2 = b'min", "isAdmin":' block_3 = pad(b' true}',16) ``` Để làm được vậy thì mình sẽ gửi lên server là ```username = b'ad' + block_3 + b'min'``` Lúc này data của ta sẽ có dạng : ``` data = b'{"username": "ad true}\n\n\n\n\n\n\n\n\n\nmin", "isAdmin": false}\x07\x07\x07\x07\x07\x07\x07` # block_1 = b'{"username": "ad' # block_2 = b' " true}\n\n\n\n\n\n\n\n\n\n' # block_3 = b'min", "isAdmin":'' # block_4 = b' false}\x07\x07\x07\x07\x07\x07\x07` ``` -> Gửi lên server thì ta thu được mã hóa của data , lúc này ta lấy ```ciphertext = enc(block1) + enc(block3) + enc(block2)``` Rồi đem nó đi login là sẽ thu được flag ```python from json import * from pwn import * from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from os import urandom io = remote("103.163.24.78", 2003) io.recvuntil(b'> ') user = b'ad' + pad(b' true}',16) + b'min' io.sendline(b'2') io.recvuntil(b'Username: ') io.sendline(user) io.recvuntil(b'account : ') ciphertext = io.recvline()[:-1].decode() ciphertext = bytes.fromhex(ciphertext) print(len(ciphertext)) ciphertext_new = ciphertext[0:16] + ciphertext[32:48] + ciphertext[16:32] ciphertext_new = (ciphertext_new).hex() print(ciphertext_new) io.recvuntil(b'> ') io.sendline(b'1') io.recvuntil(b'Token: ') io.sendline(ciphertext_new) print(io.recv()) ``` Trong lúc diễn ra giải rất tiếc mình chỉ giải được duy nhất bài này T.T Còn đây là những bài mình giải ra sau khi end giải # Miscrypt `Source` : ```python from PIL import Image import numpy as np import galois GF256 = galois.GF(2**8) img = Image.open('qr_flag_rgb.png') pixels = img.load() width, height = img.size M = GF256(np.random.randint(0, 256, size=(3, 3), dtype=np.uint8)) # scan full height -> weight for x in range(width): for y in range(0,height,3): A = GF256([pixels[x, y], pixels[x, y+1], pixels[x, y+2]]) M = np.add(A, M) pixels[x, y], pixels[x, y+1], pixels[x, y+2] = [tuple([int(i) for i in j]) for j in M] img.save('qr_flag_encrypt.png') ``` ## Phân tích Đầu tiên , chall sẽ tạo 1 ma trận M 3x3 với các phần tử ngẫu nhiên , sau đó đọc lần lượt lấy các ma trận 3x3 từ file '``qr_flag_rgb.png'`` để đem đi mã hóa như sau : ``` X1 + M = Y1 X2 + Y1 = Y2 X3 + Y2 = Y3 ... X_N + Y_N-1 = Y_N ``` Vậy để decrypt ta cần làm ngược lại : ``` X1 = Y1 - M X2 = Y2 - Y1 .... X_N = Y_N - Y_N-1 ``` Vậy ta chỉ cần biết ```M``` gốc là có thể recover lại ```Y_1,..Y_N``` để decrypt . Sau 1 hồi mình test tạo qr test thử thì mình nhận ra với các 1 qr bất kỳ thì ```X1``` sẽ luôn không đổi và là ```[255,255,255] [255,255,255][255,255,255]``` . -> Ta có thể recover lại M bằng ```M = Y_1 - X_1``` rồi decrypt như bước kể trên Script : ```python from PIL import Image import numpy as np import galois from tqdm import tqdm GF256 = galois.GF(2**8) img = Image.open('qr_flag_encrypt.png') img_2 = Image.open('qr_flag_test.png') pixels = img.load() pixels_2 = img_2.load() width, height = img.size x = 0 y = 0 result = GF256([pixels[x, y], pixels[x, y+1], pixels[x, y+2]]) print(result) x = GF256([pixels_2[x, y], pixels_2[x, y+1], pixels_2[x, y+2]]) print(x) M = np.subtract(result,x) print(M) for x in tqdm(range(width)): for y in range(0,height,3): A = GF256([pixels[x, y], pixels[x, y+1], pixels[x, y+2]]) ans = np.subtract(A,M) pixels[x, y], pixels[x, y+1], pixels[x, y+2] = [tuple([int(i) for i in j]) for j in ans] M = A img.save('qr_flag_test_2.png') ``` ```Flag : ``` ![qr_flag_test_2](https://hackmd.io/_uploads/r1S5TJ-X0.png) # Don Copper ```Source``` : ```python import random from Crypto.Util.number import * NBITS = 2048 def pad(msg, nbits): """msg -> trash | 0x00 | msg""" pad_length = nbits - len(msg) * 8 - 8 assert pad_length >= 0 pad = random.getrandbits(pad_length).to_bytes((pad_length+7) // 8, "big") return pad + b"\x00" + msg if __name__ == '__main__': p = getPrime(NBITS//2) q = getPrime(NBITS//2) n = p*q e = 3 print('n =',n) flag = b'KCSC{s0m3_r3ad4ble_5tr1ng_like_7his}' flag1 = int.from_bytes(pad(flag[:len(flag)//2], NBITS-1), "big") flag2 = int.from_bytes(pad(flag[len(flag)//2:], NBITS-1), "big") print('c1 =', pow(flag1, e, n)) print('c2 =', pow(flag2, e, n)) print('c3 =', pow(flag1 + flag2 + 2024, e, n)) #n = 20309506650796881616529290664036466538489386425747108847329314416833872927305399144955238770343216928093685748677981345624111315501596571108286475815937548732237777944966756121878930547704154830118623697713050651175872498696886388591990290649008566165706882183536432074074093989165129982027471595363186012032012716786766898967178702932387828604019583820419525077836905310644900660107030935400863436580408288191459013552406498847690908648207805504191001496170310089546275003489343333654260825796730484675948772646479183783762309135891162431343426271855443311093315537542013161936068129247159333498199039105461683433559 #c1 = 4199114785395079527708590502284487952499260901806619182047635882351235136067066118088238258758190817298694050837954512048540738666568371021705303034447643372079128117357999230662297600296143681452520944664127802819585723070008246552551484638691165362269408201085933941408723024036595945680925114050652110889316381605080307039620210609769392683351575676103028568766527469370715488668422245141709925930432410059952738674832588223109550486203200795541531631718435391186500053512941594901330786938768706895275374971646539833090714455557224571309211063383843267282547373014559640119269509932424300539909699047417886111314 #2 = 15650490923019220133875152059331365766693239517506051173267598885807661657182838682038088755247179213968582991397981250801642560325035309774037501160195325905859961337459025909689911567332523970782429751122939747242844779503873324022826268274173388947508160966345513047092282464148309981988907583482129247720207815093850363800732109933366825533141246927329087602528196453603292618745790632581329788674987853984153555891779927769670258476202605061744673053413682672209298008811597719866629672869500235237620887158099637238077835474668017416820127072548341550712637174520271022708396652014740738238378199870687994311904 #c3 = 18049611726836505821453817372562316794589656109517250054347456683556431747564647553880528986894363034117226538032533356275073007558690442144224643000621847811625558231542435955117636426010023056741993285381967997664265021610409564351046101786654952679193571324445192716616759002730952101112316495837569266130959699342032640740375761374993415050076510886515944123594545916167183939520495851349542048972495703489407916038504032996901940696359461636008398991990191156647394833667609213829253486672716593224216112049920602489681252392770813768169755622341704890099918147629758209742872521177691286126574993863763318087398 ``` ## Phân tích Để bài cho chúng ta 3 phương trình là : $x^3 ≡ c1 (mod n)$ $y^3 ≡ c2 (mod n)$ $(x + y + 2024) ≡ c3 (mod n)$ ### Cách 1 Cách này mình nhận hint từ a Quốc là dùng `groebner_basis` một phương pháp dùng để đơn giản tập sinh của một ideal trong một vành đa thức [Link](https://www.youtube.com/watch?v=q4L_f7BMOOM) Sau khi nhận được tập sinh của ideal ta chỉ cần đem n trừ đi cho nó là ta có thể tìm được flag ```python n = 20309506650796881616529290664036466538489386425747108847329314416833872927305399144955238770343216928093685748677981345624111315501596571108286475815937548732237777944966756121878930547704154830118623697713050651175872498696886388591990290649008566165706882183536432074074093989165129982027471595363186012032012716786766898967178702932387828604019583820419525077836905310644900660107030935400863436580408288191459013552406498847690908648207805504191001496170310089546275003489343333654260825796730484675948772646479183783762309135891162431343426271855443311093315537542013161936068129247159333498199039105461683433559 c1 = 4199114785395079527708590502284487952499260901806619182047635882351235136067066118088238258758190817298694050837954512048540738666568371021705303034447643372079128117357999230662297600296143681452520944664127802819585723070008246552551484638691165362269408201085933941408723024036595945680925114050652110889316381605080307039620210609769392683351575676103028568766527469370715488668422245141709925930432410059952738674832588223109550486203200795541531631718435391186500053512941594901330786938768706895275374971646539833090714455557224571309211063383843267282547373014559640119269509932424300539909699047417886111314 c2 = 15650490923019220133875152059331365766693239517506051173267598885807661657182838682038088755247179213968582991397981250801642560325035309774037501160195325905859961337459025909689911567332523970782429751122939747242844779503873324022826268274173388947508160966345513047092282464148309981988907583482129247720207815093850363800732109933366825533141246927329087602528196453603292618745790632581329788674987853984153555891779927769670258476202605061744673053413682672209298008811597719866629672869500235237620887158099637238077835474668017416820127072548341550712637174520271022708396652014740738238378199870687994311904 c3 = 18049611726836505821453817372562316794589656109517250054347456683556431747564647553880528986894363034117226538032533356275073007558690442144224643000621847811625558231542435955117636426010023056741993285381967997664265021610409564351046101786654952679193571324445192716616759002730952101112316495837569266130959699342032640740375761374993415050076510886515944123594545916167183939520495851349542048972495703489407916038504032996901940696359461636008398991990191156647394833667609213829253486672716593224216112049920602489681252392770813768169755622341704890099918147629758209742872521177691286126574993863763318087398 P.<x,y> = PolynomialRing(Zmod(n)) f1 = (x)^3 - c1 f2 = (y)^3 - c2 f3 = (x+y+2024)^3 - c3 I = P.ideal(f1,f2,f3) for eq in I.groebner_basis(): print(eq) ``` Ta thu được : ```python= x + 13735276216480234294706359844820346892092177215553901414391761850858882460635783205472406746662036273971992070607261796127119688947318559763272879567995396491115716121316753574975647148161690034108438505248524970885551589159652876676870846257287752279898736691564266993215011110767376345954955541741948634680315084968263393711859569144349753495551546569343780951427789448111710124904988309966385084377510291750050932987581798768855247780396174181337264410175133260701357189505301070362322065230989981704250274145256779438951189476596306356433095883900881070769915283761198556147219781991864498300605360624190735499303 y + 10850063064215786153306327148990924788438984598023598141431813572034023665508993022819406328531276035415236463762473907444014785919774345550388745382570351421234382216484857722363728432223575478904468786551137995573395304260701532033474455590992994546092536998679869622456414388329561594251029715255159436038660362296817381481412123357555319521172263012404519048712465622333028074769426400066439085668811357134225445548178218655872653355541146025686046192241356344100333096851330334054858073508194708777534526473121314794434611660370071725086052980875155623377312829194652529259245234592714291772331661063675437706202 ``` Đem n trừ đi 2 giá trị kia là sẽ thu được flag ```python= flag1 = long_to_bytes(n-x1).split(b'\x00')[1] flag2 = long_to_bytes(n-x2).split(b'\x00')[2] print(flag1+flag2) ``` Flag : ```KCSC{W0rk1ng_w1th_p0lyn0m14ls_1s_34sy_:D}``` ## Cách 2 Cách 2 này ta sẽ sử dụng hàm ```resultant``` của sage . Trong đó ```resultant``` là phép tìm ```Res(P,Q)``` , với P,Q là phương trình chứa 2 ẩn x,y Có thể hiểu đơn giản là nó trả về cho mình một số nghiệm ```y0``` [Link](https://www.imo.universite-paris-saclay.fr/~pierre-loic.meliot/algebra/resultant.pdf) Vậy ta cần tính res của 2 cặp phương trình rồi tính gcd của chúng thì ta có thể tìm được đúng y0 mà mình cần tìm , rồi có thể tìm được x0 Flag 1 : ```python= n = 20309506650796881616529290664036466538489386425747108847329314416833872927305399144955238770343216928093685748677981345624111315501596571108286475815937548732237777944966756121878930547704154830118623697713050651175872498696886388591990290649008566165706882183536432074074093989165129982027471595363186012032012716786766898967178702932387828604019583820419525077836905310644900660107030935400863436580408288191459013552406498847690908648207805504191001496170310089546275003489343333654260825796730484675948772646479183783762309135891162431343426271855443311093315537542013161936068129247159333498199039105461683433559 c1 = 4199114785395079527708590502284487952499260901806619182047635882351235136067066118088238258758190817298694050837954512048540738666568371021705303034447643372079128117357999230662297600296143681452520944664127802819585723070008246552551484638691165362269408201085933941408723024036595945680925114050652110889316381605080307039620210609769392683351575676103028568766527469370715488668422245141709925930432410059952738674832588223109550486203200795541531631718435391186500053512941594901330786938768706895275374971646539833090714455557224571309211063383843267282547373014559640119269509932424300539909699047417886111314 c2 = 15650490923019220133875152059331365766693239517506051173267598885807661657182838682038088755247179213968582991397981250801642560325035309774037501160195325905859961337459025909689911567332523970782429751122939747242844779503873324022826268274173388947508160966345513047092282464148309981988907583482129247720207815093850363800732109933366825533141246927329087602528196453603292618745790632581329788674987853984153555891779927769670258476202605061744673053413682672209298008811597719866629672869500235237620887158099637238077835474668017416820127072548341550712637174520271022708396652014740738238378199870687994311904 c3 = 18049611726836505821453817372562316794589656109517250054347456683556431747564647553880528986894363034117226538032533356275073007558690442144224643000621847811625558231542435955117636426010023056741993285381967997664265021610409564351046101786654952679193571324445192716616759002730952101112316495837569266130959699342032640740375761374993415050076510886515944123594545916167183939520495851349542048972495703489407916038504032996901940696359461636008398991990191156647394833667609213829253486672716593224216112049920602489681252392770813768169755622341704890099918147629758209742872521177691286126574993863763318087398 P.<x,y> = PolynomialRing(ZZ,2) f1 = y^3 - c1 f2 = x^3 - c2 f3 = (x+y+2024)^3 - c3 a = f3.resultant(f1) b = f3.resultant(f2) k1 = a.change_ring(Zmod(n)) k2 = b.change_ring(Zmod(n)) test = gcd(k1,k2) print(test) ``` Output : ```python= -y + 6574230434316647321822930819216119646397209210193207432937552565974990466669615939482832023681180654121693678070719549496991626554278011345013596247942152241122061823650002546903283399542464796010185192464525680290320909537233511915119444391720813885808145491972165080859082878397753636072516053621237377351697631818503505255319133788038075108468037251075744126409115862533190535202042625434478352202897996441408080564824700078835660867811631322853737085995176828844917813984042263291938760565740502971698498501222404344811119659294856074910330387954562240323400253780814605788848347255294835197593678481270947934256 # -> flag_1 = long_to_bytes(6574230434316647321822930819216119646397209210193207432937552565974990466669615939482832023681180654121693678070719549496991626554278011345013596247942152241122061823650002546903283399542464796010185192464525680290320909537233511915119444391720813885808145491972165080859082878397753636072516053621237377351697631818503505255319133788038075108468037251075744126409115862533190535202042625434478352202897996441408080564824700078835660867811631322853737085995176828844917813984042263291938760565740502971698498501222404344811119659294856074910330387954562240323400253780814605788848347255294835197593678481270947934256) ``` Tiếp theo chúng ta chỉ cần đảo ngược x và y trong f1 và f2 là có thể tìm được x2 ```python= f1 = x^3 - c1 f2 = y^3 - c2 ``` Output : ```python= y + 10850063064215786153306327148990924788438984598023598141431813572034023665508993022819406328531276035415236463762473907444014785919774345550388745382570351421234382216484857722363728432223575478904468786551137995573395304260701532033474455590992994546092536998679869622456414388329561594251029715255159436038660362296817381481412123357555319521172263012404519048712465622333028074769426400066439085668811357134225445548178218655872653355541146025686046192241356344100333096851330334054858073508194708777534526473121314794434611660370071725086052980875155623377312829194652529259245234592714291772331661063675437706202 # flag_2 = long_to_bytes(-10850063064215786153306327148990924788438984598023598141431813572034023665508993022819406328531276035415236463762473907444014785919774345550388745382570351421234382216484857722363728432223575478904468786551137995573395304260701532033474455590992994546092536998679869622456414388329561594251029715255159436038660362296817381481412123357555319521172263012404519048712465622333028074769426400066439085668811357134225445548178218655872653355541146025686046192241356344100333096851330334054858073508194708777534526473121314794434611660370071725086052980875155623377312829194652529259245234592714291772331661063675437706202 %n ) ``` Hoặc từ ```flag 1``` bạn cũng có thể tìm ```flag 2``` bằng gcd : ```python= n = 20309506650796881616529290664036466538489386425747108847329314416833872927305399144955238770343216928093685748677981345624111315501596571108286475815937548732237777944966756121878930547704154830118623697713050651175872498696886388591990290649008566165706882183536432074074093989165129982027471595363186012032012716786766898967178702932387828604019583820419525077836905310644900660107030935400863436580408288191459013552406498847690908648207805504191001496170310089546275003489343333654260825796730484675948772646479183783762309135891162431343426271855443311093315537542013161936068129247159333498199039105461683433559 c1 = 4199114785395079527708590502284487952499260901806619182047635882351235136067066118088238258758190817298694050837954512048540738666568371021705303034447643372079128117357999230662297600296143681452520944664127802819585723070008246552551484638691165362269408201085933941408723024036595945680925114050652110889316381605080307039620210609769392683351575676103028568766527469370715488668422245141709925930432410059952738674832588223109550486203200795541531631718435391186500053512941594901330786938768706895275374971646539833090714455557224571309211063383843267282547373014559640119269509932424300539909699047417886111314 c2 = 15650490923019220133875152059331365766693239517506051173267598885807661657182838682038088755247179213968582991397981250801642560325035309774037501160195325905859961337459025909689911567332523970782429751122939747242844779503873324022826268274173388947508160966345513047092282464148309981988907583482129247720207815093850363800732109933366825533141246927329087602528196453603292618745790632581329788674987853984153555891779927769670258476202605061744673053413682672209298008811597719866629672869500235237620887158099637238077835474668017416820127072548341550712637174520271022708396652014740738238378199870687994311904 c3 = 18049611726836505821453817372562316794589656109517250054347456683556431747564647553880528986894363034117226538032533356275073007558690442144224643000621847811625558231542435955117636426010023056741993285381967997664265021610409564351046101786654952679193571324445192716616759002730952101112316495837569266130959699342032640740375761374993415050076510886515944123594545916167183939520495851349542048972495703489407916038504032996901940696359461636008398991990191156647394833667609213829253486672716593224216112049920602489681252392770813768169755622341704890099918147629758209742872521177691286126574993863763318087398 flag_1 = 6574230434316647321822930819216119646397209210193207432937552565974990466669615939482832023681180654121693678070719549496991626554278011345013596247942152241122061823650002546903283399542464796010185192464525680290320909537233511915119444391720813885808145491972165080859082878397753636072516053621237377351697631818503505255319133788038075108468037251075744126409115862533190535202042625434478352202897996441408080564824700078835660867811631322853737085995176828844917813984042263291938760565740502971698498501222404344811119659294856074910330387954562240323400253780814605788848347255294835197593678481270947934256 def poly_gcd(a,b) : while b : a , b = b , a%b return a.monic() P.<x> = PolynomialRing(Zmod(n)) f2 = x^3 - c2 f3 = (x + flag_1 + 2024)^3 - c3 print(poly_gcd(f2,f3)) ``` Output : ```python= x + 10850063064215786153306327148990924788438984598023598141431813572034023665508993022819406328531276035415236463762473907444014785919774345550388745382570351421234382216484857722363728432223575478904468786551137995573395304260701532033474455590992994546092536998679869622456414388329561594251029715255159436038660362296817381481412123357555319521172263012404519048712465622333028074769426400066439085668811357134225445548178218655872653355541146025686046192241356344100333096851330334054858073508194708777534526473121314794434611660370071725086052980875155623377312829194652529259245234592714291772331661063675437706202 # flag_2 = long_to_bytes(-10850063064215786153306327148990924788438984598023598141431813572034023665508993022819406328531276035415236463762473907444014785919774345550388745382570351421234382216484857722363728432223575478904468786551137995573395304260701532033474455590992994546092536998679869622456414388329561594251029715255159436038660362296817381481412123357555319521172263012404519048712465622333028074769426400066439085668811357134225445548178218655872653355541146025686046192241356344100333096851330334054858073508194708777534526473121314794434611660370071725086052980875155623377312829194652529259245234592714291772331661063675437706202 %n ) ```