快速业务通道

缓冲区溢出还是问题吗?C++/CLI安全编码

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

C++/CLI是对C++的一个扩展,其对所有类型,包括标准C++类,都添加了对属性、事件、垃圾回收、及泛型的支持。

Visual C++ 2005扩展了对使用C++/CLI(通用语言基础结构)开发运行于带有垃圾回收的虚拟机上的控件及应用程序的支持,而C++/CLI是对C++编程语言的一个扩展,其对所有类型,包括标准C++类,都添加了如属性、事件、垃圾回收、及泛型等特性。

Visual C++ 2005支持.NET Framework通用语言运行时库(CLR),其是垃圾回收虚拟机Microsoft的实现。Visual C++ 2005对.NET编程的C++语法支持是从Visual C++ .NET 2003中引入的托管扩展C++演化而来的,托管扩展C++仍然被支持,但在倾向于新语法的情况下已不赞成使用。Visual C++ 2005同时也对本地编程添加了新的特性,包括64位处理器架构支持,及提高了安全性的新库函数。

在本文中,将主要讲解在以最小代价把现有老系统移植到使用CLR的新环境中来时,所要面临的问题,目的是为了确定这些程序是否仍然易受折磨C/C++程序多年的缓冲区溢出的影响。

例1会要求用户输入用户名及密码,除去用户名之外,程序只接受"NCC-1701"为有效的密码。如果用户输入了错误的密码,程序将退出。(这个程序只是作为C++/CLI代码的漏洞测试,而不是演示如何处理密码。) 例1:

1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <windows.h>
4. char buff[1028];
5. struct user {
6. char *name;
7. size_t len;
8. int uid;
9. };
10. bool checkpassword() {
11.  char password[10];
12.  puts("Enter 8 character password:");
13.  gets(password);
14.  if (strcmp(password, "NCC-1701") == 0) {
15.   return true;
16.  }
17.  else {
18.   return false;
19.  }
20. }
21. int main(int argc, char *argv[]) {
22.  struct user *userP = (struct user *)0xcdcdcdcd;
23.  size_t userNameLen = 0xdeadbeef;
24.  userP = (struct user *)malloc(sizeof(user));
25.  puts("Enter user name:");
26.  gets(buff);
27.  if (!checkpassword()) {
28.   userNameLen = strlen(buff) + 1;
29.   userP->len = userNameLen;
30.   userP->name = (char *)malloc(userNameLen);
31.   strcpy(userP->name, buff); // log failed login attempt
32.   exit(-1);
33.  }
34. }

程序从21行的main()开始执行,在25及26行使用了一对puts()和gets()来提示输入用户名,导致了一个从标准输入到缓冲区字符数组(声明在第4行)的不受控制的字符串复制,程序中的这两处地方都有可能会导致一个缓冲区溢出的漏洞。checkpassword()函数由main()中的27行调用,并在12及13行中提示用户输入密码,这也是使用了一对puts()/gets()。对gets()的第二次调用也会导致一个定义在堆栈上的密码字符数组缓冲区溢出。

程序使用Microsoft Visual C++ 2005编译,并关闭了缓冲区安全检查选项(/GS-),打开了托管扩展(/clr)。默认情况下,缓冲区安全检查是打开的,把它关闭并不是个好做法(如本例所示),而/clr选项可允许由托管及非托管代码生成混合的程序集。

程序生成过程中产生的几个警告信息都可以忽略掉,例如,"warning C4996: ''gets'' was declared deprecated"和"warning C4996: ''strcpy'' was declared deprecated",编译器推荐使用gets_s()来代替gets(),用strcpy_s()来代替strcpy()。如果完全使用这些替代函数,那么就可消除缓冲区溢出潜在的可能性。然而,这些只是警告信息,可以忽略甚至关闭,忽略这些警告信息是符合用最小的代价移植现有老系统这个前提的。

当使用托管扩展时

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号