【问题标题】:Why this code is exploitable?为什么这段代码是可利用的?
【发布时间】:2012-04-09 21:11:18
【问题描述】:

为什么这段代码不安全?

#include <stdio.h>
int main( int argc, char *argv[] )
    {
       printf(argv[1]);
       printf("\n");
       return 0;
    }

【问题讨论】:

标签: c security


【解决方案1】:

printf 将处理它的第一个参数,寻找像 %d%s 这样的东西。

根据这些值,它将从堆栈中获取更多数据并将其打印出来。

所以如果有人调用你的程序:

a.out "%d %d %d %d %d %d %d %d %d %d %d %d"

他们可以查看您计算机调用堆栈的一部分。

如果他们对格式说明符更有创意,也许他们可以转储一些重要的东西,比如信用卡号或密码。

【讨论】:

  • 使用%n,您甚至可以在内存中的任何位置写入
  • 是的,这是我的想法,但它只打印 %,因为它打印 argv[1],就是这样..
  • 这个比较良性; %n 可能会导致主动损坏(例如修改控制流)。
  • @0x90, @ouah:你不会单独使用%n,而是使用"%500d%1024x%10000x%40000s%n"之类的东西——让printf()吃掉堆栈上的参数直到位置它遇到一个“可用”指针,并使用格式字段宽度调整器控制写入的数据量。这样,您将获得一个已知值,printf() 将放入由 arg 指定的指向 %n 的指针中。
  • @0x90:我给你写了一个小例子,看我的回答。
【解决方案2】:

考虑printf 的第一个参数控制什么(提示:printf 不只是读取其输入参数)。

【讨论】:

    【解决方案3】:

    看看什么是格式字符串漏洞:

    http://en.wikipedia.org/wiki/Uncontrolled_format_string

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        既然发帖人举了一个例子,%n 做了什么:

        printf 格式字符串可以更改内存的方式是使用%n 选项;可以通过“明智地”使用格式宽度说明符来获得要写入的特定值。作为测试:

        #include <stdio.h>
        
        int main(int argc, char **argv)
        {
            int *q = (int *)argv[0];
            printf("%1$300000d%5$n",
                123,         // %1 - 1st param (formatted as '300000d')
                0,           // %2 - 2nd param (unused)
                0,           // %3 - 3rd param (unused)
                0,           // %4 - 4th param (unused)
                argv[0]);    // %5 - 5th param (written to via 'n')
        
            printf("\nNow *q == %d\n", *q);
        
            return 0;
        }
        

        如果您运行它并查看输出的最后一行,它将打印 Now *q == 300000(在 Linux 上测试)。

        我在这里为printf() 使用了相当未知的位置格式语法 (%$),以便展示如何跳过参数到选择要修改的,而不需要使用任何“无趣”的。

        我将把它留给读者实验来弄清楚printf() 将什么视为像printf(argv[1]) 这样的调用的“参数”。答案取决于calling conventions(或相关的,您系统的ABI),并且对于32/64位Windows/Linux/MacOSX等不同。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-21
          • 2011-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多