Season 1/워게임

[CryptoHack] SYMMETRIC CIPHERS(ECB ORACLE)

작성자 - ikbak_2

ECB는 간단한 모드로, 각 평문 블록이 완전히 독립적으로 암호화됩니다..
이러한 경우, 당신의 입력이 비밀 플래그 앞에 붙여지고, 암호화되고, 그게 전부입니다.
우리는  심지어 복호화 기능도 제공하지 않습니다.
아마도 "ECB 오라클"이 있을 때 패딩 오라클이 필요하지 않을까요?

https://aes.cryptohack.org/ecb_oracle/

더보기
from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad KEY = ? FLAG = ? @chal.route('/ecb_oracle/encrypt/<plaintext>/') def encrypt(plaintext): plaintext = bytes.fromhex(plaintext) padded = pad(plaintext + FLAG.encode(), 16) cipher = AES.new(KEY, AES.MODE_ECB) try: encrypted = cipher.encrypt(padded) except ValueError as e: return {"error": str(e)} return {"ciphertext": encrypted.hex()}

 

먼저 코드를 보게 되면

AES로 암호화 하기 전에 pad 함수를 사용해서,

입력한 평문 + Flag값의 암호화, 그리고 블록의 크기를 16바이트씩 맞추어 사용한다.

 

평문 + Flag값으로 암호화를 진행하여,

한 글자 (예시:"a")15개를 넣어두면 Flag값의 첫 한글자까지 해서 한 블록으로 묶인다.

 

그래서

브루트보스를 통해 "a"15개와, 무작위로 1바이트를 대입 했을때 한 글자의 flag를 알고

브루트보스를 통해 "a"14개+알고 있는 1바이트와, 무작위로 1바이트를 대입 했을때

한 글자의 flag를 아는 방식으로 패딩을 하나씩 줄여 flag 값을 알 수 있다.

 

먼저, 16바이트, 2블록으로 잡아 범위를 먼저 32로 잡고, 브루트 포싱을 하였다.

그 다음에 길이가 안나오면 16바이트, 3블록으로 잡아 48로 잡을 예정이었다.

from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad import time import requests def get_cipher(plaintext): chellenge_site = 'https://aes.cryptohack.org/ecb_oracle/encrypt/'+plaintext.hex()+'/' r = requests.get(chellenge_site) ciphertext = r.json() return bytes.fromhex(ciphertext['ciphertext']) flag=b'' for i in range(0, 32): plaintext = b'\x61' * (31 - i) ciphertext = get_cipher(plaintext)[:32] plaintext += flag print("try %d" %(i+1)) for j in range(33, 127): plaintext = plaintext[:31] plaintext += j.to_bytes(1, byteorder='big') wr_ci = get_cipher(plaintext)[:32] if (wr_ci == ciphertext): flag += j.to_bytes(1, byteorder='big') print(flag) break time.sleep(1)
꽤 시간이 오래걸린다.

 

플래그값이 나왔다.

플래그값은 'crypto{p3n6u1n5_h473_3cb}'이다.

   

 

이 글이 도움이 되었다면, 응원의 댓글 부탁드립니다.