또 뭐하지
[Dreamhack] No Shift Please! 본문
풀이
from AES import AES_implemented
import os
# For real AES without modification, this challenge is unsolvable with modern technology.
# But let's remove a step.
ret = lambda x: None
AES_implemented._shift_rows = ret
AES_implemented._shift_rows_inv = ret
# Will it make a difference?
secret = os.urandom(16)
key = os.urandom(16)
flag = open("flag.txt", "r").read()
cipher = AES_implemented(key)
secret_enc = cipher.encrypt(secret)
assert cipher.decrypt(secret_enc) == secret
print(f"enc(secret) = {bytes.hex(secret_enc)}")
while True:
option = int(input("[1] encrypt, [2] decrypt: "))
if option == 1: # Encryption
plaintext = bytes.fromhex(input("Input plaintext to encrypt in hex: "))
assert len(plaintext) == 16
ciphertext = cipher.encrypt(plaintext)
print(f"enc(plaintext) = {bytes.hex(ciphertext)}")
if plaintext == secret:
print(flag)
exit()
elif option == 2: # Decryption
ciphertext = bytes.fromhex(input("Input ciphertext to decrypt in hex: "))
assert len(ciphertext) == 16
if ciphertext == secret_enc:
print("No way!")
continue
plaintext = cipher.decrypt(ciphertext)
print(f"dec(ciphertext) = {bytes.hex(plaintext)}")
제공된 파일을 살펴보면, 제일 먼저 aes에서 shift_row 함수를 없앤 것을 확인할 수 있다.
그 다음 16바이트 secret 값과 key값을 랜덤 생성하고 secret을 암호화한 값을 보여준다.
[1] encrypt에서는 16바이트 평문을 받아 암호화를 해주고, 입력된 평문이 secret 값과 동일하면 flag를 출력한다.
[2] decrypt에서는 16바이트 암호문을 받아 복호화를 해주고, 만약 enc(secret)값을 입력했을때는 no way를 출력한다.
aes에서 shift row는 확산 성질을 부여한다.
이때 확산(Diffusion)이란 평문과 암호문과의 관계를 감추는 성질로, 평문 한 비트의 변화가 암호문의 모든 비트에 확산된다.
문제를 실행시켜보면 먼저 암호화된 secret 값을 받을 수 있다.
enc(secret)을 복호화해봤다. 역시 no way가 잘 출력된다.
그러면 그 확산이라는게 어떻게 없어진 것인지 확인해보기 위해서, 아무값으로 암호화를 해봤다.
첫 번째 출력 : 8edd0a531ce6f0a9bd7b277b d62e3045
두 번째 출력 : 8edd0a531ce6f0a9bd7b277b eb4ac428
세 번째 출력 : 8edd0a531ce6f0a9bd7b277b da351b06
8자리 단위까지만 값이 바뀌는 것 같다 다른 값으로 또 확인을 해봤다.
첫 번째 출력 : 8edd0a531ce6f0a9 bd7b277b da351b06
두 번째 출력 : 8edd0a531ce6f0a9 ce19b754 4cc70ad8
8자리 단위로 바뀌는게 확인됐다. 그리고 복호화도 동일한지 확인해봤다.
첫 번째 출력 : c4e27096 a9e3a1f2 b75caf7c 86996012
두 번째 출력 : c4e27096 a9e3a1f2 b75caf7c fe752d0f
첫 번째 출력 : c4e27096 a9e3a1f2 b75caf7c fe752d0f
두 번째 출력 : c4e27096a9e3a1f2 75063209 fe752d0f
복호화도 동일한 것으로 확인했다. 그러면 enc(secret) 값을 나눠서 입력하면 원하는 값을 얻을 수 있을 것 같다.
enc(secret) 값을 앞 8자리와 나머지로 분류하여 복호화해줬다.
나온 결과값을 합쳐 암호화를 해줬더니 flag를 확인할 수 있었다.
'Write-up > Crypto' 카테고리의 다른 글
[Dreamhack] What is This??? (0) | 2024.10.04 |
---|---|
[Dreamhack] STREAMer-Prototype (0) | 2024.10.04 |
[Dreamhack] Double DES (0) | 2024.09.20 |
[Dreamhack] ICM2022 (0) | 2024.09.13 |
[Dreamhack] Robot Only (0) | 2024.05.13 |