
💡 ECB는 각 일반 텍스트 블록이 완전히 독립적으로 암호화되는 가장 간단한 모드입니다. 이 경우 입력 내용이 비밀 플래그 앞에 추가되고 암호화됩니다. 암호 해독 기능도 제공하지 않습니다. 아마도 "ECB 오라클"이 있을 때 패딩 오라클이 필요하지 않을까요?
이번에는 입력에 뭐가 붙고 암호화되는 것 같다. decrypt도 안해준단다. 근데 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()}
내가 입력하는 plaintextdp FLAG를 붙인 다음 블록크기에 맞게 패딩을 해주고 ECB로 암호화하고 있다.
제일 먼저 input에 1byte씩 늘려가면서 FLAG의 크기가 몇인지 가늠했다.


입력이 7byte가 되었을 때 output의 길이가 16byte 더 길어졌기 때문에 FLAG는 26byte임을 알 수 있다.
그 다음 출력을 그대로 입력에 넣으면 뭐가 되지 않을까 했지만,, decrypt와 encrypt는 다르기에 별다른 효과는 없었다.
구글링을 하다가 아래의 블로그를 찾았다.
padding oracle attack이다. 간단하게 말하자면 패딩을 통해 한 글자씩 알아내는 것이다.


위의 공격을 보여주는 간단한 예시이다. A를 15byte만 보냈을 때와 A 15byte + c 1byte를 보냈을 때 첫 번째 블록의 암호문이 동일하다. 이는 FLAG의 첫 글자 역시 c이기 때문에 그렇다.
따라서 나도 A를 31byte 보냈다가 점차 줄여나가면서 flag를 한 글자씩 알아내면 될 것 같다.
이를 위해서는 먼저 웹과 통신을 해야한다.

개발자도구를 통해 살펴보니 url은 위와 같이 전송되고, 응답은 json 형태로 전달된다.

따라서 request로 받은 것을 json()으로 바꿔주고, 내가 원하는 두 블록 크기인 32byte만큼(64) 잘라주면 된다.
import requests
from tqdm import tqdm
flag=b''
url = 'https://aes.cryptohack.org/ecb_oracle/encrypt/'
for i in range(0,32):
plaintext=b'x41' * (31-i)
print(f'for oracle {plaintext}')
test=url+plaintext.hex()+'/'
rsp=requests.get(test)
js=rsp.json()
check=js['ciphertext'][:64]
plaintext+=flag
for j in tqdm(range(33,127)):
j=chr(j)
flag_test=plaintext+j.encode()
print(f'for test {flag_test}')
test=url+flag_test.hex()+'/'
rsp=requests.get(test)
js=rsp.json()
flag_check=js['ciphertext'][:64]
if(check==flag_check):
flag+=j.encode()
print(flag)
break
print(flag)
코드는 다음과 같다. check가 input을 하나씩 줄이고 실제 flag를 하나씩 더 추가시키는 부분이며, flag_check는 추가된 실제 flag를 brute forcing을 통해 알아내는 부분이다. 하나씩 보내다가 맞으면 반복문을 끝내고 flag에 추가한다.

코드 실행결과는 다음과 같다.

🚩 flag: crypto{p3n6u1n5_h473_3cb}