# 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 : ```

# 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 )
```