由指针和数组带来的软件安全性缺陷

由指针和数组带来的软件安全性缺陷


2024年4月28日发(作者:)

由指针和数组带来的软件安全性缺陷 

吕金和 

(沈阳市电化教育馆,辽宁沈阳110032) 

摘要:随着软件规模的不断扩大,软件系统深入到社会的各个领域,软件安全性测试的需求也日益扩张。软件的安全性问题 

主要是由于语言和程序本身的缺陷带来的后遗症。指针和数组能够导致多种软件安全性缺陷,其中最有名的就是“缓存区的溢 

出”。详细介绍了由指针和数组能够引发的一些安全性缺陷模型,并探讨了为这些缺陷设计测试方案所遇到的问题及解决方法。 

关键词:软件测试;软件安全;指针 

Brought about by the Pointer and an Array of Software Security Flaws 

LV Jjn—he 

{Shenyang Audio—ViSual Educag/on, ̄.e/'VICS,Shenyang,Liaonlng IIO05Z, 

Abstract:With the continued expansion of software size,software systems deep into all areas of society,software,security,the ever-growing 

demand for testing.Software security issues mainly due to deficiencies in language and the process itself had serious consequences.Pointers and 

arrays can lead to a variety of software security flaws.ode of the most famous is the”buffer overflow.”This paper describes the pointer and 

the array can be triggered by a number of security flaws model,and discusses the design of test scenarios for these shortcomings encountered 

problems and solutions. 

Key words:Testing;Software Security;Pointer 

1软件测试与软件的安全性问题 

1.1什么是软件测试 

金融和银行领域。软件的安全性问题一方面由于语言本身 

存在的缺陷,另一方面是由于程序员的忽视或经验不足。 

软件测试就是发现软件中错误和缺陷的主要手段,在 

软件工程的过程中占有相当重要的地位。测试的目标是以 

最少的时间和人力系统找出软件中潜在的各种错误和缺陷。 

如果成功地进行了测试,就能够发现软件中的错误。同时 

能够证明软件的功能和性能与需求说明是否相符合。测试 

软件的安全性缺陷中,由于指针和数组带来的软件安■ 

全性缺陷模式种类非常繁多。这跟数组和指针天生的非安一 

全性有很大关系。后面的章节将深入讨论数组和指针带来 

的安全性缺陷模式以及其对软件测试带来的一些挑战。 

是为了证明程序有错,而不是证明程序无错误;一个好 2数组和指针 

的测试用例是在于它能发现至今未发现的错误;一个成功 程序设计中,为了处理方便,把具有相同类型的若干 

的测试是发现了至今未发现的错误的测试。 

软件测试根据是否运行被测软件来分,可分为静态测 

变量按有序的形式组织起来。这些按序排列的同类数据元 

素的集合称为数组。在C语言中,数组属于构造数据类型。 

试和动态测试。动态测试是指通过运行被测程序,检查运 

行结果与预期结果的差异,来检查软件的动态行为和运行 

静态测试是一种在不执行程序的情况下对程序行为进行分 

一个数组可以分解为多个数组元素,这些数组元素可以是 

基本数据类型或是构造类型。因此按数组元素的类型不同, 

等各种类别。 

结果的正确性,因此,动态测试只能发生在编码阶段以后。 数组又可分为数值数组、字符数组、指针数组、结构数组 

析的理论和技术。 指针,是一个无符号整数(unsigned int),它是一 

1.2软件的安全性问题 

软件安全性缺陷是指有意或无意引入到系统的,可能 

导致系统违背安全需求的不正确行为的程序和数据。 

随着计算机在全世界的日益普及,计算机软件系统已 

经深入到社会的各个领域,从视图桌面系统到手机嵌入式 

系统,从个人笔记本电脑到超市结算终端。随着人们对软 

个以当前系统寻址范围为取值范围的整数。32位系统下 

寻址能力(地址空间)是4G—byte(0"2 32-1)二进制表 

示长度为32bit(也就是4B)。具体来说,指针存的是另 

一个对象的地址。 

数组本身就是一个指针,指向数组的首地址。C/C++ 

程序中,指针和数组在不少地方可以相互替换着用。因此, 

件功能的要求越来越高,软件的复杂性线性增长,软件的 

安全性问题也越来越突出。特别是在安全性要求高的航空、 

数组可以带来指针能够导致的一切问题。由于数组有长度 

限制,还能带来其他一些问题。 

指针和数组的灵活性在于它能让程序员方便地对内存 

进行操作,当这种灵活性成为问题的所在,在一定程度上 

就限制了C/C++的发展。JAVA虽然不提供malloc和 

指针这些操作内存的机制,也不需要程序员自动释放申请 

的资源,但是依然保留了数组类型,仍然会导致一些跟内 

存有关的安全性缺陷的产生。内存错误是件麻烦的事情, 

编译器不能够自动发现这些错误,而且错误的发生具有偶 

然性,也许调试好的软件,到了客户的机器上就出现问题 

了。这些问题出现的主要原因有内存分配未成功却使用了 

它;内存分配虽然成功,但是尚未初始化就引用它;内存 

分配成功并且已经初始化,但是操作越过了内存的边界。 

内存分配成功并且已经初始化,操作也为超越内存的边界, 

但是没有释放内存资源,造成了内存泄露。 

3指针和数组带来的安全性缺陷模式 

3.1指针的重复释放 

对已经释放的内存资源进行再次释放称为指针的重复 

释放。即对同一块内存地址两次调用free()函数。例如 

在下面的例子中,函数release()中已经对资源进行了释放, 

而main()中在release()后又对资源进行释放,从而 

行成重复释放。 

1 typedef struct X{ 

2 char}field; 

3 }tx: 

4 void release(tx a)f 

5 b(); 

6 free(a->field); 

7 free(a); 

8 } 

9 void main(){ 

1 0 tx}a=(tx*)malloc(sizeof(tx)){ 

1 1 if(a==NULL)return; 

l2 a一>field=(char*)malloc(10); 

13 release(a); 

14 free(a->field); 

15 free(a); 

16 } 

3.2内存泄露 

内存泄露是内存资源申请后没有被释放。它可能导致 

数据丢失。在大型或复杂的软件系统中,如果只申请内存 

资源而没有将其释放,可能导致内存资源枯竭最终导致计 

算机死机。例如在下面的例子中,P在程序结束前没有被 

释放,导致了内存泄露。 

1. #include<stdio.h> 

2. #include<stdlib-l1> 

3. #include<string.h> 

4. 

5. void 

放在一块的,初始化的全局变量和静态变量在一块区域, 

溢出。 

未初始化的全局变量和未初始化的静态变量在相邻的另一 

块区域。 

例如下表:buf的大小为20,如果str+str2的长度大 

于20,将导致栈缓冲区溢出。这给攻击者带来了入侵的 

程序结束释放。 

机会,它可以让攻击者重写内存中的数据。 

1.#indude<stdio.h> 

2.#indude<string.h> 

3.#define MAXSIZE 20 

4.另外还有一个专门放常量的地方。 一程序结束 

释放。 

在所有函数体外定义的是全局量,加了static修饰符 

后不管在哪里都存放在全局区(静态区),在所有函数体 

外定义的static变量表示在该文件中有效,不能extern 

4.void test(char*str,char*str2){ 

5. 

6. 

7. 

char pre[2】=”<”; 

char buf[MAXSIZE】=””; 

char post[2]=”>”; 

到别的文件用,在函数体内定义的static表示只在该函数 

体内有效。另外,函数中的“adgfdf”这样的字符串存放 

在常量区。 

用malloc,caUoc,realloc等分配内存的函数分配得 

到的内存就是在堆上。程序员自己负责在何时用free或 

delete释放内存。动态内存的生存期由程序员决定,使用 

非常灵活,但问题也最多。 

缓冲区溢出是一种非常普遍、非常危险的漏洞,在各 

种操作系统、应用软件中广泛存在。利用缓冲区溢出攻 

击,可以导致程序运行失败、系统当机、重新启动等后 

果。更为严重的是,可以利用它执行非授权指令,甚至可 

以取得系统特权,进而进行各种非法操作。缓冲区溢出攻 

击有多种英文名称:buffer overflow,buffer overrun, 

smash the stack,trash the stack,scribble the stack, 

mangle the stack,memory leak,overrun screw;它 

们指的都是同一种攻击手段。第一个缓冲区溢出攻击 

一一

MOrris蠕虫,发生在二十年前,它曾造成了全世界 

6000多台网络服务器瘫痪。 

C/C++的一些标准库函数提供了往分配的内存空间 

内存储数据的函数,如果控制不当,导致往里面写入数据 

的长度大于分配空间的长度,将导致堆缓冲区溢出。例如 

下表中,buf分配的空间大小为256,如果外界输入的参 

数argv的长度大于256,将导致堆缓冲区溢出。这提供 

了让外部攻击者将任何内容写入内存的机会。 

1.#define BUFSIZE 256 

2.int main(int argc,char }argv){ 

3.char,bur; 

4.bur=(char幸)maⅡoc(BUFSIZE); 

5.strcpy(buf,argv[1])} 

6.} 

3.5栈缓冲区溢出 

在执行函数时,函数内局部变量的存储单元都可 

以在栈上创建,如函数体内定义整型数组类型a:int 

a[21={1,2)。函数执行结束时这些存储单元自动被释放。 

栈内存分配运算内置于处理器的指令集中,效率很高,但 

是分配的内存容量有限。C/C++/JAVA提供的一些对 

数组进行操作的标准库函数的使用不当可能导致栈缓冲区 

8. if(strlen(str)<MAXSIZE) 

9. strcpy(buf,str); 

10.printf(”strcpy:%s%s%s\n”,pre,buf,post); 

l1. if(strlen(buf)+strlen(str2)<=MAXSIZE)// 

theoretical integer overflow 

l2. strcat(buf,str2);//CWE一121 

13.printf(”results:%s%s%s\n”,pre,buf,post); 

14.} 

1 5. 

16.nit main(int argc,char**argv){ 

17. char*userstr: 

18. char*userstr2l 

19. if(argc>2){ 

20. userstr=argv[1]t 

21. userstr2=argv[2】; 

22.test(userstr,userstr2)} 

23. 1 

24.prnitf(”donekn”)} 

25. return 0I 

26.} 

4指针别名给软件测试带来的难题 

由于数组名是指向数组首地址的指针,在后面的讨论 

中将不区别其中的差别,统一使用指针这个名称。 

当程序中有两个或两个以上的指针表达式指向同一块 

内存空间时,则这些指针表达式关于该内存空间形成别名 

关系。 

别名关系能够增加软件测试复杂度,例如下面的例 

子,由于在主程序中有语句b=c,如果缺少拷贝构造函 

数base(base&a),则当程序执行析构函数时,对指针 p 

就执行了两次释放操作,可能会造成死机。b和C就属于 

指针别名,如果在测试的过程中不能记录这一层关系,就 

没法获知最后使用free()函数释放的是同一块内存空间, 

可能造成漏报。 

class base 

f public: 

char p; 

base() 


发布者:admin,转转请注明出处:http://www.yc00.com/web/1714259670a2412161.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信