# Plaid Party Planning III

Full warning, I solved this using the unintended / cheesy solution. With that let's take a look at the binary:

```
$    file pppiii-b73804b431586f8ecd4a0e8c0daf3ba6
pppiii-b73804b431586f8ecd4a0e8c0daf3ba6: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=8190b786e8260d7cb6e6d183a1f9f182a96f86d6, stripped
$    ./pppiii-b73804b431586f8ecd4a0e8c0daf3ba6
Alphabetical it is, I guess.
Simulating the dinner...

cai: Thank you guys all for helping out. Great job on another Plaid CTF well done!
strikeskids: I got someone to figure out our seating arrangement for us. Hopefully you're
    seated near to dishes you like.
zwad3: Guys, can you please be careful to not get any gluten in the food?
zwad3: *grabs the basmati rice*
strikeskids: *grabs the samosas*
awesie: *grabs the garlic naan*
susie: *grabs the basmati rice*
tylerni7: *grabs the matar methi malai*
jarsp: *grabs the plain naan*
ubuntor: I've saved some of my best ones for tonight!
ubuntor: *grabs the kashmiri naan*
cai: *grabs the samosas*
waituck: *grabs the samosas*
erye: *grabs the mango lassi*
ricky: This looks delicious!
ricky: *grabs the samosa chaat*
strikeskids: *grabs the mango lassi*
zwad3: *grabs the dal makhani*
waituck: *puts the samosas back*
zaratec: *grabs the samosas*
jarsp: *puts the plain naan back*
ricky: *grabs the chaas*
panda: *grabs the plain naan*
strikeskids: *puts the mango lassi back*
zwad3: *grabs the mango lassi*
ricky: *puts the samosa chaat back*
jarsp: *grabs the pakoras*
zwad3: *puts the basmati rice back*
strikeskids: *puts the samosas back*
awesie: *grabs the basmati rice*
jarsp: *puts the pakoras back*
Aborted (core dumped)
```

So we are dealing with a 64 bit binary, that crashes when we run it.

### Reversing

Looking through the list of functions (or checking references to functions and strings) we find this function which appears to start the parts of this binary that we are interesting in:

```
undefined8 FUN_00105948(int arg_count,long param_2)

{
  char cVar1;
  int intCpy;
  int first_arg;
  int i;
  int j;
  int k;
  int current_placement;
 
  setup(&x,&y);
  first_arg = 1;
  if (arg_count == 1) {
    puts("Alphabetical it is, I guess.");
    i = 0;
    while (i < 0xf) {
      *(int *)(&placement + (long)i * 0x20) = i;
      i = i + 1;
    }
  }
  else {
    if (arg_count != 0x11) {
                    /* WARNING: Subroutine does not return */
      abort();
    }
    first_arg = atoi(*(char **)(param_2 + 8));
    j = 0;
    while (j < 0xf) {
      intCpy = atoi(*(char **)(param_2 + ((long)j + 2) * 8));
      *(int *)(&placement + (long)j * 0x20) = intCpy + -1;
      current_placement = *(int *)(&placement + (long)j * 0x20);
      if ((current_placement < 0) || (0xe < current_placement)) {
                    /* WARNING: Subroutine does not return */
        abort();
      }
      k = 0;
      while (k < j) {
        if (current_placement == *(int *)(&placement + (long)k * 0x20)) {
                    /* WARNING: Subroutine does not return */
          abort();
        }
        k = k + 1;
      }
      j = j + 1;
    }
  }
  if (first_arg == 1) {
    puts("Simulating the dinner...\n");
    simulatingDinner(&x,&y);
  }
  else {
    puts("Checking the dinner...\n");
    if (first_arg != 2) {
                    /* WARNING: Subroutine does not return */
      abort();
    }
    cVar1 = checkingDinner(&x,&y);
    if (cVar1 != '\x01') {
      printf("Your dinner arrangement was unacceptable. We might never finish :(");
      return 1;
    }
  }
  return 0;
}
```

Looking at this, we can see that it takes in input via arguments. Depending on the arguments it will either fill the bss section `placement` (at offset `0x2086b0`) with certain values, or exit with `abort`. If we input no arguments, then it will fill in `placament` with values `0-14` in ascending order. If we input `16` arguments (excluding the file name) it will take the first argument and save it in the `first_arg` variable. The last `15` arguments are then saved in the `placement` array (assuming that the arguments are between `0-14` and not repeated, if so the program aborts). Also if we don't either give the program `15` or no arguments (excluding file name) the program aborts.

Also with the setup function, we see that it sets `x` to be a pointer to various strings and function addresses, and sets `y` to be equal to a pointer to various strings and integers. Essentially we are giving the places for people to sit, ranging from `0-14`.

Then it decides to either simulate or check the dinner. This is based upon the value `first_arg` (initialized to `1`). If it is `1` then it simulates it, `2` for checking. If it is a value other than those two then the program aborts. At the moment the `simulatingDinner` function is of more interest to use because we can see that the flag is printed in that function:

```
  customPrint(&local_c8,"It\'s a flag!");
  FUN_00101113(&local_c8,5);
  __ptr = (void *)genFlag(lParm1);
  customPrint(lParm1 + 0x100,"Let me take a look. It seems to say\n\tPCTF{%s}.",__ptr,lParm1 + 0x100
             );
  free(__ptr);
  customPrint(lParm1 + 0x100,"Hopefully that\'s useful to someone.");
```

However before that happens, we see that this code runs around `0x1829`:

```
  while (i < 0xf) {
    abortCheck0 = pthread_create(th + (long)i,(pthread_attr_t *)0x0,FUN_001014f8,
                                 (void *)((long)i * 0x20 + lParm1));
    if (abortCheck0 != 0) {
                    /* WARNING: Subroutine does not return */
      abort();
    }
    i = i + 1;
  }
  j = 0;
  while (j < 0xf) {
    abortCheck1 = pthread_join(th[(long)j],(void **)0x0);
    if (abortCheck1 != 0) {
                    /* WARNING: Subroutine does not return */
      abort();
    }
    j = j + 1;
  }
```

What that block does is it takes the functions stored in `x`, and executes them in different threads. In one of those functions somewhere, the program is aborting. After a bit of reversing we find this section of code at `0x3288` in the function at `0x314e`:

```
  pcVar4 = strstr(*(char **)(lVar3 + 8),"paneer");
  if (pcVar4 != (char *)0x0) {
                    /* WARNING: Subroutine does not return */
    abort();
```

Depending on the order of spots we give, a different string gets compared here. To get past this, I just changed around the spots a bit until I got past that check. Then I ran into another problem where due to the `pthread_join(th[(long)j],(void **)0x0)` calls, the code hangs to the point where we won't get the flag:

```
$    ./pppiii-b73804b431586f8ecd4a0e8c0daf3ba6 1 12 13 14 15 1 2 3 4 5 6 7 8 9 10 11
Simulating the dinner...

cai: Thank you guys all for helping out. Great job on another Plaid CTF well done!
strikeskids: I got someone to figure out our seating arrangement for us. Hopefully you're
    seated near to dishes you like.
strikeskids: *grabs the pakoras*
zwad3: Guys, can you p