Tuesday, 6 September 2016

ICECTF 2016 - DRUMPF BINARY

Binary overview:-
     The Binary has facility to book a suite, book  a room , delete booking and to print booking. The Aim is to change the flow of control to the flag function which obviously prints the flag. The program is protected by Canary, NX and RELRO is partially enabled. The program employs the use of Malloc() and free(). Finding the vulnerability would be a child's play for a experienced exploiter. The vulnerability is called Use after free vulnerability .

 Intro to Use After Free vulnerability:-
      To understand what the Use After Free vulnerability is one needs to understand what are the functions and how they are used wrongly which causes such a vulnerability to rise
  • Malloc() :-  void *malloc(size_t size)                                                         The function allocates the memory given to it and returns a pointer to the location where it is stored or NULL if it fails.
  • Free() :-  void free(void *ptr)                                                                     This function is used to deallocate the memory previously allocated by a calloc, malloc or realloc function. It doesn't return any value.              Certain things to Note here are :
    •  The Free functions doesn't clear the data which is allocated. It just makes that area available for storing data and new data overwrites the previous ones.
    • The pointer pointing to the location isn't deleted and will be reused for the next malloc() unless it is cleared by using *ptr=0. This is the vulnerability which is exploited in this method.
 Solution  :-
     The functions for booking a room and booking a suite seem a bit different.
on closer looking the function for booking a suite after decompilation using IDA pro.
    int book_suite()
{
  _DWORD *v0; // ebx@1
  char s; // [sp+1Ch] [bp-1Ch]@1
  int v3; // [sp+2Ch] [bp-Ch]@1

  v3 = *MK_FP(__GS__, 20);
  suite = malloc(264u);
  printf("Name: ");
  fflush(stdout);
  fgets(suite + 4, 256, stdin);
  *suite = print_name;
  printf("Suite number: ");
  fflush(stdout);
  fgets(&s, 16, stdin);
  v0 = suite;
  v0[65] = atoi(&s);
  puts("Booked a suite!");
  fflush(stdout);
  return *MK_FP(__GS__, 20) ^ v3;
}     
 The size of the suite is declared to be 264 bytes , and the name of the person is stored from the fourth to the 260th byte. *suite which gives the first four bytes of suite since it is a 32bit program is used to store the address of the function print_name. The Suite number is converted into an integer and stored in the last four bytes of the suite object. On successfully creating the object the function prints "Booked a suite!".

On examining the book_room function.
               int book_room()
{
  int *v0; // ebx@1
  char s; // [sp+1Ch] [bp-1Ch]@1
  int v3; // [sp+2Ch] [bp-Ch]@1

  v3 = *MK_FP(__GS__, 20);
  room = malloc(260u);
  printf("Name: ");
  fflush(stdout);
  fgets(room + 4, 256, stdin);
  printf("Room number: ");
  fflush(stdout);
  fgets(&s, 16, stdin);
  v0 = room;
  *v0 = atoi(&s);
  puts("Booked a room!");
  fflush(stdout);
  return *MK_FP(__GS__, 20) ^ v3;
}
The room object is created using 260 bytes and the first four bytes is used to store the room number and the rest is used to store the name.

In the delete booking function we find the vulnerablity we need to exploit.
int delete_booking()
{
  int v1; // [sp+1Ch] [bp-Ch]@1

  v1 = *MK_FP(__GS__, 20);
  if ( suite || room )
  {
    if ( suite )
    {
      free(suite);
      puts("Suite booking deleted!");
      fflush(stdout);
    }
    if ( room )
    {
      free(room);
      puts("Room booking deleted!");
      fflush(stdout);
    }
  }
  else
  {
    printf("No booking found!");
    fflush(stdout);  }
  return *MK_FP(__GS__, 20) ^ v1;
}   
After the free() the pointer isn't deleted which means we found our vulnerability .
So we know the location where the suite and room objects are kept. This is used to get the flag

On analysing the print booking function one can see that the first four bytes of the suite object which is suppossed to contain the address of the print name is being excecuted. This is the place where we need to have the adress of the flag function so that it gets excecuted.

int print_booking()
{
int v1; // [sp+1Ch] [bp-Ch]@1

v1 = *MK_FP(__GS__, 20);
if ( suite || room )
{
if ( suite )
{
(*suite)(suite + 4);
printf("Rooms number: %u\n", *(suite + 65));
fflush(stdout);
}
if ( room )
{
printf("Name: %s", room + 4);
printf("Rooms number: %u\n", *room);
fflush(stdout);
}
}
else
{
printf("No booking found!");
fflush(stdout);
}
return *MK_FP(__GS__, 20) ^ v1;
}

The only object which takes a input as the first five bytes is the room object there fore we need to excecute the suite statement while having a room object.

Steps to do to obtain the solution:
                                           book a suite providing theneccessary details and then delete it so that we will obtain the pointer to the location of the objects . Now proceed to book a room such that the room no which is the first four bytes will contain the address of the flag function. Now when you excecute the print booking function you excecute the flag function because now the print functon thinks that the object is a suite since the pointer points to the same location and the first four bytes get executed .

No comments:

Post a Comment