# Boston Key Party 2016 Cookbook

This exploit is based off of this writeup with multiple parts (one of the best writeups I ever saw):
https://www.youtube.com/watch?v=f1wp6wza8ZI
https://www.youtube.com/watch?v=dnHuZLySS6g
https://www.youtube.com/watch?v=PISoSH8KGVI

Let's take a look at the binary and libc file:

```
$    file cookbook
cookbook: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=2397d3d3c3b98131022ddd98f30e702bd4b88230, stripped
$    pwn checksec cookbook
[*] '/Hackery/pod/modules/house_of_power/bkp16_cookbook/cookbook'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
$ ./libc-2.24.so
GNU C Library (Ubuntu GLIBC 2.24-9ubuntu2.2) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0 20170406.
Available extensions:
  crypt add-on version 2.1 by Michael Glad and others
  GNU Libidn by Simon Josefsson
  Native POSIX Threads Library by Ulrich Drepper et al
  BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
$    ./cookbook
what's your name?
guyinatuxedo
+-----------------------------+
|          .--,--.            |
|          `.  ,.'            |
|           |___|             |
|           :o o:             |
|          _`~^~'             |
|        /'   ^   `\          |
| cooking manager pro v6.1... |
+-----------------------------+
====================
[l]ist ingredients
[r]ecipe book
[a]dd ingredient
[c]reate recipe
[e]xterminate ingredient
[d]elete recipe
[g]ive your cookbook a name!
[R]emove cookbook name
[q]uit
```

So we can see that we are given a `32` bit binary, we a Stack Canary and NX. We can also see that we are dealing with the libc version `2.24`.

## Reversing

This is going to be a fun one. Checking the references to strings that we see in the menu, we find the `menu` function:

```
void menu(void)

{
  char *ptr;
  size_t sVar1;
  int in_GS_OFFSET;
  char input [10];
  int canary;
 
  canary = *(int *)(in_GS_OFFSET + 0x14);
  puts("====================");
  puts("[l]ist ingredients");
  puts("[r]ecipe book");
  puts("[a]dd ingredient");
  puts("[c]reate recipe");
  puts("[e]xterminate ingredient");
  puts("[d]elete recipe");
  puts("[g]ive your cookbook a name!");
  puts("[R]emove cookbook name");
  puts("[q]uit");
  fgets(input,10,stdin);
  switch(input[0]) {
  case 'R':
    removeName();
    break;
  default:
    puts("UNKNOWN DIRECTIVE");
    break;
  case 'a':
    addIngredient();
    break;
  case 'c':
    createRecipe();
    break;
  case 'e':
    ptr = (char *)calloc(0x80,1);
    printf("which ingredient to exterminate? ");
    fgets(ptr,0x80,stdin);
    sVar1 = strcspn(ptr,"\n");
    ptr[sVar1] = '\0';
    FUN_080497f9(ptr);
    free(ptr);
    break;
  case 'g':
    nameCookbook();
    break;
  case 'l':
    listIngredients();
    break;
  case 'q':
    puts("goodbye, thanks for cooking with us!");
    if (canary != *(int *)(in_GS_OFFSET + 0x14)) {
                    /* WARNING: Subroutine does not return */
      __stack_chk_fail();
    }
    return;
  case 'r':
    recipeCookbook();
  }
}
```

Let's start going through this code and the functions it calls bit by bit:

```
void listIngredients(void)

{
  undefined4 *currentIngredient;
 
  currentIngredient = ingredients;
  while (currentIngredient != (undefined4 *)0x0) {
    puts("------");
    printIngredient(*currentIngredient);
    currentIngredient = (undefined4 *)currentIngredient[1];
    if (currentIngredient == (undefined4 *)0x0) {
      puts("------");
    }
  }
  return;
}
```

We can see here that iterate through and print all of our ingredients using the `printIngredient` function. We can also see that our ingredients are stored in the bss variable `ingredients` stored at `0x804d094`. We can see the structure of an ingredient thanks to the `printIngredient` function:

```

void printIngredient(undefined4 *param_1)

{
  printf("name: %s\n",param_1 + 2);
  printf("calories: %zd\n",*param_1);
  printf("price: %zd\n",param_1[1]);
  return;
}
```

So we can see here, that an ingredient is `12` bytes long. The first `4` bytes holds the calories, the second `4` bytes holds the prices, and the third `4` bytes holds the name. Next up we have:

```
void recipeCookbook(void)

{
  uint recipeCount;
  undefined4 currentRecipe;
  uint i;
 
  recipeCount = countDwordValues(&recipes);
  printf("%s\'s cookbook",cookbookName);
  i = 0;
  while (i < recipeCount) {
    currentRecipe = grabRecipe(&recipes,i);
    printRecipe(currentRecipe);
    i = i + 1;
  }
  return;
}
```

Like the `listIngredients` function, this prints the recipes, which are stored in the bss variable `recipes` at `0x804d08c`. Also we can see it prints the name of the cookbook, which is stored in the bss address `cookbookName` at `0x804d0ac`. Looking at the `printRecipe` function, we see what the structure of a recipe looks like:

```
void printRecipe(undefined4 *ingredient)

{
  uint ingredientCount;
  int iVar1;
  undefined4 cals;
  int in_GS_OFFSET;
  undefined4 ingredients;
  undefined4 ingredientQuantities;
  uint i;
  int canary;
  int canaryVal;
 
  canaryVal = *(int *)(in_GS_OFFSET + 0x14);
  ingredients = *ingredient;
  ingredientQuantities = ingredient[1];
  ingredientCount = countDwordValues(&ingredients);
  printf("[---%s---]\n",ingredient + 2);
  printf("recipe type: %s\n",ingredient[0x1f]);
  puts((char *)(ingredient + 0x23));
  i = 0;
  while (i < ingredientCount) {
    cals = grabRecipe(&ingredientQuantities,i);
    iVar1 = grabRecipe(&ingredients,i);
    printf("%zd - %s\n",cals,iVar1 + 8);
    i = i + 1;
  }
  cals = getCost(ingredient);
  printf("total cost : $%zu\n",cals);
  cals = getCals(ingredient);
  printf("total cals : %zu\n",cals);
  if (canaryVal != *(int *)(in_GS_OFFSET + 0x14)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}
```

From that (and some of the functions this called) we can tell that the structure of a recipe is this:

```
0x0:  ptr to linked list of ingredient counts
0x4:  ptr to linked list of ingredient quantities
0x8:  char array for recipe name
124:  char array to recipe type
140:  Char array for recipe instruction
```

Next up is `nameCookbook`:

```
void nameCookbook(void)

{
  ulong size;
  int in_GS_OFFSET;
  char inputLen [64];
  int canary;
  int canaryVal;
 
  canaryVal = *(int *)(in_GS_OFFSET + 0x14);
  printf("how long is the name of your cookbook? (hex because you\'re both a chef and a hacker!) : "
        );
  fgets(inputLen,0x40,stdin);
  size = strtoul(inputLen,(char **)0x0,0x10);
  name = (char *)malloc(size