Write-up/Crypto
[Dreamhack] Insecure Seed
mameul
2024. 10. 31. 21:47
728x90
풀이
먼저 주어진 코드를 살펴보면 아래와 같다.
# DREAMHACK CHALLENGE - INSECURE SEED #
import os
import random
from typing import List
class Seed:
def __init__ (self) -> None:
self.a: int = os.urandom(1)
@staticmethod
def GenerateSeed() -> List[int]:
# seed는 8비트 4개로 이루어진 리스트
seed: bytearray = bytearray(random.getrandbits(8) for x in range(4))
return list(seed)
def CalculateKey(self, seed: List[int]) -> bool:
# self.a와 seed를 xor 연산하여 key를 계산, self.a는 랜덤 1byte
key: List[int] = [0] * len(seed)
for i in range(len(seed)):
result: bytes = bytes([self.a[j] ^ seed[i] for j in range(len(self.a))])
key[i] = int.from_bytes(result, byteorder='little')
return key
def Authentication(self, seed: List[int], k: List[int]) -> bool:
# CalculateKey로 생성된 키와 입력된 키가 일치하는지 비교하여
# 일치하면 Corret!!, 일치하지 않으면 Invalid Key!!를 출력
key = self.CalculateKey(seed)
if key == k:
print('Correct!!')
return True
else:
print('Invalid Key!!')
return False
if __name__ == "__main__":
# 제공해주는 seed 값을 토대로 key를 계산하여 입력하면 flag가 출력됨
s = Seed()
seed = s.GenerateSeed()
print(f"Seed: {seed}")
while 1:
k = input("Key: ").strip().split() # input ex) 41 42 43 44
kl = [int(x) for x in k]
if s.Authentication(seed, kl):
break
print('DH{fake_flag}')
문제에서 키는 a와 seed를 xor하는 단순한 형태로 계산된다. seed는 주어지므로 a에 해당하는 랜덤 1byte의 숫자를 알면 올바른 키를 구할 수 있다. a의 값의 범위가 크지 않으므로 브루트포싱으로 문제가 해결 가능하다.
실행을 해보면 아래와 같이 seed가 주어지고, 키 값을 입력할 수 있는 것을 확인할 수 있다.
익스플로잇 코드는 아래와 같이 작성하였다.
from pwn import *
import re
p = remote("host3.dreamhack.games",12983)
tmp = p.recvline().decode()
seed = list(map(int, re.findall(r'\d+', tmp))) # 제공된 seed를 list로 받아옴
for i in range(256): # a 브루트포스
key = []
for j in range(len(seed)):
key.append(str(i^int(seed[j])).encode()) # a값과 seed를 xor하여 key를 구함
s = b''
for i in range(len(key)):
s += key[i] + b' '
p.sendlineafter('Key:', s)
answer = p.recvline()
if answer != b' Invalid Key!!\n': #Invaild가 나오는 않는 경우에 for문을 끝내고 출력값을 확인함
break
p.interactive()
위 코드를 실행하면 아래와 같이 flag를 확인할 수 있다.
* seed 리스트를 받아오는 부분에서 gpt의 도움을 받았는데 아주 신박하다 정규표현식을 쓰면 노가다를 안해도 되는구나!