[CryptoHack] SYMMETRIC CIPHERS(Lazy CBC)
작성자 - ikbak_2
Lazy CBC
문제
나는 게으른 개발자일이고, 내 CBC 암호화가 작동하기를 원합니다. 초기화 벡터에 대한 이 모든 이야기는 무엇인가요? 중요하게 않은 것 같아요. |
풀이
먼저 제공된 사이트와 코드다.
from Crypto.Cipher import AES
KEY = ?
FLAG = ?
@chal.route('/lazy_cbc/encrypt/<plaintext>/')
def encrypt(plaintext):
plaintext = bytes.fromhex(plaintext)
if len(plaintext) % 16 != 0:
return {"error": "Data length must be multiple of 16"}
cipher = AES.new(KEY, AES.MODE_CBC, KEY)
encrypted = cipher.encrypt(plaintext)
return {"ciphertext": encrypted.hex()}
@chal.route('/lazy_cbc/get_flag/<key>/')
def get_flag(key):
key = bytes.fromhex(key)
if key == KEY:
return {"plaintext": FLAG.encode().hex()}
else:
return {"error": "invalid key"}
@chal.route('/lazy_cbc/receive/<ciphertext>/')
def receive(ciphertext):
ciphertext = bytes.fromhex(ciphertext)
if len(ciphertext) % 16 != 0:
return {"error": "Data length must be multiple of 16"}
cipher = AES.new(KEY, AES.MODE_CBC, KEY)
decrypted = cipher.decrypt(ciphertext)
try:
decrypted.decode() # ensure plaintext is valid ascii
except UnicodeDecodeError:
return {"error": "Invalid plaintext: " + decrypted.hex()}
return {"success": "Your message has been received"}
먼저 코드를 보게 되면
키는 AES-CBC 암호화, 해독을 위해 키와 IV 모두에 사용 되었고
get_flag는 플래그를 가져오기위해선 키가 필요하다.
그리고 주어진 암호 텍스트의 암호해독을 하고,
실패시 암호해독된 메시지가 반환된다.
이를 위해 일단 CBC를 보게 되면
평문의 블록은 xor연산을 통해 이전 암호문과 연산되고
첫번째 암호문에 대해서는 IV가 암호문 대신 사용된다.
iv = d(e0)^p0
p0 = d(e0)^iv
p1 = d(e1)^c0
p2 = d(e2)^c1
먼저 p는 평문, e는 암호문, d는 복호화일때 이러한 형태인데
이를 복호화 시켜 보자면 이러한 형태인데
p0 = d(e0) ^ iv
p1 = d(0) ^ e0
p2 = d(e0) ^ 0
만약에 e1가 0, c2가 c0이면, 이러한 형태이다.
p0^p2 = d(e0)^iv^d(e0)=iv
p0와 p2를 xor연산을 시키게 되면 iv값을 얻을 수 있다.
p0=(b'a'*(16*3)).hex()
print(p0)
그래서 세 블록을 사용하는 일반텍스트를 만들었다.
{"ciphertext":"5afa4a5595e4399f0848191b6ef47378e44f1a1b81fde8ce7e19f544b3efa496f2798f81611b27904b0977c5c0df78c3"}
이를 제공된 사이트에 대입을 하여 암호문을 얻었다.
c='5afa4a5595e4399f0848191b6ef47378e44f1a1b81fde8ce7e19f544b3efa496f2798f81611b27904b0977c5c0df78c3'
fake = c[:32] + '0'*32 + c[:32]
print(fake)
5afa4a5595e4399f0848191b6ef47378000000000000000000000000000000005afa4a5595e4399f0848191b6ef47378 |
그리고 가짜 암호 텍스트를 만들었더니
두번째 블록에 0으로 채우고 세 번째 블록이 동일하게 암호텍스트를 변경했다.
{"error":"Invalid plaintext: 6161616161616161616161616161616160f344aa47cc93d3047b17408d856a2c8458e32c8b4238e1db7f91faeaf7bdf9"} |
이를 대입 하였더니 오류가 뜨며 시도한 서버에서 해독된 평문과 함께 오류가 나왔다.
이를 통해 첫번째 블록인
61616161616161616161616161616161
세번째 블록으로 xor연산을 하였다.
8458e32c8b4238e1db7f91faeaf7bdf9
키는 ''e539824dea235980ba1ef09b8b96dc98"이다.
그리고 키를 사용하여 get_flag를 요청하면 플래그가 16진수로 반환되는데
이를 해독하면
플래그는 crypto{50m3_p30pl3_d0n7_7h1nk_IV_15_1mp0r74n7_?}이다.
'Season 1 > 워게임' 카테고리의 다른 글
[CryptoHack] SYMMETRIC CIPHERS(Triple DES) (0) | 2023.05.06 |
---|---|
[CryptoHack] SYMMETRIC CIPHERS(ECB CBC WTF) (0) | 2023.05.05 |
[CryptoHack] CRYPTO ON THE WEB(JSON in JSON) (0) | 2023.05.03 |
[CryptoHack] CRYPTO ON THE WEB(JWT Secrets) (0) | 2023.05.03 |
[CryptoHack] CRYPTO ON THE WEB(JSON WEB TOKENS, JWT Sessions, No Ways JOSE) (0) | 2023.05.01 |