문제 링크 : https://dreamhack.io/wargame/challenges/2176
EZ-Des
DES 근데 이제 뭔가 많은
dreamhack.io
문제 설명
DES 근데 이제 뭔가 많은
write - up
문제에서는 keys.txt 와 flag.txt 라는 텍스트 파일을 준다. keys는 16진수 키 후보들 리스트 같아보이고, flag 는 DH{???} 형태를 가진 400바이트가 답이라는 힌트를 준다. 추가로 des.py 파일도 주는데, 다음과 같다.
from flask import Flask, send_file, make_response, render_template_string
from Crypto.Cipher import DES
import random
import time
import os
app = Flask(__name__)
FLAG_FILE = 'flag.txt'
KEY_FILE = 'keys.txt'
CIPHER_FILE = 'ciphertext.txt'
BLOCK_SIZE = 8
NUM_BLOCKS = 50
def read_flag(filename=FLAG_FILE, target_len=400):
with open(filename, 'rb') as f:
flag = f.read()
if len(flag) < target_len:
flag += b'A' * (target_len - len(flag))
return flag[:target_len]
def read_keys(filename=KEY_FILE):
with open(filename, 'r') as f:
lines = f.readlines()
keys = [bytes.fromhex(line.strip()) for line in lines if line.strip()]
assert len(keys) == NUM_BLOCKS and all(len(k) == 8 for k in keys)
return keys
def split_blocks(msg, block_size=BLOCK_SIZE):
return [msg[i:i+block_size] for i in range(0, len(msg), block_size)]
def triple_des_ede(block, key):
c1 = DES.new(key, DES.MODE_ECB).encrypt(block)
c2 = DES.new(key, DES.MODE_ECB).decrypt(c1)
c3 = DES.new(key, DES.MODE_ECB).encrypt(c2)
return c3
def encrypt_flag(plaintext, keys, seed):
idxs = list(range(NUM_BLOCKS))
random.seed(seed)
random.shuffle(idxs)
blocks = split_blocks(plaintext, BLOCK_SIZE)
ciphertext_blocks = []
for i, block in enumerate(blocks):
key = keys[idxs[i]]
ct = triple_des_ede(block, key)
ciphertext_blocks.append(ct)
return b''.join(ciphertext_blocks)
@app.route('/')
def home():
return render_template_string('''
<h2>다운로드</h2>
<form action="/download">
<button type="submit">ciphertext.txt 다운로드</button>
</form>
<form action="/keys">
<button type="submit">keys.txt 다운로드</button>
</form>
''')
@app.route('/download')
def download_ciphertext():
pt = read_flag()
keys = read_keys()
seed = int(time.time())
ct = encrypt_flag(pt, keys, seed)
tmpfile = 'ciphertext.txt'
with open(tmpfile, 'wb') as f:
f.write(ct)
os.utime(tmpfile, (seed, seed))
resp = make_response(send_file(tmpfile, as_attachment=True))
resp.headers['X-Used-Seed'] = str(seed)
return resp
@app.route('/keys')
def download_keys():
return send_file(KEY_FILE, as_attachment=True)
if __name__ == '__main__':
app.run(host="0.0.0.0")
추가로 문제 사이트에선 VM을 가동시킬 수 있었고, 가동시킨 VM의 서버주소로 들어가면 ciphertext.txt 파일을 받을 수 있었다. ciphertext 파일을 notepad로 열었을때 꺠져있는것으로보아 암호화된 flag일 것이라 생각했고, keys 파일이랑 ciphrttext파일 을 엮어서 복호화를 진행시켜야한다는 것까지는 이해를 했으나 코드를 구현할 능력이 없기에... GPT 선생님께 여쭤본 결과 다음과 같은 코드를 내주셨다.
# solve.py
import os
import random
from Crypto.Cipher import DES
BLOCK_SIZE = 8
NUM_BLOCKS = 50
def split_blocks(msg, block_size=BLOCK_SIZE):
return [msg[i:i+block_size] for i in range(0, len(msg), block_size)]
def triple_des_ede_decrypt(block, key):
c1 = DES.new(key, DES.MODE_ECB).decrypt(block)
c2 = DES.new(key, DES.MODE_ECB).encrypt(c1)
c3 = DES.new(key, DES.MODE_ECB).decrypt(c2)
return c3
def try_seed(seed, ciphertext, keys):
idxs = list(range(NUM_BLOCKS))
random.seed(seed)
random.shuffle(idxs)
cipher_blocks = split_blocks(ciphertext)
plain_blocks = [b""] * NUM_BLOCKS
for i, block in enumerate(cipher_blocks):
key = keys[idxs[i]]
plain_blocks[i] = triple_des_ede_decrypt(block, key)
plaintext = b"".join(plain_blocks)
start = plaintext.find(b"DH{")
end = plaintext.find(b"}", start)
if start != -1 and end != -1:
return plaintext[start:end+1]
return None
def main():
ciphertext = open("ciphertext.txt", "rb").read()
keys = [bytes.fromhex(line.strip()) for line in open("keys.txt") if line.strip()]
base_seed = int(os.path.getmtime("ciphertext.txt"))
print("[*] Base seed:", base_seed)
for delta in range(-3, 4):
seed = base_seed + delta
flag = try_seed(seed, ciphertext, keys)
if flag:
print("[+] Found FLAG with seed", seed, ":", flag.decode(errors="ignore"))
break
else:
print("[-] FLAG not found in nearby seeds")
if __name__ == "__main__":
main()
해당 코드를 작동시키면 다음과 같이 나오고 정답이 맞았다. (2시간 걸림...)
[*] Base seed: /*seed 자리*/
[+] Found FLAG with seed /*seed 자리*/ : DH{/*진짜 답을 써놓긴 애매해서 주석처리 이 자리에 flag 나왔음.*/}

'2025 - 2' 카테고리의 다른 글
| 2주차 워게임 [Hidden] 공부 - XOR암호화 코드 분석 (0) | 2025.09.30 |
|---|---|
| 2주차 워게임 [Hidden] 문제풀이 (1) | 2025.09.30 |
| 2주차 기술 [ESRC 보안동향보고서] (1) | 2025.09.30 |
| 1주차 워게임 [EZ-Des] 공부 (1) | 2025.09.23 |
| 1주차 기술 [저작권 위반 안내 메일로 위장한 PureHVNC 악성코드 유포 사례] (1) | 2025.09.23 |