#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 void func(int key){
     char overflowme[32];
     printf("overflow me : ");
     gets(overflowme);   // smash me!
     if(key == 0xcafebabe){
         system("/bin/sh");
     }
     else{
         printf("Nah..\\n");
     }
 }
 int main(int argc, char* argv[]){
     func(0xdeadbeef);
     return 0;
 }

The strategy here is easy, overwite the char overflowme with 32 bytes. and then put 0xcafebabe to replace the key value.

Key Point: because the gets will not validate how many bytes we put in there. So it will keep writing to the stack until it receives a terminator byte. and it gives us the chance to overwrite the entire stack.

here is the stack flow.

  1. Initialize the stack frame.

  2. push parameter 0xdeadbeef onto the stack.

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/090eaecb-2394-4663-9cb5-d2de0543d64b/Untitled.png

  3. and then enter func prolog.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7c767272-3c75-4de1-b694-d97c20e20dd0/Untitled.png

  1. now we go to where the 0xcafebabe is being cmp. Proves of that now

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/188b5020-88e7-4f03-a023-02326104f434/Untitled.png

  1. the value stored at $EBP+8 is being compared

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fad3e50d-bf36-46f0-8d30-5b7c59cf51d4/Untitled.png

Game plan: change 0xdeadbeef to 0xcafebabe .

well, here is my way of approaching this.

I simply dump all the data between gets to the $EBP + 8 . so we can calculate how many bytes we need to write to overwrite the [$EBP + 8].

  1. Set a break point at *0x56555654
  2. Input some random A into the overflowme .

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d63bc2fb-51a9-4ad3-bd48-e02ff7f3de17/Untitled.png

  1. And we have got it somewhere

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ee5ab54e-35ad-4bc6-8372-f476adbf8ecb/Untitled.png