How to exploit variable's value

You are right that the buffer cannot overflow the flag because of the bounds check. Fgets also includes the null character in its bound check.
http://www.cplusplus.com/reference/cstdio/fgets/

However, there is a string format vulnerability here:

printf(buf);

The user-controlled variable buf is used in a printf statement, causing a format string vulnerability.

https://www.exploit-db.com/docs/28476.pdf

Using a combination of %x %n you can overwrite the flag with "1337." %x is used to pop values off the stack, and %n is used to write the number of characters into that address. The "1337u" expands the number of characters so you can write the correct value. For example, if the memory location of flag is "0xffffff80"

$(python -c 'print "\x80\xff\xff\xff"+"%x%1337u%n"')

This will write a number that is greater than 1337 because of the other stuff before the "1337u," so you just subtract that number by the amount you go overboard, and you'll have the right number. Or, if you want to do some math, the value of "u" is: “The byte to be written” – “the outputted byte” + “the width of the %x specified just before the %n”


flag is not local to any function and global in scope. Therefore, it is not located on the runtime stack. Either patch the binary or take advantage of the fact that input to buf is not sanitized and that buf an argument to printf (manipulate the value of the format string argument such that 1337 is written to address 0x601084).


flag is a statically allocated variable whose value will be stored in the data or bss segment of the process rather than in the runtime stack. If you have access to the binary you can simply patch it such that the value 1337 is stored at address 0x601084, which should be in the .data or .bss section. Since here global variable flag is initialized to 0, it will likely be in the .bss section of the binary and the bss segment of the process (this would not be the case if it was initialized to some other value).

Even if one did not know how the compiler allocates memory for variables based on their location in the source code, one could still determine that flag is not stored on the runtime stack by comparing its address with that of the stack pointer %rsp: location 0x601084 is far lower in memory than 0x7fffffffdaf0.

Tags:

C

X86

Exploit