I’m going through tutorials on formatstring vulnerabilities to learn how to code more securely. The program I’ve written so far is as follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char text[100];
strcpy(text, argv[1]);
printf(text);
}
I’m running it like this:
>>> ./foo $(ruby -e 'print "AAAA" + "%08x."*9 + "%x"')
AAAAffe466f4.00000001.f763b1c9.ffe458df.ffe458de.00000000.ffe459c4.ffe45964.00000000.41414141
I can see the “41414141” at the end, which is the AAAA at the beginning of the string. However, when I use “%s” instead like so:
>>> ./foo $(ruby -e 'print "AAAA" + "%08x."*9 + "%s"')
I get a segfault. Can anyone point me in the right direction?
The thing is that at this point, you reach raw AAAA on the stack; however, the
%sspecifier expects a pointer to a string, i.e. the address of your AAAA, instead. There is no format string specifier for what you want to do as in the normal course of execution you wouldn’t have a string pasted directly as printf()‘s parameter; one idea would be%c%c%c%cto at least print the data as characters instead of hex values, but that will not work either as the smallest size of a parameter in C is an int and even the%cspecifier works with int-sized parameter memory region.