今天一樣解一題就好,這題的目的主要為了解CBC的流程,還有它跟ECB的差別,了解後這題就迎刃而解惹!(是這樣用對吧)
剛看到這題的時候我也wtf
網址 : https://aes.cryptohack.org/ecbcbcwtf/
一樣先點進題目網址 : https://aes.cryptohack.org/ecbcbcwtf/
from Crypto.Cipher import AES
KEY = ?
FLAG = ?
@chal.route('/ecbcbcwtf/decrypt/<ciphertext>/')
def decrypt(ciphertext):
ciphertext = bytes.fromhex(ciphertext)
cipher = AES.new(KEY, AES.MODE_ECB)
try:
decrypted = cipher.decrypt(ciphertext)
except ValueError as e:
return {"error": str(e)}
return {"plaintext": decrypted.hex()}
@chal.route('/ecbcbcwtf/encrypt_flag/')
def encrypt_flag():
iv = os.urandom(16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(FLAG.encode())
ciphertext = iv.hex() + encrypted.hex()
return {"ciphertext": ciphertext}
可以看出,flag是以AES-CBC 加密, 之後提供了一個用AES-ECB解密的副函式
經過昨天的了解,對於ECB應該有一點點小了解了,對吧w
所以我們就來看encrypt_flag()就好惹
def encrypt_flag():
iv = os.urandom(16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(FLAG.encode())
ciphertext = iv.hex() + encrypted.hex()
return {"ciphertext": ciphertext}
程式碼解釋大概是
當我們按下右邊那個按鈕後
會先生成一個初始向量 iv
之後經過AES_CBC加密,最後輸出iv.hex() + encrypted.hex()
所以假設我們最後拿到{"ciphertext": "756d3a3a2fd4dfbe30400cdef7564c7123eaacb9abeb2e31efca20b7430671a26467e2c998a213b6f88a345fb18a4128"}
那麼就可以拆成
iv = "756d3a3a2fd4dfbe30400cdef7564c71"
ciphertext1 = "23eaacb9abeb2e31efca20b7430671a2"
ciphertext2 = "6467e2c998a213b6f88a345fb18a4128"
有這,就可以來解題拉
噢等等,先了解CBC在幹嘛後再解題好惹
在此以CBC的加密為例
然後我把加密後命名為plaintext""_xor
在此切為plaintext1、plaintext2、plaintext3
之後會生成一個初始向量iv
每個明文塊先與前一個密文塊進行互斥或後,再進行加密
這題其實不難,看懂這兩張圖就ok了!
在這題可以觀察出
ciphertext = iv.hex() + encrypted.hex()
return {"ciphertext": ciphertext}
ciphertext1丟到ECB_decrypt之後xor iv = plaintext1
ciphertext2丟到ECB_decrypt之後xor ciphertext1 = plaintext2
plaintext1 + plaintext2 = flag
from pwn import *
ciphertext = "756d3a3a2fd4dfbe30400cdef7564c7123eaacb9abeb2e31efca20b7430671a26467e2c998a213b6f88a345fb18a4128"
iv = "756d3a3a2fd4dfbe30400cdef7564c71"
ciphertext1 = "23eaacb9abeb2e31efca20b7430671a2"
ciphertext2 = "6467e2c998a213b6f88a345fb18a4128"
ciphertext1_ECB = "161f434a5bbba48d532253eb82352744"
ciphertext2_ECB = "7cdeda899a8f7100d8950196622750df"
plaintext1 = xor(bytes.fromhex(iv), bytes.fromhex(ciphertext1_ECB))
plaintext2 = xor(bytes.fromhex(ciphertext1), bytes.fromhex(ciphertext2_ECB))
print((plaintext1 + plaintext2).decode())
flag : crypto{3cb_5uck5_4v01d_17_!!!!!}
今天了解了CBC的流程,跟複習了一下昨天學的ECB,明天繼續下一題!