|
作者: a_one [a_one] 论坛用户 | 登录 |
来自linux的内核的安全模块里(不可利用的),这个代码在内核中运行: int rsbac_acl_sys_group(enum rsbac_acl_group_syscall_type_t call, union rsbac_acl_group_syscall_arg_t arg) { ... switch(call) { case ACLGS_get_group_members: if( (arg.get_group_members.maxnum <= 0) /* [A] */ || !arg.get_group_members.group ) { ... rsbac_uid_t * user_array; rsbac_time_t * ttl_array; user_array = vmalloc(sizeof(*user_array) * arg.get_group_members.maxnum); /* [b] */ if(!user_array) return -RSBAC_ENOMEM; ttl_array = vmalloc(sizeof(*ttl_array) * arg.get_group_members.maxnum); /* [C] */ if(!ttl_array) { vfree(user_array); return -RSBAC_ENOMEM; } err = rsbac_acl_get_group_members(arg.get_group_members.group, user_array, ttl_array, arg.get_group_members.max num); ... } 在这个例子中,[A]的数据越界检查部分不能足够的防止[b][C]能造成的整数溢出,绕过这个检查只需 提供一个足够高的(比如:高于 0xffffffff / 4 )的值给 arg.get_group_members.maxnum,我们能引 起[b]和[C]处和这个值相乘的整数溢出,并且强制ttl_array 和user_array分配的缓冲区要小于程序 中预期的大小.因此rsbac_acl_get_group_members函数拷贝我们能控制的数据到这个缓冲区里,可能 改写tty_array和user_array指向的缓冲区后面的一些数据.在这里,程序中使用了vmalloc 分配缓冲 区,所以尝试改写tty_array和user_array指向的缓冲区后面的一些数据仅仅只是造成一个错误,所以 并不能被利用,尽管如此,它提供了一个例子以提醒我们在现实生活中编写代码要注意这些问题. 另外一个例子是最近SUN rpc XDR库中所带的xdr_array()函数中存在一个整数溢出漏洞的问题(见 I SS X-Force的安全公告).在这个例子里面,用户提交的数据用来计算动态分配缓冲区的大小,该缓冲区 用来存储用户提交的数据,看如下有问题的代码: bool_t xdr_array (xdrs, addrp, sizep, maxsize, elsize, elproc) XDR *xdrs; caddr_t *addrp; /* array pointer */ u_int *sizep; /* number of elements */ u_int maxsize; /* max numberof elements */ u_int elsize; /* size in bytes of each element */ xdrproc_t elproc; /* xdr routine to handle each element */ { u_int i; caddr_t target = *addrp; u_int c; /* the actual element count */ bool_t stat = TRUE; u_int nodesize; ... c = *sizep; if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { return FALSE; } nodesize = c * elsize; /* [1] */ ... *addrp = target = mem_alloc (nodesize); /* [2] */ ... for (i = 0; (i < c) && stat; i++) { stat = (*elproc) (xdrs, target, LASTUNSIGNED); /* [3] */ target += elsize; } 正如你看到的,当提供一个很大的值给 elsize 和 c (sizep),可能引发[1]乘法操作导致整数溢出,并且 使nodesize的值小于应用程序中所预期的值,既然nodesize被用于[2]的缓冲区分配操作,该缓冲区将会被 错误的定位大小,导致[3]的堆溢出.更多关于这个漏洞的信息,见参考资料中CERT安全咨询公告. ---add by Sam@sst 还有一个关于整数溢出导致堆溢出的很典型的例子,OpenSSH Challenge-Response SKEY/BSD_AUTH 远程缓冲区溢出漏洞. 下面这段有问题的代码摘自OpenSSH的代码中的auth2-chall.c中的input_userauth_info_response() 函数: unsigned int nresp, nresp = packet_get_int(); if (nresp > 0) { response = xmalloc(nresp * sizeof(char*)); [1] for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL); } packet_get_int是从用户提交的数据中取得一个int值,保存在整数变量nresp中,由于没有考虑到[1]处的乘法会导致程序的异常 (在32位的系统环境中,unsigend int的最大值是0xffffffff,我们只要提供0xffffffff/4 的值,比如0x40000000).程序执行如下 操作.比如: 0x40000000 + 1 (nresp的值) = 0x40000001 (满足 nresp > 0的要求) 0x40000001 * 4 (分配 nresp * 4 的缓冲区空间) = 0x100000004 (计算结果已经超出了32位的值) 由于以上的值已经超出了32位的值,将被截断成0x00000004.也就是说其实 xmalloc 只在堆上分配了4个字节的缓冲区空间.接下来 的for 循环操作: for (i = 0; i < 0x40000001; i++ ) response[i] = packet_get_string(NULL); packet_get_string函数从用户数据中读取4个字节的内容写入 response + i的地址.经过0x40000001的循环,用户的数据早已覆盖 了xmalloc原先分配的4字节的空间以及后面的数据(如同样分配在heap区的函数指针等等来获得程序流程的控制权). _______________________________________ |
地主 发表时间: 04-06-09 16:28 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号