Double Encryption
์ํธํค ์ ์์กฐ์ฌ๊ฐ ๊ฐ๋ฅํ๋ค๋ฉด? ์ํธํค ํฌ๊ธฐ๋ฅผ ๋์ด๋ฉด ๋๋ค!
์ํธ ์๊ณ ๋ฆฌ์ฆ Cipher1 = Enc(Plan, key1)
๊ฐํ๋ ์๊ณ ๋ฆฌ์ฆ : Cipher2 = Enc(Cipher1, key2)
๋ธ๋ก ํฌ๊ธฐ๋ ๊ทธ๋๋ก, ์ํธํค ํฌ๊ธฐ๋ 2๋ฐฐ๋ก ๊ฐํํ์๋ค.
๊ณผ์ฐ ๋๋ฐฐ์ ์์ ์ฑ์ ๊ฐ์ง๊น?
Cipher1 = Enc(Plan, key1) → ํค ํฌ๊ธฐ 2^n ์ผ ๋, Cipher2 = Enc(Cipher1, key2) → ํค ํฌ๊ธฐ 2^2n์ ๊ธฐ๋ํ์ง๋ง MITM attack ์ ์ด์ฉํ๋ฉด 2^(n+1)๋ก ๊ณต๊ฒฉ์ด ๊ฐ๋ฅํ๋ค.
MITM (Meet In The Middle) ์ด๋?
์ฃผ์ด์ง (ํ๋ฌธ(P), ์ํธ๋ฌธ(C)) ์์ ๋ํ์ฌ, ์ํธํค key1, key2๋ฅผ ์ฐพ๋ ๊ณต๊ฒฉ
ํ๋ฌธ P ๋ฅผ ๊ฐ๋ฅํ ๋ชจ๋ key1์ผ๋ก ์ํธํ ํ์ฌ ์ฌ์ ์ ์ ์ฅํ๋ค.
์ํธ๋ฌธ C๋ฅผ ๊ฐ๋ฅํ ๋ชจ๋ key2๋ก ๋ณตํธํ ํ์ฌ ์ ์ฅํ ์ฌ์ ์์ ์ฐพ๋๋ค.
ํ์ด ๊ณผ์
from Crypto.Cipher import DES
import signal
import os
if __name__ == "__main__":
# ํ๋ก๊ทธ๋จ์ 15์ด ํ์ ์ข
๋ฃํ๋๋ก ์๋ ์ค์
signal.alarm(15)
with open("flag", "rb") as f:
flag = f.read()
## key : 'Dream_' + 4๋ฐ์ดํธ์ ๋๋ค + 'Hacker'
key = b'Dream_' + os.urandom(4) + b'Hacker'
## key ๋ฅผ 8byte ์ฉ ๋๋
key1 = key[:8]
key2 = key[8:]
print("4-byte Brute-forcing is easy. But can you do it in 15 seconds?")
# key1, key2๋ฅผ ์ฌ์ฉํ๋ DES ์ค๋ผํด ์์ฑ
cipher1 = DES.new(key1, DES.MODE_ECB)
cipher2 = DES.new(key2, DES.MODE_ECB)
# Double Encryption ์๋ณตํธํ ํจ์ ์ ์
encrypt = lambda x: cipher2.encrypt(cipher1.encrypt(x))
decrypt = lambda x: cipher1.decrypt(cipher2.decrypt(x))
# 'DreamHack_blocks'๋ฅผ Double Encryption ํ ์ํธ๋ฌธ ์ ๊ณต
print(f"Hint for you :> {encrypt(b'DreamHack_blocks').hex()}")
# ์๋์ 'give_me_the_flag'์ ์ํธ๋ฌธ์ ์ ๋ฌํ๋ฉด flag๋ฅผ ์ป๋ ํ์
msg = bytes.fromhex(input("Send your encrypted message(hex) > "))
if decrypt(msg) == b'give_me_the_flag':
print(flag)
else:
print("Nope!")
- Cipher1์ ํค 2๋ฐ์ดํธ๋ฅผ ๋ชจ๋ ๋์ ํ์ฌ b‘DreamHack_blocks’๋ฅผ ์ํธํ ๊ฐ์ ์ฌ์ ์ ์ ์ฅํ๋ค. ์ฌ์ ์๋ { ์ํธ๋ฌธ : 2๋ฐ์ดํธ ํค} ํํ๋ก ์ ์ฅํ๋ค.
- ํต์ ์ผ๋ก ์ํธ๋ฌธ์ ๋ฐ๊ณ , cipher2์ ํค 2๋ฐ์ดํธ๋ฅผ ๋์ ํ์ฌ ๋ณตํธํํ๋ค. ์ด ๊ฐ์ด 1์์ ๋ง๋ ์ฌ์ ์ ์์ผ๋ฉด ๊ทธ ๋, ์ฌ์ ์ 2 ๋ฐ์ดํธ ํค ๊ฐ๊ณผ, cipher2๋ฅผ ๋ณตํธํํ ํค ๊ฐ์ ์ ์ฒดํค๋ก ํ์ ํ๋ค.
- ์์ ๋ฐฉ๋ฒ์ผ๋ก ์ฐพ์ ํค๋ฅผ ์ฌ์ฉํ์ฌ b‘give_me_the_flag’๋ฅผ ์ํธํ ๊ฐ์ ์๋ฒ๋ก ์ ๋ฌํ๋ค.
ํ์ด ์ฝ๋
from Crypto.Cipher import DES
from pwn import *
key = b'Dream_' + bytearray(4) + b'Hacker' # ํค ํ์ ์ ์: 'Dream_' + 4๋ฐ์ดํธ์ ๋น ๋ฐ์ดํธ ๋ฐฐ์ด + 'Hacker'
# key1์ ๋ถ๋ถ์ ๋ธ๋ฃจํธํฌ์ฑํ์ฌ ๋ชจ๋ ๊ฐ๋ฅํ ๊ฐ์ ๋ํด ์ํธํ๋ ํ
์คํธ๋ฅผ ์ ์ฅ
m = {}
for i in range(0, 256 * 256):
key1 = key[:6] + int.to_bytes(i, 2, 'big')
cipher1 = DES.new(key1, DES.MODE_ECB)
cipher_text = cipher1.encrypt(b'DreamHack_blocks') # 'DreamHack_blocks' ๋ฌธ์์ด ์ํธํ
m[cipher_text] = int.to_bytes(i, 2, 'big') # {"key1๋ก ์ํธํ๋ ์ํธ๋ฌธ", "key1์ "}
r = remote('host3.dreamhack.games', 18638)
data = r.recvline()
data = r.recvline()[16: -1]
print(data)
# 16์ง์๋ก ๋ ์ํธํ๋ ๊ฐ์ ๋ฐ์ดํธ ๋ฐฐ์ด๋ก ๋ณํ
cipher_text3 = int.to_bytes(int(data, 16), 16, 'big')
ans = 0
# key2๋ฅผ ๋ธ๋ฃจํธํฌ์ฑํ์ฌ ๋ณตํธํํ ๊ฐ์ด ๋์
๋๋ฆฌ์ ์๋์ง ํ์ธ.
for i in range(0, 256 * 256):
key2 = int.to_bytes(i, 2, 'big') + key[10:]
cipher2 = DES.new(key2, DES.MODE_ECB)
cipher_text2 = cipher2.decrypt(cipher_text3)
if cipher_text2 in m:
ans = m.get(cipher_text2) + int.to_bytes(i, 2, 'big')
# ๋ ๊ฐ์ ํค ๋ถ๋ถ์ผ๋ก DES ์ํธ ๊ฐ์ฒด ์์ฑ
cipher1 = DES.new(key[:6] + ans[:2], DES.MODE_ECB)
cipher2 = DES.new(ans[2:] + key[10:], DES.MODE_ECB)
# 'give_me_the_flag' ๋ฌธ์์ด์ ์ด์ค DES๋ก ์ํธํ
send_msg = cipher2.encrypt(cipher1.encrypt(b'give_me_the_flag'))
print(send_msg.hex())
r.sendline(send_msg.hex().encode('ascii'))
r.interactive()
'๐ดโโ ๏ธ CTF ๐ดโโ ๏ธ > ๐งฎ ์ํธํ ๐งฎ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Dream Hack - Crypto] Private Storage (1) | 2024.01.23 |
---|---|
[Dream Hack - Crypto] Padding Oracle (0) | 2023.12.29 |
[Dream Hack - Crypto] Pyploit (2) | 2023.12.18 |
[Dream Hack - Crypto] [LINE CTF 2021] babycrypto1 (2) | 2023.12.12 |
[Dream Hack - Crypto] X-Time Pad (0) | 2023.12.09 |