我的一亩三分地 我就喜欢!
13fen  设为主页
 收藏本站
 
当前位置: > 一亩三分地:首页 > 网络学院 > 网络编程 > ASP专区 > Asp客户端/系统 > 格式化字符串攻击 《转》
热门文章排行
热门文章排行 手推车”功能的实现(10-07)
八大法则防范ASP网站漏洞(10-23)
ASP教程十一、调试ASP脚本(10-23)
在JSP中访问数据库大全(10-23)
虚机服务中常见Asp.Net低级错误一览(03-21)
精采文章排行
精采文章排行 ASP.NET实现抓取网页中的链接(11-15)
ASP连接数据库的11种方法(11-10)
如何动态创建网页的RSS内容摘要(11-10)
ASP网站漏洞及入侵防范方法(11-10)
ASP自定义函数:对字符串正则替换(11-10)
技术专题推荐
网管论坛交流
 

格式化字符串攻击 《转》 

作者:佚名   来源:一亩三分地   点击:   日期:2007-03-23

翻译:   xuzq@chinasafer.com

内容:
        介绍
        什么是格式化字符串攻击?
        Printf-学校忘记教给你的东西
        简单的例子
        来格式化吧!(Format Me!)
        X MARKS THE SPOT(X是本文示例程序中我们试图重写的一个变量,这句我不知
道如何翻译)
        怎么着(So what)?

摘要

本文讨论格式化字符串漏洞的成因和含义,并给出实际的例子来解释原理。

介绍

我知道在某些时候对于你我和我们大家而言,下面这种情况总会发生。在一个时下流行的
晚餐会上,夹杂在同事们大呼小叫的声音里,你听到了"格式化字符串攻击"这只言片语。
"格式化字符串攻击?什么是格式化字符串攻击?"你心说。由于害怕在同事们面前显露出
自己的无知,你决定停
止不自然的微笑,而频频点头以示自己对这玩艺了如指掌。如果一切顺利,大家会共饮鸡
尾酒,谈话仍将继续,但是没人明白这究竟是怎么回事。现在不用再害怕什么了,本文会
提供你想知道而又不好意思问的所有内容。

什么是格式化字符串攻击?

格式化字符串漏洞同其他许多安全漏洞一样是由于程序员的懒惰造成的。当你正在阅读本
文的时候,也许有个程序员正在编写代码,他的任务是:打印输出一个字符串或者把这个
串拷贝到某缓冲区内。他可以写出如下的代码:

    printf("%s", str);

但是为了节约时间和提高效率,并在源码中少输入6个字节,他会这样写:

    printf(str);

为什么不呢?干嘛要和多余的printf参数打交道,干嘛要花时间分解那些愚蠢的格式?
printf的第一个参数无论如何都会输出的!程序员在不知不觉中打开了一个安全漏洞,可
以让攻击者控制程序的执行,这就是不能偷懒的原因所在。

为什么程序员写的是错误的呢?他传入了一个他想要逐字打印的字符串。实际上该字符串
被printf函数解释为一个格式化字符串(format  
string)。函数在其中寻找特殊的格式字符比如"%d"。如果碰到格式字符,一个变量的参
数值就从堆栈中取出。很明显,攻击者至少可以通过打印出堆栈中的这些值来偷看程序的
内存。但是有些事情就不那么明显了,这个简单的错误允许向运行中程序的内存里写入任
意值。

Printf-学校忘记教给你的东西

在说明如何为了自己的目的滥用printf之前,我们应该深入领会printf提供的特性。假定
读者以前用过printf函数并且知道普通的格式化特性,比如如何打印整型和字符串,如何
指定最大和最小字符串宽度等。除了这些普通的特性之外,还有一些深奥和鲜为人知的特
性。在这些特性当中,
下面介绍的对我们比较有用:
        *在格式化字符串中任何位置都可以得到输出字符的个数。当在格式化字符串中
碰到"%n"的时候,在%n域之前输出的字符个数会保存到下一个参数里。例如,为了获取在
两个格式化的数字之间空间的偏量:

      int pos, x = 235, y = 93;
      printf("%d %n%d\n", x, &pos, y);
      printf("The offset was %d\n", pos);

* %n格式返回应该被输出的字符数目,而不是实际输出的字符数目。当把一个字符串格式
化输出到一个定长缓冲区内时,输出字符串可能被截短。不考虑截短的影响,%n格式表示
如果不被截短的偏量值(输出字符数目)。为了说明这一点,下面的代码会输出100而不
是20:

      char buf[20];
      int pos, x = 0;
      snprintf(buf, sizeof buf, "%.100d%n", x, &pos);
      printf("position: %d\n", pos);

简单的例子

除了讨论抽象和复杂的理论,我们将会使用一个具体的例子来说明我们刚才讨论的原理。
下面这个简单的程序能满足这个要求:
    /*
     * fmtme.c
     *       Format a value into a fixed-size buffer
     */

    #include <stdio.h>

    int
    main(int argc, char **argv)
    {
        char buf[100];
        int x;
        if(argc != 2)
            exit(1);
        x = 1;
        snprintf(buf, sizeof buf, argv[1]);
        buf[sizeof buf - 1] = 0;
        printf("buffer (%d): %s\n", strlen(buf), buf);
        printf("x is %d/%#x (@ %p)\n", x, x, &x);
        return 0;
    }

对这个程序有几点说明:第一,目的很简单:将一个通过命令行传递值格式化输出到一个
定长的缓冲区里。并确保缓冲区的大小限制不被突破。在缓冲区格式化后,把它输出。除
了把参数格式化,还设置了一个整型值随后输出。这个变量是随后我们攻击的目标。现在
值得我们注意的是这个
值应该始终为1。

本文中所有的例子都是在x86 BSD/OS  
4.1机器上完成。如果你到莫桑比克执行任务超过20年时间可能会对x86不熟悉,这是一个
little-endian机器。这决定在例子中多精度数字的表示方法。在这里使用的具体数值会
因为系统的差异而不同,这些差异表现在不同体系结构、操作系统、环境甚至是命令行长
度。经过简单调整,这
些例子可以在其他x86平台上工作。通过努力也可以在其他体系结构的平台上工作。

来格式化吧!(Format Me!)

现在是我们戴上黑帽子开始以攻击者方式思考问题的时候了。我们现在手头有一个测试程
序。知道这个程序有一个漏洞并且了解程序员是在哪里犯错误的(直接把用户输入的命令
行参数作为snprintf的格式化参数)。我们还拥有关于printf函数深入的知识,知道如何
运用这些知识。让我们
开始修补我们的程序吧。
从简单的开始,我们通过简单的参数调用程序。看这儿:

    % ./fmtme "hello world"
    buffer (11): hello world
x is 1/0x1 (@ 0x804745c)

现在这儿还没有什么特别的事情发生。程序把我们输入的字符串格式化输出到缓冲区里,
然后打印出它的长度和数值。程序还告诉我们变量x的值是1(以十进制和十六进制分别显
示),x的存储地址是0x804745c。
接下来我们试着使用一些格式指令。在下面的例子中我们打印出在格式化字符串之上栈堆
中的整型数值:

    % ./fmtme "%x %x %x %x"
    buffer (15): 1 f31 1031 3133
    x is 1/0x1 (@ 0x804745c)

对这个程序的快速分析可以揭示在调用snprintf函数时程序堆栈的规划:

    Address  Contents       Description
    fp+8     Buffer         pointer 4-byte address
    fp+12    Buffer         length 4-byte integer
    fp+16    Format         string 4-byte address
    fp+20    Variable x     4-byte integer
fp+24    Variable buf   100 characters

(补充:我参考了"缓冲区溢出机理分析"一文,才看明白上面的内容。简单介绍一下:当
程序中发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保存指令寄存器
(IP)中的内容做为返回地址(RET);第三个放入堆栈的是基址寄存器(FP);然后把当前的


文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【论坛讨论

   相关文章:
·ASP中巧用Response属性 ·第六课:ASP脚本循环语句
·在 Web 页上使用条件数值格式 ·连接数据库查询手册(不仅仅适用于asp)
·警惕"给你的FileSystemObject对象加把锁" ·用ASP做全文检索

   文章评论:(条)
  
 请留名: 匿名评论   点击查看所有评论 网管论坛
 

  责任编辑:一分  声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。