| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- AWS IAM Role
- AWS 아키텍처 분석
- python
- network
- dreamhack
- reversing.kr
- programmers
- IAM Federation
- AWS 인프라 분석
- AWS
- 프로그래머스
- AWS 사고 사례 분석
- TryHackMe
- 리버싱
- operating system
- reversing
- terraform
- AWS 보안 사고 사례 모음
- 침입 차단 시스템(IPS)
- AWS 인프라 아키텍처
- AWS Active Directory
- Amazon S3
- AWS 3 Tier Architecture
- AWS 침해사고 사례 분석
- AWS 침해 사고 사례 분석
- 드림핵
- 네트워크
- 운영체제
- C
- AWS 보안 아키텍처 분석
- Today
- Total
lhywk 님의 블로그
[Dreamhack] flag printer 본문
문제
Simple Flag Printer
문제 풀이

해당 문제는 4개의 바이너리가 제공됩니다.

다른 바이너리 상관없이 flag-printer를 실행해 동작하는 걸 보니 이 바이너리를 분석하겠습니다.
1. 정적 분석
main 함수를 디컴파일해 분석해 보겠습니다.

1. while 루프를 진입한다.
2. 두 번째 while 루프에서 입력을 받고 sub_1437()함수에 인수를 넣어 호출한 리턴값을 v3에 할당한다.
3. v3가 2가 아니라면 while루프를 탈출한다.
4. 3번 과정이 아니라면 sub_1749()함수를 호출한다.
4. v3가 2를 초과한다면 Invalid Command!를 출력한다.
5. v3이 1이라면 sub_1711(1)함수를 호출한다.
6. v3이 1도 아니고 2도 아니라면 sub_1673()를 호출한다.
v3를 기준으로 조건문들이 분기를 하고 있기 때문에 16번째 줄에 있는 sub_1437() 함수를 분석해 보겠습니다.
sub_1437()

1. 문자열을 a1에 저장한다.
2. 개행 문자를 제거한다.
3. strtok를 사용하여 첫 번째 문자열을 s1에 저장한다.
4. s1이 print와 일치하면 (unsigned __int64)v4 << 32;를 리턴한다. (0)
5. s1이 id와 일치하면 (unsigned __int64)v4 << 32 | 1; 을 리턴한다. (1)
6. s1이 help와 일치하면 (unsigned __int64)v4 << 32 | 2;을 리턴한다. (2)
7. 4,5,6번이 아니라면 v7에 문자열을 복사한다.
8. 0x42값과 문자열을 XOR연산을 수행한다.
9. &-17을 s2에 복사한다.
10. v7과 v2이 일치하지 않으면 (unsigned __int64)v4 << 32 | 0xFFFFFFFF;을 리턴한다. (-1)
11. 10의 과정이 아니라면 v4에 1을 저장하고 s1에 다음 문자열을 저장하고 루프를 다시 돈다.

main함수에서 sub_1437()함수 반환 값이 2라면 sub_1749()함수를 호출합니다.
sub_1749() 함수를 분석해 보겠습니다.
sub_1749()

3개의 출력문을 출력합니다.
help와 s1이 일치하면 2를 리턴한다고 했으니 help를 입력해 보겠습니다.

실제로 help를 입력하면 출력문이 나오는 것을 확인할 수 있습니다.

이번엔 v3가 1이라면 sub_1711() 함수를 호출합니다.
sub_1711 함수를 분석해 보겠습니다.

인자값이 1이라면 id: user(godmode)을 출력하고 아니라면 id: user를 출력합니다.
이때 인자값은 HIDWORD(v3)입니다.
리턴할 때 64비트(8바이트)를 리턴했었고 1이었습니다.
HIDWORD는 0x0000000000000001에서 0이기 때문에 id: user가 출력이 될 겁니다.

실제로 id을 입력하면 id: user이라는 문자열이 출력됩니다.

0이 반환되면 sub_1673() 함수가 호출됩니다.
이때도 인자값이 HIDWORD(v3)로 상위 4바이트를 넣습니다. 아직은 0입니다.
해당 함수를 분석해 보겠습니다.

a1이 참이라면 플래그를 읽고 출력합니다.
거짓이라면 art를 읽고 출력합니다.
지금은 a1이 0이므로 art를 읽고 출력할 것입니다.

예상대로 깃발 그림이 출력됩니다.
코드 분석이 끝났고 그래서 플래그를 출력하려면 a1이 1이 되어야 합니다.
이건 v3의 상위 4바이트를 1로 만들어야 하고 이 값을 바꿀 수 있는 함수는 오직 sub_1437()입니다.

해당 로직을 다시 살펴보겠습니다.
문자열을 v7에 저장을 하고 for루프를 돌며 모든 문자를 0x42와 XOR 연산합니다.
그 결과가 &-17과 똑같은지 확인합니다.
일치하면 v4=1을 합니다.
해당 로직을 역연산 코드로 구현해 보겠습니다.
data = "&-17"
key = 0x42
answer = ""
for i in data:
answer += chr(ord(i) ^ key)
print(answer)

결과는 dosu가 나왔습니다.
저희가 찾던 문자열은 dosu입니다.
상위 4바이트는 1이어야 하고 하위 4바이트는 0이어야 플래그를 획득할 수 있었습니다.

코드를 다시 보면 먼저 우리는 dosu를 입력하여 35번째 줄에 있는 v4 = 1을 해줘야 합니다.
그리고 다시 while루프를 돌면서 print를 입력해야 18줄에 있는
return (unsigned __int64)v4 << 32;이 실행이 되면서
0x0000000100000000이 되어
상위 4바이트는 1
하위 4바이트는 0 값이 됩니다.
결과적으로 dosu print를 입력하면 됩니다.

dosu id는 0x0000000100000000이니까 user(godmode)를 출력합니다.

dosu print를 입력하여 플래그를 획득합니다.
'Reversing > Dreamhack' 카테고리의 다른 글
| [Dreamhack] rev-basic-5 (0) | 2026.01.27 |
|---|---|
| [Dreamhack] rev-basic-7 (0) | 2026.01.27 |
| [Dreamhack] My Favorite Fruit (0) | 2026.01.21 |
| [Dreamhack] Recover (0) | 2026.01.18 |
| [Dreamhack] Easy Assembly (0) | 2026.01.10 |