https://dreamhack.io/wargame/challenges/851
Small Counter
Description플래그를 생성하는 함수 flag_gen()을 호출하고 플래그를 출력하세요. 플래그 형식은 DH{...} 입니다.Hint: https://dreamhack.io/lecture/courses/55
dreamhack.io
리버싱 공부를 좀 해야할 것 같은데, 손을 안댄지 너무 오래돼서 두렵다.

우선 파일을 받아서 아이다로 열어보았다.
이 화면에서 스페이스바를 누르면 view로 넘어갈 수 있다.

옆에는 이 실행 파일 내에 존재하는 여러가지 함수들이 있고, 눌러서 그 부분으로 이동할 수 있다.
일단 main 함수와 start 함수로 이동해서 살펴보았다.

f5를 누르면 디컴파일링된 결과를 확인할 수 있는데, start 함수를 찍고 들어왔는데 아무래도 여기는 아닌 것 같다.

main 함수를 디컴파일링해보니 그래도 어떤 동작을 하는지 파악은 할 수 있을 것 같다.
프로그램 실행 시 10부터 1까지 카운트다운을 찍고, i가 3일 때 특이한 동작을 하는 것을 알 수 있다.
src에 문자열을 strcpy로 복사하고, memcpy로 src의 0x45 바이트를 dest로 복사한다.
결국 아무것도 출력되지 않고 main 함수가 끝나고 있으므로, 플래그가 출력되도록 조작해주어야한다.

실행하기 위해서 gdb <프로그램명> = gdb chall 해주었다.
그리고 run으로 프로그램을 실행해볼 수 있다.
일단 실행하면 10부터 시작해서 카운트를 시작하고 1을 찍고 프로그램이 종료된다.
https://h-factory.tistory.com/793
[Dreamhack] Small Counter
풀이힌트 링크를 보니 gdb를 사용하라고 되어 있어서 gdb에서 열어보았다. 파일을 실행하면 입력할 틈도 없이 출력되고 끝이 나게 된다. 입력값이 10개라는 건가..? 문장이 10글자..? 방향을 못
h-factory.tistory.com
여기까지는 알겠 다음으로 뭐부터 해야할지 감이 안잡혀서 라이트업을 참고했다.

nice와 종료로 분기되는 이 지점에 주목하신 것 같다.
[rbp+var4]가 5이면 flag_gen이 있는 쪽으로 분기하는 것을 알 수 있다.
pwndbg> disassemble main
Dump of assembler code for function main:
0x0000000000001494 <+0>: endbr64
0x0000000000001498 <+4>: push rbp
0x0000000000001499 <+5>: mov rbp,rsp
0x000000000000149c <+8>: sub rsp,0xf0
0x00000000000014a3 <+15>: mov DWORD PTR [rbp-0x4],0x0
0x00000000000014aa <+22>: lea rax,[rip+0xb53] # 0x2004
0x00000000000014b1 <+29>: mov rdi,rax
0x00000000000014b4 <+32>: call 0x1090 <puts@plt>
0x00000000000014b9 <+37>: mov DWORD PTR [rbp-0x4],0xa
0x00000000000014c0 <+44>: jmp 0x15a0 <main+268>
0x00000000000014c5 <+49>: mov eax,DWORD PTR [rbp-0x4]
0x00000000000014c8 <+52>: mov esi,eax
0x00000000000014ca <+54>: lea rax,[rip+0xb41] # 0x2012
0x00000000000014d1 <+61>: mov rdi,rax
0x00000000000014d4 <+64>: mov eax,0x0
0x00000000000014d9 <+69>: call 0x10b0 <printf@plt>
0x00000000000014de <+74>: cmp DWORD PTR [rbp-0x4],0x3
0x00000000000014e2 <+78>: jne 0x159c <main+264>
0x00000000000014e8 <+84>: movabs rax,0x38383830357b4d49
0x00000000000014f2 <+94>: movabs rdx,0x6a37386a32336a39
0x00000000000014fc <+104>: mov QWORD PTR [rbp-0xf0],rax
0x0000000000001503 <+111>: mov QWORD PTR [rbp-0xe8],rdx
0x000000000000150a <+118>: movabs rax,0x3035363435676a39
0x0000000000001514 <+128>: movabs rdx,0x6a68383234303438
0x000000000000151e <+138>: mov QWORD PTR [rbp-0xe0],rax
0x0000000000001525 <+145>: mov QWORD PTR [rbp-0xd8],rdx
0x000000000000152c <+152>: movabs rax,0x6838306969326968
0x0000000000001536 <+162>: movabs rdx,0x3833356a68693437
0x0000000000001540 <+172>: mov QWORD PTR [rbp-0xd0],rax
0x0000000000001547 <+179>: mov QWORD PTR [rbp-0xc8],rdx
0x000000000000154e <+186>: movabs rax,0x3667376a33343568
0x0000000000001558 <+196>: movabs rdx,0x68696a386b6a356b
0x0000000000001562 <+206>: mov QWORD PTR [rbp-0xc0],rax
0x0000000000001569 <+213>: mov QWORD PTR [rbp-0xb8],rdx
0x0000000000001570 <+220>: mov DWORD PTR [rbp-0xb0],0x7d663232
0x000000000000157a <+230>: mov BYTE PTR [rbp-0xac],0x0
0x0000000000001581 <+237>: lea rcx,[rbp-0xf0]
0x0000000000001588 <+244>: lea rax,[rbp-0x50]
0x000000000000158c <+248>: mov edx,0x45
0x0000000000001591 <+253>: mov rsi,rcx
0x0000000000001594 <+256>: mov rdi,rax
0x0000000000001597 <+259>: call 0x10c0 <memcpy@plt>
0x000000000000159c <+264>: sub DWORD PTR [rbp-0x4],0x1
0x00000000000015a0 <+268>: cmp DWORD PTR [rbp-0x4],0x0
0x00000000000015a4 <+272>: jg 0x14c5 <main+49>
0x00000000000015aa <+278>: cmp DWORD PTR [rbp-0x4],0x5
0x00000000000015ae <+282>: jne 0x15fe <main+362>
0x00000000000015b0 <+284>: lea rax,[rip+0xa5f] # 0x2016
0x00000000000015b7 <+291>: mov rdi,rax
0x00000000000015ba <+294>: call 0x1090 <puts@plt>
0x00000000000015bf <+299>: mov eax,DWORD PTR [rbp-0x4]
0x00000000000015c2 <+302>: mov DWORD PTR [rbp-0x8],eax
0x00000000000015c5 <+305>: mov edx,DWORD PTR [rbp-0x8]
0x00000000000015c8 <+308>: lea rcx,[rbp-0xa0]
0x00000000000015cf <+315>: lea rax,[rbp-0x50]
0x00000000000015d3 <+319>: mov rsi,rcx
0x00000000000015d6 <+322>: mov rdi,rax
0x00000000000015d9 <+325>: call 0x11c9 <flag_gen>
0x00000000000015de <+330>: lea rax,[rbp-0xa0]
0x00000000000015e5 <+337>: mov rsi,rax
0x00000000000015e8 <+340>: lea rax,[rip+0xa2d] # 0x201c
0x00000000000015ef <+347>: mov rdi,rax
0x00000000000015f2 <+350>: mov eax,0x0
0x00000000000015f7 <+355>: call 0x10b0 <printf@plt>
0x00000000000015fc <+360>: jmp 0x160d <main+377>
0x00000000000015fe <+362>: lea rax,[rip+0xa1c] # 0x2021
0x0000000000001605 <+369>: mov rdi,rax
0x0000000000001608 <+372>: call 0x1090 <puts@plt>
0x000000000000160d <+377>: mov eax,0x0
0x0000000000001612 <+382>: leave
0x0000000000001613 <+383>: ret
End of assembler dump.
다시 gdb로 돌아와서 disassemble main을 통해 어셈블리어 언어로 변경해주었다.
0x00000000000015aa <+278>: cmp DWORD PTR [rbp-0x4],0x5
바로 이 부분이 분기되는 조건이라는 것을 알 수 있다.
여기에 브레이크 포인트를 잡고 값을 5로 설정해주면 조건을 만족하면서 플래그를 출력한다.

브레이크 포인트를 걸 때는 break *(bp를 걸 위치) 명령어를 사용해주면 된다.
다시 실행해보면 걸어준 포인트에서 실행이 멈추게 된다.

멈춘 상태에서 set *(int*)($rbp-4) = 5를 통해 값을 5로 덮어씌워줬다.
그리고 c로 계속 진행시켜주면 플래그가 출력되는 것을 볼 수 있다.

공부할 겸 추가적으로 알아두면 좋았을 핵심 코드를 살펴보았다.
이 부분이 바로 i를 rbp-4에서 꺼내서 5랑 비교하는 부분이다.
jne는 ZF가 0일 때 점프한다는 것으로 i != 5이면 루프를 빠져나간다는 말이다.
현재 값은 1이므로 점프가 예정되어있는 상태로 원래대로라면 루프가 종료되어야 한다.
하지만 set으로 값을 5로 바꿔주어서 jne 조건이 깨져서 분기 흐름을 조작한 것이다.
'해킹 스터디' 카테고리의 다른 글
| [Dreamhack] Stop before stops! (0) | 2025.07.27 |
|---|---|
| [DreamHack] easy-login (2) | 2025.07.24 |
| [DreamHack] Addition calculator (1) | 2025.07.23 |
| [DreamHack] curling (1) | 2025.07.12 |
| [DreamHack] Description (1) | 2025.07.09 |
