Writeup: Stackulator

NAME: stackulator
CATEGORY: pwn
POINTS: 200

First pwn of the season! And the second pwn of my life!

Welcome to my first calculator!
 
What is your name?:

Aw man. What a polite calculator. What a shame we have to pummel it with malicious input.

undefined8 main(void)

{
  int iVar1;
  undefined8 uVar2;
  long lVar3;
  undefined8 *puVar4;
  long in_FS_OFFSET;
  undefined8 local_88 [8];
  int local_48;
  undefined8 local_44;
  undefined8 local_3c;
  undefined8 local_30;
  undefined8 local_28;
  char local_20 [16];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  puVar4 = local_88;
  for (lVar3 = 0xe; lVar3 != 0; lVar3 = lVar3 + -1) {
    *puVar4 = 0;
    puVar4 = puVar4 + 1;
  }
  local_44 = 0x6c2e636c61632f2e;
  local_3c = 0x676f;
  puts("Welcome to my first calculator!\n\nWhat is your name?:");
  fgets((char *)local_88,99,stdin); // Reads 99 bytes to local_88
  printf("\nHello %s",local_88);
  if (local_48 == 1) { // This seems important
    debug_menu(&local_44);
  }
  else {
    ...

OK, so we have an opportunity to write past the 64 bytes that are allocated to local_88. The following variable is local_48, which needs to be set to 1 to enter the debug menu. So if we send 64 bytes of gibberish, we can overwrite local_48. Appending 1 as a 4-byte little-endian integer gets us to the debug menu:

Select an option:
1) Receive a compliment
2) View log file
3) Get a random YouTube link
4) Show me an ASCII bee

This now gives us an option to read a file. More importantly, however, we can get a compliment:

You are good at making secure calculators

Goodbye!

Wrong!

void debug_menu(char *param_1)

{
...
      if (local_40d == '2') {
        puts("\nLog contents:");
        local_40c = open(param_1,0);
        read(local_40c,local_408,1000);
        puts(local_408);
        goto code_r0x00101396;
      }
...
}

This reads a file that’s passed in by param_1. Which conveniently is just after the stuff you’ve overwritten. Now it is time to spend 20 minutes guessing the name of the flag. It’s not flag.txt or calc.log. 2 minutes after the challenge expires we will learn that the correct file is merely titled flag. I don’t know why I went so long without trying that. Appending that will get us the flag, so all is well!

Craft the exploit with a final payload of 64 bytes, the integer 1, and then “flag”, being sure to add a null terminator. Submitting this prints out the contents of a file named “flag”!

Leave a Reply

Your email address will not be published. Required fields are marked *