I am reading about and trying to learn format string vulnerabilities. I have a vulnerable function and I understand the gist of what I have to do with my format string.
Basically, this is what I want to do. Pass in my format string which contains some shellcode as part of it. I also need to format my string so that the return address of the vulnerable function gets replaced so that it points to my shellcode on the stack. Hence, when the function returns, it will jump to my shellcode on the stack and open a shell.
Currently, I am at the point where I can see my shellcode on the stack, and I am able to write to the return address to change it. Problem is, I am using %n as my way of overwriting the return address and am not sure how to get %n to overwrite with a specific value. Of course, %n simply prints the number of bytes written so far to the specified address on the stack. I've read a couple of things on how you can manipulate %n to write the exact address/value you want, but I am lost on how to do that.
Can anyone shed some light?
Edit: I've tried padding my format string with things such as '%500d" and "%.500d" as well as "%nu" for some n values. (I've tried much smaller values as well) but that just brings about a segmentation fault.
To clear up some confusion, here's a quick example I wrote in response to a comment:
Okay, I'll try to be a little more clear. I have a vulnerable program. The vulnerable point is "printf(input);". I want to exploit this by passing in a format string. Now for example, I have a format string
"\x0c\xde\xbf\xff%08x.%08x.%08x.%08x.%08x.%08x.%n"
This format string, when passed into the vulnerable function, will overwrite the memory address of 0xffbfde0c with the number of bytes written. I am looking to find out how I can modify that format string so that I can make %n overwrite with a specific value by somehow padding the number of bytes written before the %n.
The only way to get %n
to write a number is to make printf
print this number of characters. To get to any pointer's value, you'll need to print many many bytes.
The easiest way is something like %999999s
.
Also, it may be easier to try to direct the return value to some function (AKA "return to libc"), because code typically resides in relatively low addresses.