用户名: 密码: 免费注册 忘记密码? 网站地图 | 加入收藏 | 设为首页
首页 | 新闻 | 工具 | 系统 | 办公 | 聊天 | 多媒体 | 网页 | 运营 | 平面 | 欣赏 | 数据库 | 程序 | 服务器 | 组网
网页 | 3dmax | Ghost | Windows Xp| Dreamweaver | photoshop | Flash | office | Alexa | Css | QQ | Asp | PHP | Jsp | Access
Flash MX 2004入门 | 网站推广策略 | CorelDRAW入门 | ASP学习 | 网站建设大师功 | Word入门
  iTbulo.com > 学院 > 软件新闻 > 病毒安全 > 文章正文
利用格式化字符串漏洞对系统发起攻击
iTbulo.COM 2007-3-9 天极()

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

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

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。

[1] [2] 下一页

文章搜索
相关资讯
相关文章 相关下载
安全攻略 探秘全新一代安全接入技术
赛门铁克发布第11期互联网安全威胁报告
宁可错杀,不可放过!OneCare删除用户邮件
防止系统崩溃!Apple修复无线安全漏洞
危险无处不在 账号防盗防骗的小经验
焦点信息