| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- Simple Crack Me
- ADsP
- id pool
- dreamhack
- writeup
- AWS
- OWASP TOP 10
- 라운드로빈
- 병행성
- randzzz
- OpenClaw
- 교체 정책
- user pool
- HRRN
- ADsP책추천
- 시나공ADsP
- rev-basic-4
- ADsP시험
- cloudgoat
- rev-basic-3
- Juice Shop
- adsp독학
- wargame
- ADsP합격
- 운영체제
- Pacu
- 세그먼테이션
- OS
- 26년 1회
- ADsP교재
- Today
- Total
chon
[Dreamhack] Recover 본문
[ 문제 링크 | https://dreamhack.io/wargame/challenges/1569 ]
[ 문제 설명 ]

드림핵 워게임 Reversing Level 1 문제로, 파일 입출력과 간단한 XOR 기반 암호화를 분석하는 문제이다.
[ 문제 풀이 ]

- 제공 파일:
- chall (암호화 프로그램)
- encrypted (암호화된 결과물)
문제 설명에서 나왔듯이 두 개의 파일이 제공된다.
flag.png --> (chall) --> encrypted 이런 흐름으로 암호화가 되었고, 우리가 해야 할 일은 encrypted -- (역연산) --> flag.png --> 플래그 추출이다.
chall을 실행하면 즉시 fopen() error가 출력되며 종료된다.

이는 chall이 실행 과정에서 외부 파일(flag.png)을 필요로 하지만, 문제 환경에는 해당 파일이 존재하지 않기 때문이다.
- open, openat, fopen 관련 syscall 확인하는 명령어
pwndbg> !strace -e openat ./chall

프로그램이 어떤 파일을 열려고 시도하는지 확인하기 위해 strace를 사용하여 open/openat 계열 시스템 콜을 추적하였다.
- Entry point 기반 수동 디스어셈블
info files

심볼이 제거된 바이너리이므로 main 함수 대신
Entry point부터 직접 디스어셈블하여 분석을 진행하였다.
전체 코드 디스어셈블
disas 0x1120, 0x1363
- 0x1209 → main 함수 시작
- fopen("flag.png","rb")
- fopen("encrypted","wb")
- fread → 1바이트
- XOR → ADD 0x13 → fwrite
암호화 로직 요약 (ASM → C)
key = *(0x2004) // 4바이트 키
while (fread(&b, 1, 1, in) == 1) {
b ^= key[i % 4];
b += 0x13;
fwrite(&b, 1, 1, out);
i++;
}
복호화는 역순
b = (b - 0x13) ^ key[i % 4]
PNG 파일은 항상 고정된 8바이트 시그니처 [ 89 50 4E 47 0D 0A 1A 0A ]로 시작한다.
암호화는 XOR + 덧셈 방식이므로, 암호문 앞부분과 평문 시그니처를 이용해 XOR 키를 역으로 계산할 수 있다.
역연산 코드
png_sig = bytes([0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A])
with open("encrypted", "rb") as f:
enc = f.read()
# 키 복구
key = [0]*4
for i in range(4):
key[i] = (enc[i] - 0x13) ^ png_sig[i]
print("key =", key)
# 복호화
out = bytearray()
key = [222, -83, -66, 239]
for i, b in enumerate(enc):
v = (b - 0x13) ^ key[i % 4]
out.append(v & 0xFF)
with open("flag.png", "wb") as f:
f.write(out)
해당 값은 Python의 정수 표현이며 Python에서는 음수도 XOR 연산에 사용 가능하므로 최종적으로 & 0xFF를 통해 바이트 범위로 보정한다. (실제 바이트 값은 & 0xFF로 처리됨)
[ Flag ]


cmd창에서 역연산 코드를 실행하여 flag.png를 복원하고 플래그를 획득하였다.
flag.png 파일을 열면 플래그가 적혀있다.


앞서 찾은 Flag를 입력하면 된다.
'Reversing > Dreamhack Write up' 카테고리의 다른 글
| [Dreamhack] Happy New Year! (0) | 2026.01.14 |
|---|---|
| [Dreamhack] Simple Crack Me Write up (0) | 2025.12.14 |
| [Dreamhack] randzzz Write up (0) | 2025.11.20 |
| [Dreamhack] rev-basic-4 Write up (1) | 2025.11.18 |
| [Dreamhack] rev-basic-3 Write up (0) | 2025.11.02 |