또 뭐하지

[Dreamhack] No Shift Please! 본문

Write-up/Crypto

[Dreamhack] No Shift Please!

mameul 2024. 9. 27. 15:54
728x90

풀이

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