lhywk 님의 블로그

[Dreamhack] Recover 본문

Reversing/Dreamhack

[Dreamhack] Recover

lhywk 2026. 1. 18. 01:39

문제

본 문제에서는 chall 바이너리와 encrypted 파일이 제공됩니다.

chall 바이너리는 플래그가 담긴 flag.png 파일을 정해진 방식으로 암호화하여 encrypted 파일로 저장합니다.

flag.png 파일을 복구하여 플래그를 획득하세요.

문제 풀이

해당 문제의 바이너리는 chall, encrypted 2개가 제공됩니다.

문제를 읽어보면 chall 바이너리가 flag.png 파일을 암호화하여 encrypted 파일로 저장한다고 되어있습니다.

먼저 chall 바이너리를 실행해 보겠습니다.

실행하면 fopen() error 문자열을 출력합니다.

아마도 flag.png가 없어서 띄운 것 같습니다.

 

IDA를 통해 chall 코드를 보겠습니다.

main 디컴파일

해당 코드 동작은 다음과 같습니다.

1. flag.png 파일을 바이너리 읽기 모드로 열어 stream 포인터에 할당 -> 에러 발생 시 fopen() error 출력

2. encrypted 파일을 바이너리 쓰기 모드로 열어 s 포인터에 할당 -> 에러 발생시 fopen() error 출력 후 stream 파일 포인터 close

3. stream 데이터를 한 바이트씩 끝까지 읽어 들임

4. 읽은 데이터에 v6 배열의 값을 4바이트로 반복해서 사용하여 한 바이트씩 xor 연산

5. 그 결과에 19를 더함

6. s 포인터에 연산 값을 쓰기

7. v5 카운터를 1 증가시키고 3으로 돌아감 ( 반복 )

8. 파일 포인터 모두 close

 

ptr ^= v6[v5 % 4];
ptr += 19;

해당 코드가 암호화를 처리하는 코드입니다.

flag.png 파일의 데이터를 1바이트씩 암호화합니다.

 

ptr = (ptr ^ v6[v5%4]) + 19

위 코드를 복호화하기 위한 역연산 식은

(ptr - 19) ^ v6[v5%4]

로 구성됩니다.

 

v6의 값을 IDA에서 확인해 보겠습니다.

 

v6 배열 값 확인

역시 % 4 연산을 사용하고 있으니 해당 배열은 4바이트 값을 가지고 있습니다.

 

이제 복호화를 위한 역연산 코드를 작성하겠습니다.

 

key = [0xDE, 0xAD, 0xBE, 0xEF]

with open("encrypted", "rb") as f:
    data = bytearray(f.read())
    
for i in range(len(data)):
    data[i] = (data[i] - 19) & 0xFF
    data[i] = data[i] ^ key[i % 4]

with open("flag.png", "wb") as f:
    f.write(data)

encrpyted 파일을 열어 데이터를 읽어 들이고

복호화 연산 수행 후 원래의 파일인 flag.png를 쓰기로 열어 연산을 수행한 데이터를 씁니다.

 

flag 획득

해당 코드를 실행하면 flag.png이 복구가 되고 플래그를 획득합니다.

'Reversing > Dreamhack' 카테고리의 다른 글

[Dreamhack] flag printer  (0) 2026.01.26
[Dreamhack] My Favorite Fruit  (0) 2026.01.21
[Dreamhack] Easy Assembly  (0) 2026.01.10
[Dreamhack] r-xor-t  (0) 2026.01.01
[Dreamhack] Small Counter  (0) 2025.12.28