直接参数访问不起作用,在 C 中使用 printf
我正在做一些计算机安全研究,我正在尝试了解字符串格式漏洞。我正在运行一个包含以下代码的程序:
char buf[1<<5];
strncpy(buf, data, sizeof(buf));
buf[sizeof(buf)-1]='\0';
fprintf(stderr, buf);
当我向程序提供参数“%08x.%08x.%08x.%08x.%08x”(它被读入“data”变量)时,我得到输出: 00000020.b7fd7560.08048b09.00000019.78383025
我知道每个十六进制数字都会从堆栈中弹出,而“78383025”来自缓冲区本身。因此,在到达缓冲区开头之前,我必须弹出 4 个字(16 个字节)。
当我给出参数 `perl -e 'print "\x2a\xf9\xff\xbf%08x.%08x.%08x.%08x_%s_";'`
时,%s 部分打印位于内存地址 0xbffff92a 的字符串。
现在,我想使用直接参数访问来完成此操作。如果我向程序提供参数 `perl -e 'print "\x2a\xf9\xff\xbf%16$s";'`
,我应该期望程序执行与上面相同的操作。但程序打印的只是缓冲区开头的四个字符。那么,什么给了???我是否使用了错误的 DPA 语法??? 顺便说一下,我使用的是 Ubuntu 9.04,32 位。
这是一些可编译的代码,但不能保证产生相同的结果:
#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;
}
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 'print "\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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
%16$s
引用格式字符串后的第 16 个参数,并告诉printf
将其解释为char*
并显示它作为字符串。您似乎使用它作为在获取字符串之前跳过 16 个字节的方法,但这并不完全相同。
由于您想要第 5 个参数,请尝试更像此格式字符串的内容:
由于您使用
perl -e 'print "...";'
来传递数据,因此您必须转义$
字符。 IE。 :%16$s
refers to the 16-th argument after the format string, and tellsprintf
to interpret it as achar*
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 :
Since you're using
perl -e 'print "...";'
to pass the data, you will have to escape the$
character. Ie. :